Zoom Icon

Soluzione Crackme 22

From UIC Archive

Crackme n.22 : A Serial, Keyfile, And A Suprise

Contents


Soluzione Crackme 22
Author: ValerioSoft
Email: ValerioSoft(AT)tin.it
Website:
Date: 15/03/2007 (dd/mm/yyyy)
Level: Very Easy, if you can read this, you can do it
Language: Italian Flag Italian.gif
Comments: Dove passa l’aratro della tempesta si trova sempre il solco della miseria.



Introduzione

Ciaoooooooooo, sesto tuteeeee??? Hey la fame vien mangiando :-D


Tools


Notizie sul CrackMe N.22

Questo è un crackme scritto da Quequero in persona, chissà che cosa ci riserva???.


Essay

Dal precedente Tute abbiamo imparato che...

...come prima cosa dobbiamo avviare il PEID 0.94, poi apriamo il file eseguibile del CrackMe, bene questa volta il file è crittato con PEtite 1.2 ma questo in realtà non dovrebbe interessarci dato che come regolamento del CrackMe Quequero ci dice di non decrittarlo infatti l'unico scopo per cui è stato utilizzato è quello di non permetterci di disassemblarlo altrimenti diventa troppo semplice!!!

Cosa significa??? Beh significa che questa volta dovremo utilizzare solo Ollydbg, ed è proprio quello che faremo!!!

Apriamo il file con Ollydbg e ovviamente ci troviamo nella zona di codice che si occupa di decrittare l'algoritmo a RunTime, per essere sicuri che il file sia bello che decrittato avviamo l'applicazione con il tasto Play. Ora dobbiamo fare qualcosa che negli altri Tute non abbiamo mai visto, clicchiamo con il tasto destro del mouse su un punto qualsiasi del codice e scegliamo Go to->Origin oppure premiamo semplicemente l'asterisco (*) sulla tastiera. Ora scegliamo View->Module'The_mask' in modo tale da ritrovarci all'istruzione 00401000, guardate un attimo il codice risulta essere tutto sballato!!! Per questo motivo bisogna analizzarlo e quindi scegliamo Analysis->Analyse code, ora il codice che ci viene mostrato risulta comprensibilissimo.

Senza dilungarmi troppo dato che ormai questa è una cosa scontata utilizziamo come punto di attacco la stringa Sorry bad serial, try again!!!, andiamo quindi a vedere se compare questa occorrenza nel debugger con il solito metodo, la stringa c'è allora andiamo a vedere in che punto del programma viene utilizzata:

004014EA XOR EAX,EAX 004014EC PUSH 004022D2 // Text = "Unregistered - - by Quequero" 004014F1 PUSH DWORD PTR DS:[402048] // hWnd = 0023053E ('Unregistered - -

                                                    // by Quequero',class='asm')

004014F7 CALL JMP.&USER32.SetWindowTextA // SetWindowTextA 004014FC PUSH 0 // Style = MB_OK|MB_APPLMODAL 004014FE PUSH 00402386 // Title = "Sorry!!!!" 00401503 PUSH 00402390 // Text = "Sorry bad serial, try again!!!" 00401508 PUSH 0 // hOwner = NULL 0040150A CALL JMP.&USER32.MessageBoxA // MessageBoxA

Quindi cosa succede???
Questo è il pezzo di codice che ci mostra la finestra di errore, ma chi richiama questo pezzo di codice???
Beh basta cliccare con il tasto sinistro del mouse sull'istruzione 004014EA e seguire verso l'alto la linea blu, ci ritroviamo qui:

0040131A PUSH 0F // Count = F (15.) 0040131C PUSH 00402058 // Buffer = The_mask.00402058 00401321 PUSH DWORD PTR DS:[40204C] // hWnd = 00390520 (class='Edit',parent=0023053E) 00401327 CALL JMP.&USER32.GetWindowTextA // GetWindowTextA

0040132C CMP EAX,0 // Controlla se non sono stati inseriti caratteri 0040132F JE SHORT 0040134E 00401331 CMP EAX,0C // Controlla se i caratteri sono 12 00401334 JNZ 004014EA // Salta all'errore se non sono 12

La funzione GetWindowTextA legge il testo inserito nel box e mette in EAX il numero di caratteri letti e mette alla locazione 00402058 la stringa letta quindi alla riga 0040132C controlla se non sono stati inseriti caratteri mentre la riga 00401331 controlla se la stringa inserita è di 12 caratteri. Che cosa dobbiamo fare??? Beh dobbiamo inserire una parola di 12 caratteri, io metto Valerio-Soft e premo il pulsante Check, ci da ancora la scritta Sorry bad serial, try again!!! ma sicuramente il flusso del programma sarà cambiato!!! Per verificare cosa succede piazziamo un breakpoint alla riga 00401334 e premiamo nuovamente il tasto Check, guardate il salto non viene effettuato quindi il box di errore viene richiamato da qualche altra parte del programma.

