Notre première injection de shellcode avec un buffer overflow !

Introduction

Dans l’article précèdent je vous ai expliqué le principe d’un buffer overflow, nous allons donc appliquer un buffer overflow de type stack overflow (dépassement de tampons dans la pile).

Pour cela nous allons injecter un shellcode, puis écraser l’adresse de retour pour contrôler le registre EIP. Le registre EIP est le registre pointant sur la programme instruction à exécuter.

Le contrôler nous permet donc nous permet de contrôler l’exécution du programme.

Qu’est-ce qu’un « shellcode » ?

Un shellcode est une suite d’octets qui forme un programme permettant généralement d’obtenir un shell, d’où son le nom « shellcode ».

Voici un exemple de shellcode 32bits qui lance le programme /bin/sh : le shell.

Il a été trouvé sur http://shell-storm.org/shellcode/  :

Nous utiliserons ce shellcode pour ce challenge.

Le programme vulnérable

Voici le code source du binaire que nous allons exploiter :

Il faut compiler le programme avec la commande suivante afin de désactiver les protections que nous verrons plus tard : gcc vuln.c -m32 -fno-stack-protector -z execstack -no-pie -o vuln

Nous allons ensuite désactiver temporairement l’ASLR qui est une protection du système d’exploitation permettant de rendre les adresses aléatoires. Nous allons le faire à l’aide de la commande suivante :

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Exploitation du binaire

La vulnérabilité du programme que nous venons de compiler est le manque de contrôle de la taille entrée dans le buffer grâce à la fonction gets.D’ailleurs n peut voir lors de la compilation que gcc nous prévient que gets est dangereuse et ne doit pas être utilisée :

vuln.c:(.text+0x21): avertissement : the `gets’ function is dangerous and should not be used.

Recherche de l’offset requis pour contrôler EIP

La première étape pour exploiter ce binaire est de trouver a quel offset se trouve l’adresse de retour à écraser pour contrôler EIP. Lançons gdb-peda et envoyons une chaîne « pattern » dans le buffer :

recupération du nombre d'octets pour controler EIP

Nous pouvons voir qu’il faut écrire 136 caractères pour écraser la valeur de retour dans EIP.

Voici le fichier BofPattern.pl que j’utilise : https://pastebin.com/afsVqGeX .

Création de notre exploit

Maintenant créons un programme python qui envoie le shellcode, les caractères pour écraser l’adresse dans la pile, ainsi que l’adresse du shellcode où nous voulons rediriger l’exécution, dans le processus « vuln » avec la bibliothèque pwntools :

Nous mettons les caractères « BBBB » donc le programme va segfault à l’adresse 0x42424242 ( ‘B’ = 0x42 dans la table ascii )

Maintenant nous allons chercher notre shellcode dans la stack avec la commande :

x/56wx $esp-256

pour afficher le contenu de la pile (stack) du programme un peu plus haut dans la pile :

contenu de la pile

Nous pouvons voir que notre shellcode commence à l’adresse 0xffffd5f4, remplaçons nos « BBBB » par p32(0xffffd5f4) dans notre payload.

la fonction p32 permet d’écrire l’adresse  à l’envers  ( little-endian ) car nous sommes dans une architecture intel.

voici l’exploit final :

Lançons le programme :

Nous avons un shell
Nous avons un shell!

Conclusion

J’espère que vous avez apprécié l’article !

Prochainement nous apprendrons à bypasser les diverses protections modernes car ici nous les avons toutes désactivées pour un exemple plus simple.

Add a Comment

Votre adresse de messagerie ne sera pas publiée.