Hello, aujourd'hui on s'attaque a l'exercice "Julia" de Beginer.re.

L'exercice est disponible ici

Sans plus attendre, on est parti !

Etape 1: Trouver le main

Comme toujours on commence par chercher le main.

On remarque dans cette fonction, un second argument est attendu (en plus du nom du programme).

On en profite pour déduire que la fonction printf et la renommer. Pour ça il suffit de suivre le saut conditionnel en cas valeur différente de zéro.

Etape 2: Allocation mémoire

Maintenant on va s'intéresser au bloc suivant (quand on spécifie bien 2 arguments en paramètre)

NB: la ligne shl eax, 0 ne fait rien, surement une erreur dans l'algorithme d'optimisation du compilateur.

J'ai donc étudié cette fonction et voici le résultat de mon analyse. Je me suis permis de renommer cette fonction en conséquence.

Cette fonction n'a que pour seul but d'allouer un espace mémoire dans le heap (malloc).

Le bloc qui suit est assez simple, il va copier la string passée en paramètre dans l'espace qui vient d'être alloué.

Etape 3: La boucle

Le morceau de code suivant est plus complexe mais aussi plus intéressant.
Il est composé de 2 partie.

La partie rouge est la la loop

Un première partie qui va boucler et une seconde partie qui va faire une comparaison via strncmp.

On va d'abord se concentrer sur la boucle.
Je me suis permis de mettre mon analyse directement en commentaire dans IDA.

Ce qu'on peut observer d’emblée c'est qu'une boucle parcourt chaque caractère de la string passé en argument et ensuite passe chaque caractère dans la fonction que j'ai appelée "MysteriousFunction".

Etape 4: La MysteriousFunction

Comme on peut le voir la fonction mystère contient beaucoup de conditions.

On va y aller étapes par étapes

On voit que chaque test est fait de la même manière. Si on garde à l'esprit le fait que notre caractère est comparé à une valeur, on peut faire l'hypothèse que cette valeur est une lettre. J'ai donc remplacé chaque valeur de test par son équivalent ASCII.

On peut aussi voir qu'on a un bout de code étrange dans notre fonction mystère.

Ce code est présent 2 fois.
- 1 fois dans le test qui permet de dire si le caractère est entre "a" et "z"
- 1 fois dans le test qui permet de dire si le caractère est entre "A" et "Z"

Donc si notre caractère est une lettre alors on ajoute 4 à sa valeur ASCII.

"a"+ 4 => 65 + 4 => 69 => "i"

Normalement vous avez compris ce que fait ce code. Il crée un décalage de 4 pour chaque lettre de notre paramètre.
C'est ça, c'est exactement un chiffrement de César avec un décalage de 4.

Etape 5: Trouver le mot de passe

Mais pourquoi ce décalage ? La réponse se trouve dans l'autre bloc celui qui est atteint une fois que la boucle a fini de modifier nos caractères.

J'ai donc analysé cette fonction et voila ce que ça donne:

Pour résumer, on passe en paramètre a notre programme une chaîne de caractères qui seront décalé de 4 positions chacun leur tour (a => i). Ensuite une comparaison entre la chaîne de caractère obtenue et la chaîne "VIMwXliFiwx" est faite, si ce sont bien les mêmes chaînes alors on a gagné !


Il faut donc trouver la chaîne de caractère qui donne "VIMwXliFiwx" une fois décalée de 4 positions.

Un simple outil en ligne permet de retrouver le mot de passe.

Etape 6: Vérification

Awesome !

Conclusion

Ne croyez pas que le Reverse Engineering soit une activité simple, ça demande du temps et de la concentration ainsi qu'une bonne compréhension du fonctionnement d'un programme en général.

Il ne faut pas se décourager si on n'y arrive pas au début, c'est normal. Il faut beaucoup de pratique pour peu de résultats, mais c'est comme toute activité, il faut que le résultat surpasse les efforts fournis de votre point de vue sinon vous n'atteindrez jamais un niveau correct.

Social et Media

Comme toujours je suis disponible sur Twitter et cie, si vous avez des questions, des remarques, des suggestions etc. N’hésitez pas !

Twitter: @GhostAgs

Discord: hackraw