quasarpwn.github.io

View on GitHub

Introduction à l’exploitation Windows | Théorie

/!\ Attention vous trouverez ici beaucoup d’aproximation et de fautes d’orthographes: cause (je suis nul en ortho oui mais pas que) cet article est un “troll” avec un message secret ! Essaye de le retrouver :) Bonne chance ! /!\ Bonjour à tous ! On se retrouve pour un article toujours basique. En effet aujourd’hui on va parler théorie.

Quand on commence le pwn on se tourne plutôt vers l’exploitation sous Linux et les challenges n’en manquent pas ! Ducoup on oublie souvent Windows qui est plus present sur le marché.

Les sécurité sous windows

Vous devez sans doute connaitre l’ASLR, la NX, la PIE ou le stack canary. Ces protections sont aussi presente sur Windows mais sous un autre nom et quelque petites difference.

Délivré des format strings !

Bon, les formats strings … Comment dire que c’est juste du CTF et rien d’autre vous ne trouverez jamais un format string dans la vie réelle. Les formats strings peuvent être utile parfois: un programme avec la PIE, les format strings permettent un Memory Leak ce qui peut simplifier l’exploit sauf qu’il ne faut pas rêver cette vulnerablilité est très très peu présente. Alors revenons au sujets sous Windows les format strings n’existent tous simplement pas ! Pourquoi ? Il y’a longtemps une format string trainait sur Windows, Microsoft à juste décider qui’il ne faut pas patcher cette vulnérabilité et qu’il faut juste désactiver le formateur %n qui est obligatoir pour l’exploitation d’un format string.

Pour resumer: Sous Windows vous n’aurez jamais à exploiter cette vulnérabilité !

Note sur les shellcodes

Vous n’êtes pas sans savoir qu’un shellcode doit executer un syscall: le plus souvent execve() voici par exemple le code d’un shellcode Linux pioché sur zeste du savoir:

bits 32

shellcode:
    ; On réinitialise les registres
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx

    ; Appel système 11
    mov al, 11

    ; ebx doit contenir un pointeur vers //bin/sh
    ; donc on construit la chaîne sur la pile

    push ebx ; ebx = 0, donc on a notre null-byte
    push `n/sh`
    push `//bi`

    ; A ce moment là, esp pointe sur `//bin/sh\0`
    mov ebx, esp ; on met dans ebx l'adresse de notre chaîne.

    ; ecx et edx valent déjà zéro (NULL)
    ; donc nous sommes tranquilles :)

    ; On exécute l'appel système
    int 0x80

    ; Et on quitte proprement
    ; (cf. shellcode Hello World)
    mov al, 1
    xor ebx, ebx
    int 0x80

Et Windows dans tout ça ? vous voyez le int 0x80 (cette instruction execute le syscall dont le numéro est eax (al ici pour éviter les nullbyte) le numero de execve est 11 en x86. Eh bien sur Windows ont pas les syscalls: de base ont ne peut pas créer de programme executant des syscalls directement, on doit passer par l’API WinAPI pour nos drivers ect ..

Petite parenthèse importante sur la WinAPI: Pour faire simple cette API appele des focntion interne de la NtAPI (qui n’est pas documenté) qui fait les appels système. NtAPI est implémenté dans un libraire dll (on reviendra sur ça dans la suite) ntdll.dll. Les fonction documenté de WinAPI se trouvent majortairement dans kernel32.dll. Vous comprendrez par la suite l’importance de kernel32.dll, sachez juste qu’il est utilisé par tout les executable windows (PE) même un simple Hello World. On va finir cette partie sur cela: coder des shellcodes sur Windows est plus compliqué que sur linux. En effet il faut passer par WinAPI ou NtAPI (non documenté) pour le faire.

PE et DLL

D’abord voyons ce que signifie ces deux sigles: -PE: Portable Executable -DLL: Dinamyc Linked Library

Continuons sur les Portable Executable: Ce sont des fichier executable (.exe) dérivé du format COFF (Mais si ! Common Object File Format ! Le premier format de fichier executable pour Unix System V) Comment se structure le format ? Vous savez sans doute qu’un ELF est constituer de differents segment .text .rodata .bss ect … Bah maitenant on va voir comment ça se passe pour les PE:

Bon revenons sur les DLL, ou Dynamic Link Library En fait c’est tout simple, vous vous rappelez libc.so.6 que vous avez surement dû rencontrer pour le developpemetnt d’une rop chain ou autre … Peut-être savez vous que quand vous faites printf(“Hello World \n”); en C vous executer une fonction de libc.so.6. Sous Linux les libraire ont une extension .so eh bien sous Windows c’est .dll.

Peut être que vous avez dejas coder un programme en reseau sous Windows par exemple ? Au debut vous avez dû inclure winsock2 nan ?

#include <winsock2.h>

Eh bien vous avez donc utiliser winsock32.dll ! Voila pour les PE et le DLL

Et si on codait un peu avec WinAPI ?

Peut-être avez vous remarquer des code sur github qui commence par:

#include <windows.h>

Que peut donc bien être ce windows.h ? C’est juste la WinAPI ! Alors commençons on va juste voir les bases !

Attention à être boulversé vous vous rappelez du main qui vous suis depuis si longtemps ? Eh bien il va maintenant disparaitre. Voici le code minimal pour un programme WinAPI

#include <windows.h>

int WinMain (
                HINSTANCE cetteInstance,
                HINSTANCE precedenteInstance,
                LPSTR lignesDeCommande,
                int modeDAffichage)
{
   return 0;
}

Vous devrez mettre votre code entre entre le { et return 0; } Mais d’abord analysons notre code (et ça sera tout pour cet article, je continuerai pour la WinAPI si les votes des lecteurs le veulent sur le discord.)

On voit que main est remplacé par WinMain qui est toujours un int, maintenant ce qui peut semblerbizarre c’est les arguments:

Sur ce, à la prochaine !