grim7reaper

Un artisan du code

Crackme — ltrace

Le crackme étudié dans cet article provient d’ici.

Avec ce troisième crackme, on reste dans du très simple mais ça va nous permettre de voir une nouvelle approche lorsque l’on veut faire de la rétroingénierie sur des exécutables dynamiques.

Bon, déjà voyons à quoi nous avons à faire.

% ./crackme
(*) -Syntaxe: ./crackme03 [password]

Ok, celui-ci prend le mot de passe via les arguments de la ligne de commande.

Commençons par le traditionnel strings qui, comme on pouvait s’y attendre, ne nous apprend pas grand-chose.

% strings crackme
/lib/ld-linux.so.2
__gmon_start__
libc.so.6
_IO_stdin_used
strcpy
exit
puts
__stack_chk_fail
printf
memcpy
malloc
strcmp
__libc_start_main
GLIBC_2.4
GLIBC_2.0
PTRh0
QVhT
libe
_0cG
jc5m
_.5T
[^_]
(*) -Syntaxe: %s [password] 
_0cGj35m9V5T3
8CJ0
9H95h3xdh
_Celebration
rification de votre mot de passe..
(!) L'authentification a 
chou
 Try again ! 
'+) Authentification r
ussie...
 U'r root! 
 sh 3.0 # password: %s
le voie de la sagesse te guidera, tache de trouver le mot de passe petit padawaan 

Il y a bien quelques chaînes qui ressemblent vaguement à un mot de passe, mais aucune ne fonctionne.

% ./crackme _0cGj35m9V5T3
Vérification de votre mot de passe..
le voie de la sagesse te guidera, tache de trouver le mot de passe petit padawaan 
% ./crackme 9H95h3xdh
Vérification de votre mot de passe..
le voie de la sagesse te guidera, tache de trouver le mot de passe petit padawaan 

Voyons à quel type de binaire nous avons là :

crackme03: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped

Hum, intéressant : cet exécutable est lié dynamiquement. Voyons donc ce que nous donne un petit ltrace :

% ltrace ./crackme AAAAAAAA
__libc_start_main(0x8048554, 2, 0xbfa5d744, 0x8048840, 0x8048830 <unfinished ...>
malloc(29)                                                                                                     = 0x09a6d008
memcpy(0x09a6d008, "_0cGj35m9V5T3\303\2078CJ0\303\2009H95h3xdh", 31)                                           = 0x09a6d008
memcpy(0xbfa5d60a, "_Celebration", 13)                                                                         = 0xbfa5d60a
strcpy(0xbfa5d66e, "AAAAAAAA")                                                                                 = 0xbfa5d66e
puts("V\303\251rification de votre mot de pa"...Vérification de votre mot de passe..
)                                                              = 38
strcmp("AAAAAAAA", "_0cGjc5m_.5\r\n\303\2078CJ0\303\2009")                                                     = -1
printf("le voie de la sagesse te guidera"...le voie de la sagesse te guidera, tache de trouver le mot de passe petit padawaan 
)                                                                  = 84
exit(0  <unfinished ...>
+++ exited (status 0) +++

Hum, c’est très instructif. On voit que le code fait un strcmp contre une chaîne un peu bizarre. Essayons d’utiliser cette chaîne bizarre en tant que mot de passe. Étant donné que la chaîne contient la séquence de caractères de contrôles \r\n, je préfère utiliser Ruby pour passer la chaîne en argument (d’autres solutions étaient bien sûr possible) plutôt que d’essayer de la taper directement dans le shell.

% ./crackme "$(ruby -e 'print("_0cGjc5m_.5\r\n\303\2078CJ0\303\2009")')"
Vérification de votre mot de passe..
'+) Authentification réussie...
 U'r root! 

  sh 3.0 # password: liberté!

Gagné !
Le mot de passe est donc liberté!.