Adesso steppiamo in modo tale da individuare qualche pezzo di codice che effettua la manipolazione del serial inserito. Questo è ciò che troviamo dopo qualche istruzione:

00401482 MOV EAX,00402058 // ASCII "Valerio-Soft" 00401487 XOR BL,BL 00401489 MOV BL,AL 0040148B INC BL 0040148D ADD BL,21 00401490 XOR BL,2D 00401493 OR EDX,EDX 00401495 DEC EDX 00401496 CMP EDX,5687 0040149C JE 0040135E 004014A2 MOV EAX,00402058 // ASCII "Valerio-Soft" 004014A7 MOV DL,DS:[EAX] 004014A9 ADD DL,38 004014AC INC DL 004014AE DEC ECX 004014AF CMP ECX,0 004014B2 JE 0040135E

Beh questa porzione di codice vuole assomigliare ad un controllo sul serial ma in realtà Quequero ci vuole far perdere il nostro prezioso tempo :-D ,allora continuiamo a steppare! Lungo il nostro cammino incontriamo questa Call che ha lo scopo di modificare l'istruzione 004013D1 da una somma ad una Call.

00401373 CALL 00401514

Se volete entrarci fatelo ma vi ho già detto di cosa si tratta! Continuiamo a steppare ed arriviamo proprio sulla riga 004013D1

004013D1 CALL 00401532

Questa Call ha il compito di controllare se in alcune istruzioni del programma sono state patchate o qualcosa di simile, a noi non interessa dato che non vogliamo trasgredire alle regole del CrackMe. Continuiamo a steppare...

004013D6 XOR ECX,ECX // Azzera ECX 004013D8 MOV AL,DS:[EBX+ECX] // Al primo giro mette in AL il valore di V 004013DB MOV DL,DS:[ECX+4022FB] // Mette in DL il valore preso dalla locazione 004022FB 004013E1 XOR AL,DL // Fa lo XOR tra AL e DL e mette il risultato in AL 004013E3 CMP AL,DS:[ECX+4022EF] // Confronta il risultato con il valore alla

                                        // locazione 004022EF

004013E9 JNZ 004014EA // Salta all'errore se non sono uguali 004013EF INC ECX // Incrementa ECX 004013F0 CMP ECX,0C // Confronta ECX con il 12 esadecimale 004013F3 JNZ SHORT 004013D8 // Se non sono uguali salta e analizza l'altra lettera 004013F5 JMP SHORT 0040140C // Salta quando tutto è andato bene

Abbiamo individuato l'algoritmo per il serial inserito, quindi cosa succede??? L'algoritmo fa lo XOR tra la lettera (in AL) ed il valore corrispondente in DL preso dalla locazione 004022FB, il risultato dello XOR viene messo in AL e viene confrontato con il valore che si trova alla locazione 004022EF e successive locazioni. Quindi non ci resta che andare a prendere i 12 valori dalla memoria (sia a 004022FB che a 004022EF)ed effettuare il calcolo inverso in modo tale da ottenere la stringa da inserire nel box.

004022FB = 75 3F 8B 41 D2 FF B1 18 DB 49 B8 52 XOR 004022EF = 20 76 C8 1E B4 90 C3 7D AD 2C CA 72

         -----------------------------------------

55 49 43 5F 66 6F 72 65 76 65 72 20

I calcoli li potete effettuare con la calcolatrice di WinZoz, ora andate a vedere a quali lettere corrispondono i valori!!!

UIC_forever

Attenzione a non sbagliare, contate le lettere di UIC_forever sono 11 quindi nel box dovremo inserire anche uno spazio alla fine del serial infatti il 20 esadecimale corrisponde allo spazio.

Se inseriamo nel box UIC_forever allora viene eseguito il JUMP alla riga 004013F5, continuiamo a vedere cosa succede!!!

Very good, this is the good serial!!!

00401203 PUSH 0 // Mode = OF_READ|OF_SHARE_COMPAT 00401205 PUSH 004020E3 // pOfstruct = The_mask.004020E3 0040120A PUSH 004020DA // FileName = "mask.key" 0040120F CALL JMP.&KERNEL32.OpenFile // OpenFile 00401214 MOV DS:[4021EC],EAX // Salva l'handle del file 00401219 CMP EAX,-1 0040121C JNZ SHORT 00401223 // Salta se il file viene aperto 0040121E JMP 004012FB


