Le binaire s'appelait 1337 (et les orgas avaient prévenus qu'ils aimaient le l33tsp34k). En attendant que l'orga mette les fichiers en libre-accès, je le pose sur un site de dl.
Writeup, première phase de découverte:
kevin@slack:~/chall/grehack$ file 1337
1337: ELF 32-bit LSB executable, Intel 80386,, statically linked, stripped
kevin@slack:~/chall/grehack$ readelf -s 1337
readelf: Error: Unable to read in 0x28 bytes of section headers
readelf: Error: Unable to read in 0x488 bytes of section headers
readelf: Error: Unable to read in 0x100 bytes of program headers
WUT? Un ELF illisible?
Bon, premier exercice, réparer le binaire:
kevin@slack:~/chall/grehack$ hexdump -C 1337 | head -2
00000000 7f 45 4c 46 01 01 01 13 37 13 37 13 37 13 37 00 |.ELF....7.7.7.7.|
00000010 02 00 03 00 01 13 37 00 90 84 04 08 34 13 37 00 |......7.....4.7.|
kevin@slack:~/chall/grehack$ hexdump -C /bin/ls | head -2
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 b4 c1 04 08 34 00 00 00 |............4...|
Il y a quand même beaucoup de 1337 dans ce binaire. On tente une approche basique: tous les 0000 sont remplacés par des 1337:
kevin@slack:~/chall/grehack$ cp 1337 wip
kevin@slack:~/chall/grehack$ sed -i 's/\x13\x37/\x00\x00/g' wip
kevin@slack:~/chall/grehack$ readelf -s wip
Symbol table '.dynsym' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (2)
2: 00000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.0 (2)
3: 00000000 0 FUNC GLOBAL DEFAULT UND fgets@GLIBC_2.0 (2)
4: 00000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.0 (2)
5: 00000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.0 (2)
6: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 00000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.0 (2)
8: 00000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.0 (2)
9: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2)
10: 0804889c 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
11: 08049aa0 4 OBJECT GLOBAL DEFAULT 26 stdin@GLIBC_2.0 (2)
kevin@slack:~/chall/grehack$
Ok, ça semble bon.
kevin@slack:~/chall/grehack$ ./wip
Ready to become 1337?
yes
fail
Ok. Il est temps de regarder un peu à quoi ressemble ce challenge, pour une approche rapide, je prends metasm. Je démarre par l'entrypoint (0x8048490) et je navigue un peu jusqu'à 0x0804857c qui semble intéressant.
Et ce qui est à l'adresse 0x080488a0 est encore plus intéressant: on découvre trois manières d'écrire FAIL, puis un message de félicitations.
Si je regarde une vue d'avion du programme, on se rend compte que l'on peut dérouler l'exécution en plusieurs phases:
Pour ne pas alourdir le post, je ne met pas l'ensemble des
vérifications, mais on voit deux boucles qui semblent faire des choses,
puis des séries de checks qui mènent aux trois différents FAIL. C'est
sympathique, car selon le message, on peut tout de suite savoir si on a
passé l'étape. Analysons la Boucle1 et sa condition en sortie:
En résumé, nous avons à esp+0x14 l'adresse de la clé entrée, et en esp+0x18 la somme des valeurs hexa de chacun des caractères.
En fin de boucle, on compare si la somme vaut 0x539 (ce qui fait 1337 en décimal, il y a du l33t dans ce chall). Vérifions si on prend 11 (0xa en hexa) caractères 'y' (0x79 en hexa) et un 'u' (0x75):
'0x79'*a+'0x75'+'0x0a' = 0x539
kevin@slack:~/chall/grehack$ ./wip
Ready to become 1337?
yyyyyyyyyyu
f41l
Le message d'erreur a changé, nous avons f41l, ce qui signifie que la première étape est donc passée.
La seconde étape fait 4 comparaisons:
Comparaisons très simples d'ailleurs.
On vérifie que le second caractère (eax+1) vaut 0x31 (1)
On vérifie que le quatrième caractère (eax+3) vaut 0x33 (3)
On vérifie que le quatrième caractère (eax+3) vaut 0x33 (3)
On vérifie que le huitième caractère (eax+7) vaut 0x37 (7)
Du 1337 encore. Si je modifie ma chaine par:
y1y3yyy7yyu, il va me manquer des points pour aboutir à 0x539, je complète donc avec d'autres caractères pour que la somme fasse 0x539 pour continuer à passer la première étape, comme par exemple: y1y3yyy7yyuHDD
kevin@slack:~/chall/grehack$ ./wip
Ready to become 1337?
y1y3yyy7yyuHDD
0xPh41L
Ok, on a bien le second message d'erreur, signe que la deuxième étape est passée.
La troisième étape démarre par la boucle nommée boucle 2 sur l'image vue d'avion:
Le programme va aller du côté de esp+0x14 (la clé) et faire deux XOR successifs, 13 puis 37 (oooooh, encore 1337). La clé va donc être XORée par 0x24.
La suite du programme est une longue suite de comparaison dont voici le début:
On voit que différents caractères du mot de passe sont comparés entre eux. Si on suit la chaîne complète, on observe que les caractères: 0,2,4,5,6,8,9,a,b,c,d sont identiques, et que le caractère en e-ième position vaut v (0x76). Si cela est vrai alors le message de succès est affiché:
Le dernier caractère est comparé à 'v', mais est XORé. 'v' XORé à 0x24 vaut 0x52 autrement dit 'R'.
.1.3...7......R+padding
avec tous les caractères '.' identiques, et que la somme en hexa de l'ensemble des chiffres vaut 0x539. Si je compte:
0x539 - 0x0a (retour chariot) - 0x31 - 0x33 - 0x37 - 0x52 = 0x442
J'ai besoin au minimum de 11 caractères et que le reste soit de l'ascii inscriptible. Avec une calculette hexa, je trouve une solution avec onze 'Y' et un 'o': Y1Y3YYY7YYYYYYRo
kevin@slack:~/grehack$ ./wip
Ready to become 1337?
Y1Y3YYY7YYYYYYRo
W3LL d0|\|3, y0u'r 50 L337 |\|0W...
Ok, chall done.
Et puisque je suis devenu un l33t et que le challenge permet plusieurs solutions, je propose sans trop de difficultés avec plein d'31337ness :
kevin@slack:~/grehack$ ./wip
Ready to become 1337?
31333337333333R^k3v1n
W3LL d0|\|3, y0u'r 50 L337 |\|0W...
EDIT 20/11/2013: A la réflexion, je me rends compte qu'il y a une autre solution. Si on supprime le retour chariot de fin de chaine, alors on obtient une solution plus simple:
kevin@slack:~/grehack$ echo -n d1d3ddd7ddddddR | ./wip
Ready to become 1337?
W3LL d0|\|3, y0u'r 50 L337 |\|0W...
PS: Je teste aussi un nouveau layout du blog, dites moi ce que vous en pensez, ça me paraît plus clair lorsque je copie colle du terminal et que je met des images. Si vous connaissez une CSS qui affiche correctement de l'hexa, je suis preneur aussi.
Aucun commentaire:
Enregistrer un commentaire