Patcher un binaire avec Radare2

PUBLISHED ON OCT 2, 2015 — SECURITY

En lisant la doc de Radare2, je me suis aperçu qu’on pouvait facilement patcher un binaire très rapidement.

Pour l’exemple, j’ai utilisé un CrackMe open-source trouvé sur Github : github.com/geyslan/crackmes/blob/master/src/crackme.01.c

Une fois téléchargé, on le compile de façon basique avec GCC :

$ gcc crackme.01.c -o crackme.01

Maintenant que l’on a le binaire, la partie reverse commence !

On lance le binaire une première fois pour découvrir comment il marche en apparence.

$ ./crackme.01
Please tell me my password : password
No! No! No! No! Try again.

Lorsqu’il me demande le mot de passe, j’essaie “password” mais ça ne marche pas. L’accès est refusé.

Il faut avouer que le vrai but de ce CrackMe est de trouver le mot de passe, pas de le bypasser. Ce CrackMe est simple et compréhensible, c’est pour cette raison que je l’ai choisi. Si vous débutez dans le reverse engineering, tentez de trouver le mot de passe, il est fun et abordable.

À présent, passons aux choses sérieuses !

On ouvre Radare2 en mode écriture :

$ r2 -w ./crackme.01

Quelques commandes

Sur l’image ci-dessus, on voit l’exécution de trois commandes.

La première, aa, sert à analyser le binaire.

La seconde, fs symbols, sélectionne la liste des symboles.

La troisième, f, affiche cette liste.

On remarque très vite le symbole main. Ce symbole représente la partie principale du programme.

Pour regarder le code de cette fonction, on lance la commande :

]> pdf @ main

Désassemblage du binaire

Que voyons nous ?

Une fonction sym.compare ! Une instruction “test” plus tard, voilà une instruction conditionnelle !

Et si l’on suit la flèche, on peut voir que l’instruction “jne” ou “jump if not equal” renvoie vers un code qui affiche le message “No ! No ! No ! No ! Try again …”.

Si l’on inverse l’instruction conditionnelle, lorsque l’utilisateur entrera un mauvais mot de passe, le message “The password is correct ! Congratulations !!!”.

Faisons le !

Pour commencer, on place le curseur de radare2 sur l’offset de l’instruction conditionnelle : 0x004009a2.

]> 0x004009a2
Pour modifier cette instruction, on lance cette commande :

]> wa je 0x4009c4

Détaillons un peu :

wa => Write Assembly (Écrire en Assembleur)

Cet argument est nécessaire pour dire à Radare2 que l’on souhaite écrire une instruction en Assembleur dans cet offset.

je => Jump if Equal

C’est une instruction conditionnelle. JE est l’instruction inverse de JNE.

0x4009c4 => Offset de destination du jump

Tout est dit, “je 0x4009c4” veut dire : Saute à l’offset 0x4009c4 si les deux paramètres d’entrées sont égaux”.

On quitte ensuite Radare2 et voilà ! Votre binaire est patché !

Facile non ?

Évidemment, dans cet exemple, le binaire a été patché rapidement. Il vaudrait mieux ne pas faire ce genre de chose pour un patch sérieux.