Alla riga 0040120F tenta di aprire il file mask.key se non viene trovato allora inizializza EAX con FFFFFFFF (-1) e quindi il salto non viene effettuato e poi alla riga 0040121E si salta all'errore altrimenti se il file viene trovato in EAX viene messo l'handle del file. Adesso dobbiamo creare nella cartella che contiene il CrackMe il file mask.key ed al suo interno io ci scrivo come al solito ValerioSoft. Vediamo cosa succede......

00401223 XOR EAX,EAX // azzera EAX

00401225 PUSH 0 // Origin = FILE_BEGIN 00401227 PUSH 0 // pOffsetHi = NULL 00401229 PUSH DWORD PTR DS:[402293] // OffsetLo = 0 0040122F PUSH DWORD PTR DS:[4021EC] // hFile = 0000007C (window) 00401235 CALL JMP.&KERNEL32.SetFilePointer // SetFilePointer

0040123A PUSH 0 // pOverlapped = NULL 0040123C PUSH 004021F0 // pBytesRead = The_mask.004021F0 00401241 PUSH DWORD PTR DS:[4021F4] // BytesToRead = 20 (32.) 00401247 PUSH 004021FC // Buffer = The_mask.004021FC 0040124C PUSH DWORD PTR DS:[4021EC] // hFile = 0000007C (window) 00401252 CALL JMP.&KERNEL32.ReadFile // ReadFile 00401257 MOV CL,1A 00401259 JMP 0040144E


La Call alla riga 00401235 setta il puntatore all'inizio del file, mentre la Call alla riga 00401252 legge il file, questa volta viene passato alla funzione il numero di byte da leggere cioè 32 e la locazione in cui memorizzare i caratteri letti (004021FC) e poi anche la locazione in cui memorizzare il numero di caratteri letti (004021F0)

0040144E XOR ECX,ECX // azzera ECX 00401450 MOV ESI,004021FC // mette in ESI l'indirizzo che contiene // i caratteri letti

00401455 MOV EDI,00402239 // mette in EDI l'indirizzo 00402239 0040145A MOV AL,DS:[ECX+402252] // al primo giro mette il valore contenuto // alla locazione 00402225 in AL

00401460 MOV AH,DS:[ESI+ECX] // mette in AH la prima lettera letta 00401463 MOV DL,DS:[EDI+ECX] // mette il valore contenuto alla // locazione 00402239 in DL

00401466 XOR AH,AL // Xora AH con AL e mette il risultato in AH 00401468 CMP AH,DL // Confronta AH con AL 0040146A JNZ 004012FB // se non sono uguali salta all'errore 00401470 INC ECX // incrementa ECX per leggere il prossimo valore 00401471 CMP ECX,19 // confronta ECX con 19 (25 decimale) 00401474 JNZ SHORT 0040145A // salta se ha scandito tutti i caratteri // correttamente

00401476 JMP 0040125E // altrimenti reitera

Cosa si intuisce???

  1. La stringa ValerioSoft è errata dato che ha meno di 25 caratteri
  2. Per capire cosa scrivere nel file basta fare uno XOR tra i 25 valori contenuti alla locazione 00402225 con quelli

contenuti alla locazione 00402239.

00402252 = 65 4A B5 89 12 58 9F FF FB ED 55 21 A8 /B CE E5 18 97 45 3A 12 37 77 EE 58 XOR 00402239 = 3F 3F D7 ED 67 34 F3 9E 97 81 34 0F 86 55 AC 9C 38 C6 30 5F 63 42 12 9C 37

         --------------------------------------------------------------------------------

5A 75 62 64 75 6C 6C 61 6C 6C 61 2E 2E 2E 62 79 20 51 75 65 71 75 65 72 6F

Zubdullalla...by Quequero

Se il il key file contiene la stringa Zubdullalla...by Quequero allora sicuramente viene eseguito il JUMP alla riga 00401476 e quindi ci troviamo dinanzi a questo pezzo di codice:

0040125E PUSH 40 00401260 PUSH 0 // Mode = OF_READ|OF_SHARE_COMPAT 00401262 PUSH 00402163 // pOfstruct = The_mask.00402163 00401267 PUSH 004021E3 // FileName = "mask.exe" 0040126C CALL JMP.&KERNEL32.OpenFile // OpenFile 00401271 MOV DS:[4021EC],EAX 00401276 CMP EAX,-1 00401279 JNZ SHORT 00401280 0040127B JMP 004013F7

Questo pezzo di codice non ha bisogno di molte presentazioni, quindi dovreste aver già intuito che bisogna creare nella cartella del CrackMe il file mask.exe, allora fatelo!!! :-D
Per chi non lo avesse capito bisogna creare un bel file di testo, che contiene la scritta ValerioSoft e poi gli cambiate l'estensione da txt ad exe! Se avete fatto tutto per bene allora alla riga 00401279 viene eseguito il salto che ci porta alla riga 004013F7

