CrackMe 01 de jB par Kharneth | |||
---|---|---|---|
Outils utilisés | Public | Cible | |
- PEId - OllyDbg - Calculatrice - Papier, Crayon, Cerveau 5.0 | Débutant en Cracking ayant des connaissances de base en programmation | crackme_jB_01 | |
1 - PEId | |||
On commence par une analyse rapide avec PEId pour vérifier que le programme n'est pas compressé ou crypté.
Et justement, PEId nous signale qu'il est compressé avec UPX. Alors, soit on est pas pressé et on le décompresse à la main. Dans ce cas, Elooo vous l'expliquera mieux que moi (elooo_-_UPXUnpackme_Clandestino). Soit on veut passer directement aux choses sérieuses et on utilise simplement UPX. | |||
2 - OllyDbg | |||
On commence par regarder dans la liste des chaînes de caractères en faisant click-droit, "Search for", "All referenced text strings". On voit rien d'intéressant. Bon passons au plan B. On fait Ctrl+N pour afficher les imports et on va chercher une API intéressante du style GetDlgItemText ou GetWindowText. Et là non plus, on ne trouve rien d'intéressant! ![]()
Plan C, regardons dans la fenêtre de dump (en bas à gauche) si on y trouve des chaînes de caractères. Enfin, on trouve "Réussi!", "POUSSINS" et "Challenge InfoHackers". Ce "POUSSINS" est intéressant. A quoi peut-il correspondre? Je ne pense pas que ce soit le pass, c'est trop flagrant! D'ailleurs, en le testant, ça se confirme. Mais il doit bien être utilisé quelque part!
Voyons d'abord où est utilisée la chaîne "Réussi!". Notons son adresse (00409030) puis cherchons-la dans le code en faisant click-droit, Search for --> Constant. On tape l'adresse puis Entrer. ![]() On atterit au début d'une routine assez longue en 00401045 qui contient plusieurs ligne d'initialisation. ![]() Suivies par une boucle qui effectue des calculs sur des nombres de 64 bits (QWORD) et une API qui a l'air intéressante! Elle envoie des messages à des contrôles. Ici, c'est le message WM_GETTEXT qui est suffisamment explicite! Nous sommes peut être à l'endroit où notre pass est récupéré. On va regarder si cette API est utilisée ailleurs en faisant Ctrl+N, puis en sélectionnant USER32.SendDlgItemMessageA, puis en pressant la touche Entrée. La nouvelle fenêtre nous montre 3 adresses d'où est appelée la fonction. ![]()
La premiére est celle que l'on a trouvé. En double-clickant sur la deuxième, on se retrouve à la fin de la longue routine et la troisième nous emmène un peu plus bas. ![]()
On retourne sous OllyDbg qui s'est bien arrêté sur l'appel de l'API. On voit dans la fenêtre de la pile les différents paramêtres passés et notamment Buffer qui contient l'adresse de destination de notre pass. On la sélectionne, click-droit puis Follow in dump. On exécute la fonction en pressant F8 et on voit apparaître notre pass dans la fenêtre de dump. On va maintenant tracer avec F8 pour voir ce que le programme fait de notre pass. ![]()
On voit dans la fenêtre des registres que notre pass est chargé en ESI et le fameux POUSSINS en ECX. Ensuite, une boucle compare ces 2 chaînes. On continue de tracer. ![]()
On saute par dessus une boucle que l'on aurait prise si on avait entré POUSSINS comme pass. Cette boucle génère le texte "Non...!" à partir du texte "Réussi!", puis le JMP nous expédie à la fin de la routine pour l'afficher dans le champ texte. Ces 2 boucles ne servent donc à rien. ![]()
On arrive sur une boucle qui prend les 8 caractères de notre pass 1 par 1, les aditionne avec 8 autres valeurs, puis effectue un XOR avec encore 8 nouvelles valeurs. On va voir où sont stockées ces 16 valeurs. ![]()
Dans la fenêtre d'information, on click-droit sur l'adresse, puis Follow adress in dump. ![]() On voit sur la première ligne, les 16 octets qui seront utilisés pour crypter notre pass. ![]()
Une boucle effectue des calculs sur des QWORDS à partir de notre pass crypté. Puis la valeur résultante est comparée avec une autre valeur. Cette boucle ressemble étrangement à celle que l'on a vu en début de routine. On va regarder à partir de quel texte, cette première boucle effectue ses calculs. On pose un point d'arrêt sur la deuxième ligne qui récupère les caractères, on lance le prog avec F9, on retape un pass puis on valide. On se retrouve dans la boucle et on voit qu'elle prend les caractères de la chaîne "POUSSINS". ![]() Juste après la récupération du mot de passe, on place un JMP qui saute directement au début de la boucle de cryptage et évite ainsi que le programme détecte que l'on a tapé "POUSSINS". Dans la boucle, on inverse les 2 adresses qui récupèrent les octets de la clé ([ESP + EAX + 18] devient [ESP + EAX +20] et inversement). Le ADD CL,DL devient XOR CL,DL et le XOR CL,DL devient SUB CL,DL. ![]()
Ensuite, on passe en paramètre de l'API qui va afficher le résultat, l'adresse qui contient le mot de passe décrypté. On enlève tous les points d'arrêt restants, puis on lance le prog avec F9. ![]() On tape POUSSINS, on click sur "Vérifier" et le mot de passe apparaît en clair! :o) | |||
Kharneth | |||
There's danger on the edge of town Ride the King's highway, baby | |||
![]() |