[pDrilI's Crypto keygenme #2 ]
par Amenesia

 

Analyse du code:
  Recherche des 2 GetDlgItemTextA ( un pour le nom ,l'autre pour le serial ) puis observation :



_text:004010D6 LongNom: 
_text:004010D6                 lea     edi, [Nom]
_text:004010DD                 or      ecx, 0FFFFFFFFh    ;
_text:004010E0                 xor     eax, eax           ; 
_text:004010E2                 xor     edx, edx           ;   Calcul de 
_text:004010E4                 repne scasb                ;  la longueur
_text:004010E6                 not     ecx                ;     du Nom
_text:004010E8                 dec     ecx                ;
_text:004010E9                 mov     [Clef], 0
_text:004010F1                 test    ecx, ecx
_text:004010F3                 jle     Suite
_text:004010F5 
_text:004010F5 CalculClef: 
_text:004010F5                 movsx   ecx, [Nom]         ; recupere un caractere
                                                          ; du nom
_text:004010FD                 mov     eax, ecx
_text:004010FF                 lea     edi, [Nom]
_text:00401106                 shl     eax, 4             ; le multiplie par 16 
_text:00401109                 add     eax, ecx           ; somme le resultat avec
                                                          ; la valeur du caractere
_text:0040110B                 shl     eax, 4
_text:0040110E                 add     eax, ecx           ; idem
_text:00401110                 shl     eax, 4
_text:00401113                 add     eax, ecx           ; idem
_text:00401115                 mov     ecx, [Clef]
_text:00401119                 inc     edx
_text:0040111A                 lea     eax, [eax+eax*4]   ; Resultat*5
_text:0040111D                 lea     eax, [ecx+eax*2]   ; Clef + Resultat*5*2
_text:00401120                 or      ecx, 0FFFFFFFFh
_text:00401123                 mov     [Clef], eax
_text:00401127                 xor     eax, eax
_text:00401129                 repne scasb
_text:0040112B                 not     ecx
_text:0040112D                 dec     ecx
_text:0040112E                 cmp     edx, ecx
_text:00401130                 jl      CalculClef
_text:00401132 Suite:

D'ou Clef = Somme[ ((( caractere * 16 + caractere)*16 + caractere)*16 + caractere  )*10 ] = caractere * 43690
 



 

Puis le programme verifie que le serial ne comporte que des lettres et des chiffres:

_text:0040116F Majuscule: 
_text:0040116F                 mov     al, byte ptr [esp+edx+104h+var_E8]
_text:00401173                 cmp     al, 41h
_text:00401175                 jl      Minuscule
_text:00401177                 cmp     al, 5Ah
_text:00401179                 jle     VerifFormatSerial
_text:0040117B 
_text:0040117B Minuscule: 
_text:0040117B                 cmp     al, 61h
_text:0040117D                 jl      Chiffre
_text:0040117F                 cmp     al, 7Ah
_text:00401181                 jle     VerifFormatSerial
_text:00401183 
_text:00401183 Chiffre: 
_text:00401183                 cmp     al, 30h
_text:00401185                 jl      ErreurFormatSerial
_text:0040118B                 cmp     al, 39h
_text:0040118D                 jg      ErreurFormatSerial
_text:00401193 
_text:00401193 VerifFormatSerial: 
_text:00401193 
_text:00401193                 lea     edi, [esp+104h+var_E8]
_text:00401197                 or      ecx, 0FFFFFFFFh
_text:0040119A                 xor     eax, eax
_text:0040119C                 inc     edx
_text:0040119D                 repne scasb
_text:0040119F                 not     ecx
_text:004011A1                 dec     ecx
_text:004011A2                 cmp     edx, ecx
_text:004011A4                 jl      short loc_0_40116F
_text:004011A6 
_text:004011A6 Suite: 


 Une fois le format du serial verifié, la chaine est transformée en nombre ( 'MIRACL error from routine ' => utilisation de la librairie Miracl ), et pour compliquer un peu la chaine est interpreté comme si le serial etait ecrit en base 60.
avec 0 = 0, ..., A = 10,..., Z = 35 , a =  36, ... , x = 59.  ( c'est sans doute pour cela que le programme se ferme lorsque l'on rentre un Serial comportant un y ou un z )
 

_text:004011AE                 lea     eax, [Serial]
_text:004011B2                 push    eax 
_text:004011B3                 push    edi 
_text:004011B4                 mov     dword ptr [edx+238h], 3Ch 
_text:004011BE                 call    CvrtMiracl
 



On remarque que un peu plus bas le programme utilise les valeurs 7E2BDC8ED8856EE745A9D6F93E143B7ACE202999 et 10001 ( un nombre premier )... 

Tout semble indiquer que le programme utilise RSA... 

_text:004011E7                 push    ebp         ; RSASerial
_text:004011E8                 push    esi         ; 7E2BDC8ED8...
_text:004011E9                 push    ebx         ; 10001
_text:004011EA                 push    edi         ; Serial_
_text:004011EB                 call    RSA
 

Ou RSASerial = Serial_^10001 mod 7E2BDC8ED8856EE745A9D6F93E143B7ACE202999


Un fois RSASerial calculé, le programme s'assure que les 4 premieres lettres verifient :
   eax xor 12344321h = 54770B67h 
ie eax = 54770B67h xor 12344321h = 46434846h = 'FCHF' 
Autrement dit le serial doit commencer par 'FHCF'
 

_text:00401204                 mov     eax, [RSASerial] ; les 4 premieres lettre
_text:00401208                 xor     eax, 12344321h
_text:0040120D                 add     esp, 38h
_text:00401210                 cmp     eax, 54770B67h
_text:00401215                 jnz     Mauvais_serial


Puis compare la Clef et le RSASerial privé de ses 5 premieres lettres:

_text:00401235                 lea     eax, [RSASerial + 5]
_text:00401239                 lea     ecx, [ClefStr]
_text:00401240                 push    eax 
_text:00401241                 push    ecx 
_text:00401242                 call    ds:lstrcmpA
_text:00401248                 test    eax, eax
_text:0040124A                 push    0
_text:0040124C                 jnz     Mauvais_serial
_text:0040124E                 mov     edx, [esp+110h+var_24]
_text:00401255                 push    offset aNiceJob 
_text:0040125A                 push    offset aHeyYourKeyIsGooood 
_text:0040125F                 push    edx


Trouver un Nom/Serial valide:
 

Nom:
Choisir un Nom... pourquoi pas Amenesia :)
Calculer la clef correspondante et la faire preceder par 'FHCF' et un caractere au choix : FHCF0217533e ( en ascii 464843463032313735333365 )
 

Serial:
On voudrait que:
  464843463032313735333365 = Serial^10001 mod 7E2BDC8ED8856EE745A9D6F93E143B7ACE202999
c'est a dire :
  Serial  = 464843463032313735333365^D mod 7E2BDC8ED8856EE745A9D6F93E143B7ACE202999
 où D est la clef privée utilisée lors du cryptage RSA 

Les clef utilisée etant tres petite "RSA Tool" n'a aucune difficultée pour la determiner: 

                                                     D = 3FC69E031A914000E925FC61F2BF888F410EB07D
 

  Serial =  2C1C24FC8ECA1305E553142DBC3EF29D151B55F6
           =   EjjOnVYobCoARqfakDirkHRqa7I  ( en base 60 )
 
 
 


Conclusion :
 
 

Nom   :  Amenesia
Serial  : EjjOnVYobCoARqfakDirkHRqa7I

Amusez vous bien ;)