Ritz CrackMe #1 |
|
|
Data |
by "GuZuRa" |
|
Published by Quequero |
||
Chi sa soffre... | Guzura, bravo hai avuto un'idea davvero originale :) e non importa ciò che l'autore si aspetta da noi, perchè il lavoro del reverser è proprio quello di attaccare ciò a cui il programmatore non ha pensato :) bello anche il programmino in Masm, cmq per le parti di codice DOVETE usare il font "Courier New" perchè essendo a spaziatura fissa vi rende il tutto mooolto più chiaro di come non sarebbe con altro font |
Chi non sa soffre di più... |
UIC's form |
|
UIC's form |
Difficoltà |
( )NewBies (x)Intermedio ( )Avanzato ( )Master |
/*
Piccolo commento di Ritz (se Que me lo concede;)).
Uno dei problemi maggiori di questo crkme era il fatto di dover uscire da quei vari cicli di calcoli. In realtà era sufficiente trovare un particolare valore affinchè il tutto fosse (quasi) scontato, e GuZuRa per far ciò sembra aver utilizzato il metodo più semplice... far fare il tutto al computer (uovo di Colombo rulezzz;) ).
Leggete bene questo tute che è veramente bello, se poi qualcuno trova il keyfile che ho usato io allora mi contatti (la chiave originale è una frase di senso compiuto).
Bravo GuZuRa!
Ritz
*/
Questo crackme è il mio primo risolto :))) è mi ha dato parecchie soddisfazioni dato che sono newbie
Introduzione |
Tools usati |
URL o FTP del programma |
Notizie sul programma |
Essay |
Mettiamo un bel breakpoint sul salto che ci dice che siamo belli esatamente a :4011A5 e lanciamo il programma, clikkiamo Check e il programma se ne sbatte del nostro breakpoint , ma noi ce lo aspettavamo perchè oltre il salto (che se non eseguito ci sbatte fuori, sempre quello in :4011A5) c'erano due punti che ci portavano alla Mboxa che ci diceva di riprovare, ergo, andiamo a vedere i due salti (vi riporto dove avvengono i due salti condizionati :00401158 e :00401171)
Troviamo questo pezzo di codice che riporto per intero:
* Possible StringData Ref from Data Obj ->"RitzKey.key"
:0040114B push 0040218A ---------->
Salva nello stack la stringa RitzKey.Key
* Reference To: KERNEL32.OpenFile
:00401150 Call
00401219 ---------->
Chiama questa funzione che verifica che nella directory corrente ci
sia il file
RitzKey.Key
:00401155 cmp eax, FFFFFFFF ----------> Se c'è il
file non salta
:00401158 je 004011A7
----------> Ci spara alla Mboxa "Siete Cattivi"
Primo salto
:0040115A push 00000000
----------> Primo parametro in ingresso alla ReadFile inutile per noi
:0040115C push 004021FC
----------> Parametro inutile
per noi
:00401161 push 00000060
---------->
Numero dei byte da leggere
:00401163 push 00402198
----------> Idirizzo dove vengono memorizzati i dati letti dalla ReadFile
:00401168 push eax
----------> Handle del file da leggere
* Reference To: KERNEL32.ReadFile
:00401169 Call
0040121F ---------->
Chiama
la ReadFile
:0040116E cmp eax, 00000000 ----------> Verifica
se il file era vuoto o almeno se la read è andata a
buon fine
:00401171 je 004011A7
----------> Ci spara alla Mboxa "Siete Cattivi"
Secondo salto
Morale della favola : dobbiamo creare un file RitzKey.Key lungo 96 Byte al quale appoggiarci per andare avanti; ma cosa ci andrà dentro? Se i salti non sono andati a buon fine (ciò che volevamo) si prosegue nel codice quindi andiamo a vedere cosa ci sta dopo
Prima però dobbiamo costruire un dummy file (Digressione : dummy in inglese significa fantoccio e non credo che nessuno abbia mai chiamato così un file creato per fottere una protezione; questo termine mi è venuto in mente perchè sto studiando Elettronica 2 e il termine dummy e riferito ad alcune celle che si trovano nei blocchi ram (dentro il silicio) e servono soltanto per fare in maniera che risulti bilanciato il carico capacitivo visto dalle due bit line in ingresso ad un sense amplifier che deve rilevare la tensione differenziale, proprio tra le due bit line ,e quindi riconoscere se il dato letto è una tensione alta (1) oppure bassa (0); la trattazione è molto lacunosa devo ancora studiare... però il termine Dummy File mi sembra carino e abastanza adeguato... fatemi sapere)
Ah si il file: lo creiamo con Hiew o con qualsiasi HexEditor che vi piace (Andatevi a leggere il tut di prima di Tin_Man che vi spiega anche Hiew) e gli cacciamo dentro 96 byte di questo tipo 30 31 32 33 34 35 36 37 38 39 30 31 32 ... e così via (31 equivale a 1 in ASCIIm, 32 a 2 e inoltre 31 è un byte solo non due ciò vuol anche dire che ogni carattere occupa un byte occhio :))))
Eravamo rimasti al codice dopo i salti da non effettuare
:00401173 xor edi, edi ----------> Azzera edi
:00401175 xor ecx, ecx ---------->
Azzera ecx
Mi pice quando si incominciano a vedere delle variabili
inizzializzate, mi emoziono
* Referenced by a Jump :00401198(C) *condizionato*
:00401177 mov eax, dword ptr
[edi+00402198] ---------->
Muove in eax il contenuto di 402198+edi
:0040117D mov ebx, dword ptr [edi+0040219C] ---------->
Muove in eax il contenuto di 40219C+edi
:00401183 imul ebx
----------> Moltiplica eax per ebx e
il contenuto va in eax : edx (eax contiene i byte meno significativi) Imul è moltiplicazione con segno occhio;)
:00401185 add eax, ebx
---------->
Aggiunge
ebx a eax
* Referenced by a Jump :0040118E(C)
:00401187 add al, bl
---------->
Aggiunge bl a al
:00401189 dec bl
---------->
Decresce di uno bl
:0040118B cmp bl, 00
---------->
Ovvio
:0040118E jne 00401187 ---------->
In pratica si ciclano queste 4 ultime istruzioni fino a che bl non è zero
:00401190 add ecx, eax
---------->
Aggiunge eax ad ecx
:00401192 add edi, 00000004 ---------->
Aggiunge ad
edi 4
:00401195 cmp edi, 0000005C ---------->
Non lo
commento per ora
:00401198 jne 00401177
----------> Ci spara sopra a ricominciare tutto l'elaborazione con altri byte
:0040119A mov eax, ecx
---------->
Banale
:0040119C imul ecx
---------->
Come sopra
:0040119E imul edx
---------->
Attenzione a questa istruzione che non è così banale almeno secondo me
:004011A0 cmp eax, EF0BB1F8
---------->
In eax se c'è questo valore...
:004011A5 je 004011BF
---------->
Se
eax è EF0BB1F8 salto alla Mboxa che ci fa i complimenti altrimenti se proseguiamo finiamo
dove non vogliamo... Locazione che abbiamo già visto sopra questa eh...
Il codice è tutto qui ma ora viene il casino : incominciamo col capire come vengono letti e manipolati i byte: vi ricordate dove la Readfile aveva cacciato ciò che aveva letto? Proprio nella locazione 402198, ora metto i primi 4 byte in eax (al primo giro ho edi azzerato) e in ebx 4 byte a partire dalla locazione 40219C (proprio 4 byte dopo la locazione 402198) poi ci sono un pò di operazioni matematiche che elaborano i valori nei registri fino a che non si arriva alla locazione :401190 dove aggiungo a ecx il valore di eax (prima cosa importante ad ogni giro sommo eax al vecchio valore di ecx (vi ricordo che all'inizio prima del primo ciclo azzero ecx quindi ecx è usata come una variabile che viene di volta in volta incrementata del nuovo valore di eax) seconda cosa da notare, prima di ricominciare il ciclo per intero edi è comparato con 5C (proprio 60-4 in hex; chiaro no? Al primo giro uso i primi 8 byte che trovo in 402198, 4 in eax e i 4 seguenti in ebx, al secondo giro i byte da 5 a 12 e così via) Se non è ancora chiaro steppate col WDasm per due o tre cicli osservando cosa finisce in eax e ebx e tutto vi si illuminera
Da notare è anche come vengono disposti i byte nei registri, se avete usato un dummy file (bello no?:))))) come vi ho detto io dovreste vedere al primo giro in eax : 33 32 31 30 e in ebx : 37 36 35 34 ,fateci caso
Bene non abbiamo ancora concluso una pippa però se avete capito tutto la generazione del key file diventera facile ma ci sono ancora un paio di cose difficilotte. Tutto si risolve nell'avere in eax il valore EF0BB1F8 (offset :4011A0) ma come si genera questo valore: questo non è così scontato,finito l'ultimo ciclo di conti (quando edi = 5C) abbiamo un certo valore in ecx che viene mosso in eax, poi si moltiplica eax per ecx e poi il nuovo eax per edx ma qui c'è qualcosa che dovrebbe turbarvi un poco a meno che non siate dei masochisti della matematica, in realtà è come se avessimo la seguente equazione ecx * ecx * edx = EF0BB1F8 (o meglio l'equazione da un risultato della forma edx :eax ma la comparazione si fa solo su eax) ma c'è un problema; edx è generato proprio da ecx * ecx (ricordate che imul caccia il risultato in edx : eax cioè cazzi acidi) Se avete voglia potete provare a farvi i conti a mano, vi ricordo che dovete trovare un numero che moltiplicato per se stesso dia un pezzo del risultato in eax e un pezzo in edx e che moltiplicando ora il nuovo eax per il nuovo edx dia in eax il valore EF0BB1F8 e in edx ciò che vi pare
Il fedele Winamp (non l'ho nominato tra i tools?) mi viene in soccorso con un pezzo di Elio ( La visione ) e io realizzo che forse so abbastanza assembler per creare un programmino che becchi il valore che devo avere in ecx (tale che l'equazione sopra sia risolta...) al posto mio (Allego il codice che ho compilato col Masm32)
.386
.model flat, stdcall
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
ExitProcess PROTO ,:DWORD
MessageBoxA PROTO ,:DWORD, :DWORD, :DWORD, :DWORD
.data
MsgBoxCaption db "Beccato",0
dabeccare dd 4010521080 ;equivale a EF0BB1F
beccatoecx db "Beccato ecx guarda esi",0
beccatoedx db "Beccato edx guarda edi",0
.const
NULL equ 0
MB_OK equ 0
.code
inizio:
mov ecx,00000001h ;valore di ecx di primo tentativo
conto:
xor edx,edx ;azzero edx
mov eax,ecx ;come nel crackme
imul ecx ;come nel crackme
mov esi,ecx ;salvo il valore di ecx che ho utilizzato in esi
mov edi,edx ;salvo il valore che ho ottenuto per edx dalla ecx * ecx in edi
imul edx ;come nel crackme
cmp eax,dabeccare ;verifico se in eax ho EF0BB1F
je fine
inc ecx ;incremento ecx nel caso il valore precedente non abbia funzionato
jne conto
fine:
INVOKE MessageBoxA, NULL,ADDR beccatoecx, ADDR MsgBoxCaption, MB_OK
INVOKE MessageBoxA, NULL,ADDR beccatoedx, ADDR MsgBoxCaption, MB_OK
je conto
end inizio
Questo programmino non fa altro che rifare i passaggi del codice del crackme verificando per vari valori di ecx (da 1 a ...) se uno di questi valori soddisfa le specifiche richieste dall'equazione di cui sopra... E' stato il mio primo programma in asm quindi sono mui contento, se non lo capite (mi sembra strano) andate a vedere i tut di iczelion (si scriverà così?) sul Wasm32
Lanciamolo e vediamo che spunta una prima messageboxa che vi dice che ha beccato l'ecx che ci serve e di guardare esi (nota: potete usare sice mettendo un bpx sulla Mboxa e scrivervi il valore di esi che vedete che è l'ecx che cercavamo) e analogamente per il valore di edx dovete guardare edi (le API di windows come la Messageboxa non modificano esi e edi quindi ce li ritroviamo pari pari dopo la chiamata non modificati :)))) Se usate Wdasm32 per disassemblare il programmino e poi lo steppate questo vi becca due valori possibili per ecx invece una volta compilato dopo aver beccato il primo si chiude(chi sa perchè?) Lo so il vero reverser avrebbe fatto apparire ecx e edx nel testo della Mboxa ma vi ricordo che questo è stato il mio primo programmino asm e voi non sapete quanto mi è costato
Troviamo che ecx può essere questo valore 0033261D oppure B2450FEA ma come facciamo ad avere in ecx questo valore prima che incomincino le varie imul?Se avete seguito il mio consiglio e avete steppato il crackme per un paio di cicli vi sarete accorti che il punto piu fastidioso che incasina le cose è sicuramente il ciclo add al bl , dec bl ... Come facciamo per sfoltire la computazione : semplice se bl fosse uguale a 01 l'istruzione add al bl sarebbe eseguita una sola volta ogni ciclo, apriamo hiew e ricostruiamo il file con delle sequenze di questo tipo 01 00 00 00 01 00 00 00 01 00 00 00 (ricordando di inserire roba per 96 byte) e vediamo come si comporta, Occhio alla disposizione dei byte; vi avevo fatto notare come finivano i byte dentro i registri (Vi vengono fuori tutte faccine;)))))
Riprendete il WDasm32 e steppate un pò guardando ecx, ogni ciclo a ecx viene sommato 3, meglio detto; ad ogni ciclo ad eax viene sempre sommato 2 perchè con ebx uguale a 00000001 è sempre così e eax è uguale a uno (questo avviene solo con il dummy che vi ho consigliato per sfoltire i conti) e alla fine il in ecx ho 45 (molto lontano dal valore che mi interessa :(((( )
Prendetevi una pausa di cinque minuti chiamate la morosa e poi tornate qua (è una cosa pazzesca, dopo che ho chiamato la mia ragazza tutti i programmi mi funzionano immediatamente) Ah si, se non avete la ragazza è ora che molliate un po di più il pc...
Bentornati ;) non avete avuto una rivelazione? Ci sono due parti del dummy file che vengono considerte una sola volta; una sono i primi 4 byte che passano per eax al primo ciclo e poi non si usano più, l'altra sono gli ultimi 4 che passano per ebx all'ultimo ciclo, ma cosa possiamo fare (lo scopo era avere in ecx il valore 0033261D o l'altro trovato) : la scelta cade sui primi 4 byte del file per due motivi : 1) se fissiamo gli ultimi 4 byte del file devo confrontarmi col ciclo add al bl , dec bl ... perchè devo andare a modificare i penultimi 4 byte ma cio si ripercuoterebbe su tutto e dovrei modificare i precedenti... 2) ai primi 4 byte viene aggiunto 2 (perchè stanno in eax) e poi non vengono più toccati , (ricordate qualche riga sopra cosa ho detto) questo valore viene messo in ecx e poi per tutti i cicli successivi ad ecx viene aggiunto3
Bhe ora è banale capire cosa devo mettere nei primi 4 byte : ricordate con il secondo dummy file che valore finiva in ecx? 45 quindi non mi resta altro che fare 0033261D - 42 - 2 per avere il valore da mettere nei primi 4 byte cioè 003325DA (occhio a come lo mettete in Hiew comunque riporto il Dummy sotto) tolgo 42 che è quello che viene aggiunto a ecx dal secondo ciclo in poi e poi -2 del primo ciclo e qui finisce la lezione se non avete capito steppate anche con l'ultimo dummy e Amen
00000000: D9 25 33 00-01 00 00 00-01 00 00 00-01 00 00 00
00000010: 01 00 00 00-01 00 00 00-01 00 00 00-01 00 00 00
00000020: 01 00 00 00-01 00 00 00-01 00 00 00-01 00 00 00
00000030: 01 00 00 00-01 00 00 00-01 00 00 00-01 00 00 00
00000040: 01 00 00 00-01 00 00 00-01 00 00 00-01 00 00 00
00000050: 01 00 00 00-01 00 00 00-01 00 00 00-01 00 00 00
Provate a farne un altro dummy con l'altro valore per ecx
ARRIVEDERCI (andate a vedere il film di South Park)
Byez GuZuRa
|
Disclaimer |
UIC's page of reverse engineering, scegli dove andare: |
Home Anonimato Assembly CrackMe ContactMe Forum Iscrizione |
Lezioni Links Linux NewBies News Playstation |
Tools Tutorial Search UIC Faq |
UIC |