Cracking "The XOR Algorithm II"
|
02-10-2012, 18h43
(Modification du message : 14-06-2020, 21h33 par supersnail.)
Message : #1
|
|
supersnail
![]() Éleveur d'ornithorynques ![]() ![]() ![]() ![]() ![]() ![]() ![]() Messages : 1,616 Sujets : 73 Points: 466 Inscription : Jan 2012 |
Cracking "The XOR Algorithm II"
Bonjour,
Ce tutoriel a pour but de montrer en quelque sorte la "démarche" de résolution d'un keygenme assez simple mais loin d'être trivial (trouvé sur http://www.crackmes.de/, très bon site où vous pouvez trouver des crackmes/keygenme en tous genres et de tous les niveaux). Ce tuto se découpe en 3 parties: tout d'abord le premier contact avec le keygenme, puis l'analyse de l'algorithme en lui-même, pour terminer sur l'élaboration d'un keygen. Comme vous pouvez le constater, ce tuto repose plus sur des morceaux de code commentés que sur de réelles explications. Il est du coup recommandé d'avoir quelques bases en assembleur (ou de profiter de ce tuto pour vous perfectionner en assembleur ![]() ![]() Bref vous pouvez trouver le crackme ici. I - Premier contact avec le keygenme Il est désormais temps d'avoir notre premier contact avec notre keygenme, pour cela on va l'ouvrir avec notre désassembleur préféré (pour ma part ce sera IDA Pro), qui nous donne un point d'entrée ressemblant à peu près à ceci: Code ASM :
public start On constate alors que notre programme crée un dialog à partir d'une ressource (que je vous invite à regarder à l'aide de "Resource Hacker"), dont la WndProc (la fonction qui traite les évènements, pour ceux qui n'ont jamais fait de dev sous Windows) a été nommée très logiquement "DialogFunc" par IDA. Allons donc jeter un oeil à cette fonction (que je ne posterai pas ici en entier, vu qu'il est assez "conséquent"). Notre crackme ayant besoin de récupérer la valeur notre mot de passe, on doit s'attendre à trouver un "GetDlgItemText" quelque part, et c'est le cas: Code ASM :
.text:004010F2 push 80h ; cchMax On aperçoit ici un appel à une fonction mystérieuse juste après l'appel à GetDlgItemTextA, suivi d'une routine de comparaison entre la chaîne "aWeGoAbout" et le unk_4030F1. Cette fonction mystérieuse doit donc faire des rites sataniques sur aWeGoAbout ou sur le "unk" pour éviter que la comparaison échoue tout le temps. Il est donc grand temps pour nous d'aller plonger dans cette fonction mystérieuse. II - Voyage en terre inconnue Une fois arrivé en 0040106E, on peut observer quelque chose similaire à ceci: Code ASM :
sub_40106E proc near ; CODE XREF: DialogFunc+2Cp Il nous reste maintenant à savoir quel rôle jouent la "fonction mystérieuse 1" et la "fonction mystérieuse 2" pour comprendre l'algo mis en oeuvre. Examinons donc la "fonction mystérieuse 1": Code ASM :
sub_401014 proc near ; CODE XREF: sub_40102D+12p On observe ici une routine qui fait la somme des codes ASCII des caractères du mot de passe entré par l'utilisateur, le tout tronqué à 1 octet (la taille du registre dl). Avant de pouvoir examiner la routine principale, il faut d'abord savoir ce que fait la "fonction mystérieuse 2", dont le code est posté ci-dessous: Code ASM :
sub_401000 proc near On remarque que cette fonction place la valeur de ebx dans eax, qui sera divisé par ebx, qui vaut 32. Le quotient de la division se trouve dans eax, tandis que le reste se situe dans edx (cf la doc Intel). Grâce à ces précieuses informations, on peut déduire de la fonction principale (sub_40106E) le processus de génération, dont le début est: - Somme des codes ASCII du serial entré par l'utilisateur (on invoque "fonction mystérieuse 1") - Modulo 32 de cette somme (on invoque "fonction mystérieuse 2" et on récupère edx) Il faut maintenant comprendre la boucle principale de l'algo: Code ASM :
loc_401091: En une sorte de pseudo-C, notre algo donnerait quelque chose du genre: Code C :
Cela transforme donc notre chaîne aWeGoAboutOurDa, qui va ensuite être comparée au unk qu'on a vu précédemment, et nous renvoyer le "good boy" si ces deux zones mémoires ont le même contenu. III - Let's keygen it ! On remarque assez vite que l'algorithme qui "chiffre" aWeGoAboutOurDa dépend d'un paramètre lié à l'entrée de l'utilisateur, que nous ne connaissons évidemment pas. Cependant (et heureusement pour nous), ce paramètre ne peut avoir que 32 valeurs possibles (merci le modulo !), ce qui nous autorise à bruteforcer légèrement pour trouver la (ou les) bonnes clés. De plus, ce paramètre étant égal à la somme des codes des caractères du serial, il faut vérifier que le serial trouvé vérifie ce critère. Ainsi, l'algo sera (toujours en "pseudo-C"): Code C :
Finalement, l'implémentation de notre keygen (en C) donne quelque chose comme: Code C :
#include <stdio.h> Bien sûr, si quelqu'un a une solution plus propre pour keygen, je suis preneur ![]()
Mon blog
Code : push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp "VIM est merveilleux" © supersnail |
|
03-10-2012, 06h57
Message : #2
|
|
Horgh
![]() Membre actif ![]() Messages : 197 Sujets : 4 Points: 91 Inscription : Mar 2012 |
RE: Cracking "The XOR Algorithm II"
Nice post, c'est toujours sympa à lire
![]() |
|
03-10-2012, 08h26
Message : #3
|
|
supersnail
![]() Éleveur d'ornithorynques ![]() ![]() ![]() ![]() ![]() ![]() ![]() Messages : 1,616 Sujets : 73 Points: 466 Inscription : Jan 2012 |
RE: Cracking "The XOR Algorithm II"
Merci beaucoup
![]()
Mon blog
Code : push esp ; dec eax ; inc ebp ; and [edi+0x41],al ; dec ebp ; inc ebp "VIM est merveilleux" © supersnail |
|
03-10-2012, 08h58
Message : #4
|
|
ark
![]() Psyckomodo! ![]() ![]() ![]() ![]() ![]() Messages : 1,033 Sujets : 48 Points: 317 Inscription : Sep 2011 |
RE: Cracking "The XOR Algorithm II"
Pas mal, tes explications sont clair, c'est cool
![]() |
|
« Sujet précédent | Sujet suivant »
|
Sujets apparemment similaires… | |||||
Sujet | Auteur | Réponses | Affichages | Dernier message | |
Introduction au Cracking sur Linux | systemprog | 1 | 1,753 |
26-10-2011, 23h02 Dernier message: CyberSee |
Utilisateur(s) parcourant ce sujet : 1 visiteur(s)