00401280 PUSH 0 // Origin = FILE_BEGIN 00401282 PUSH 0 // pOffsetHi = NULL 00401284 PUSH DWORD PTR DS:[402297] // OffsetLo = B0 (176.) 0040128A PUSH DWORD PTR DS:[4021EC] // hFile = 00000080 (window) 00401290 CALL JMP.&KERNEL32.SetFilePointer // SetFilePointer

00401295 PUSH 0 // pOverlapped = NULL 00401297 PUSH 00402221 // pBytesRead = The_mask.00402221 0040129C PUSH DWORD PTR DS:[4021F8] // BytesToRead = 14 (20.) 004012A2 PUSH 00402225 // Buffer = The_mask.00402225 004012A7 PUSH DWORD PTR DS:[4021EC] // hFile = 00000080 (window) 004012AD CALL JMP.&KERNEL32.ReadFile // ReadFile

Beh anche questa parte ci dovrebbe essere familiare ma con una piccola variante, quale??? :-D
Osservate il valore pushato alla riga 00401284, beh quello è l'offset che ci indica il punto in cui inizierà la lettura del file, quindi già questo è indice di un errore dato che io la stringa ValerioSoft l'ho inserita all'inizio del file. Ci conviene andare avanti lo stesso e vedere cosa succede e poi traiamo le nostre conclusioni!!!

004012B4 XOR ECX,ECX // azzera ECX 004012B6 MOV ESI,00402225 // mette in ESI l'indirizzo che // contiene i caratteri letti // dal file

004012BB MOV EDI,0040226B // mette in EDI l'indirizzo 0040226B 004012C0 MOV AL,DS:[ECX+40227F] // mette in AL il valore che si trova // alla locazione 0040227F

004012C6 MOV AH,DS:[ESI+ECX] 004012C9 MOV DL,DS:[EDI+ECX] 004012CC XOR AH,AL // fa lo XOR tra AH e AL 004012CE CMP AH,DL 004012D0 JNZ SHORT 004012FB 004012D2 INC ECX 004012D3 CMP ECX,14 004012D6 JNZ SHORT 004012C0 004012D8 JMP 004013AB

...non continuo con i commenti dato che ormai abbiamo imparato a memoria la tecnica, quindi andiamo a prendere questi benedetti 20 valori dalla memoria per fare lo Xor:

0040227F = 6F 45 4B 8C 9A 21 18 46 1A 69 97 4A 5F 2D 3C 8A 9B 54 6D 12 XOR 0040226B = 28 2A 24 E8 BA 6D 6D 25 71 49 D4 38 3E 4E 57 EF E9 75 4C 33

         -----------------------------------------------------------------

47 6F 6F 64 20 4C 75 63 6B 20 43 72 61 63 6B 65 72 21 21 21

Good Luck Cracker!!!

Cosa dobbiamo fare??? Apriamo il file mask.exe che abbiamo creato in precedenza con AXE, poi inseriamo nel file tanti zeri fino ad arrivare all'offset AF, dall'offset B0 i valori esadecimali che ci siamo calcolati oppure andate nell'Ansi Text corrispondente e scrivete Good Luck Cracker!!!, poi salvate il file. Avviamo nuovamente il CrackMe, inseriamo il serial UIC_forever (+ lo spazio finale) e premiamo il pulsante Check!!!

Totally Registered

Registry Attack

Il PEtite 1.2 se non sbaglio è un programma che serve a comprimere i file eseguibili e quindi non utilizza sofisticate tecniche per evitare il dump della memoria quindi avviamo il nostro file eseguibile e poi apriamo il nostro amato PEditor 1.7, ora clicchiamo su taskse poi andiamo a selezionare il file the mask.exe, clicchiamoci su con il tasto destro del mouse e poi scegliamo l'opzione Dump (Full). Diamo un nome al file e salviamo!!! Adesso proviamo ad avviare il file appena salvato, OK funziona perfettamente e non c'è neanche bisogno di cambiare l'Entry Point dato che l'algoritmo che decritta il file a runtime automaticamente modifica la sua prima istruzione in un JUMP 00401000 che corrisponde alla prima vera istruzione del programma.


Note Finali

Bene siamo venuti a capo della situazione anche questa volta, colgo l'occasione per salutare in blocco l'intera UIC e QUEQUERO per aver scritto questo semplice CrackMe!!! :-D ;-) :-P

Ciaoooooooooooooooooo alla proximaaaaaaaaa

ValerioSoft


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.