Sogno o son desto? Per la prima volta il nostro caro
Spinone ci presenta un form...Fatto bene...Il problema è che quello che sta scritto qua
dentro è anche meglio del form....Bravo spino :)))
UIC's form
Spin0ne
UIC's form
Difficoltà
(X)NewBies (
)Intermedio ( )Avanzato ( )Master
Proverò a commentare la soluzione di questo crackme molto simpatico............. come
il suo autore :)))))).
6° Corso Newbies
Registry sniffing
Written by Spin0ne
Introduzione
Questa volta Andrea ci ha preparato un crackme per farci prendere confidenza con il
registro di Wiindows.
Un crackme multilivello didatticamente molto valido (bravo André!!) che ci fà
prendere gradatamente dimestichezza con le chiavi di registro di windows.
Essay
Innanzitutto vorrei fare i complimenti all'autore, non è facile scrivere crackme per i
newbies anche xchè spesso si danno per scontate delle conoscenze che invece non sono
tali.
Il programma è facilmente reversabile con l'aiuto del Regmon, ma ho voluto
appositamente usare solo il Sice perchè credo che cosi facendo si e costretti a ragionare
maggiormente sulle Api.
Apriamo il programma e sulle info subito Andrea ci ammonisce dal patchare il proggy.
Premiamo il pulsante relativo al primo livello e...... ci prendiamo del "Lamah"
sul muso! Bene...anzi male! apriamo Softice, settiamo un Bpx messageboxA e vediamo che
succede. Chiudiamolo, nuovamente clic sul pulsante e Sice poppa all'Api messageboxA,
pigiamo F12 per uscire dalla funzione e ci ritroviamo nella MFC2.DLL. Sarà sufficiente
steppare fino al ret per arrivare finalmente nel programma "Sesto" ( ve ne
accorgerete dal nome sulla barra del Sice in basso a destra.) e precisamente all'indirizzo
401567:
:00401530 push ecx
:00401531 lea eax, dword ptr [esp]
:00401535 push esi
:00401536 push eax
:00401537 push 000F003F
:0040153C push 00000000
:0040153E push 0040409.....................Questo parametro è la locazione dove punta al
nome della chiave da aprire
:00401543 mov esi, ecx
:00401545 push 80000001
:0040154A Call dword ptr [00405290]
:00401550 test eax, eax....................Eax=0 se la chiave è stata trovata
:00401552 je 00401575......................Salta se trovata, altrimenti continua verso la
nag
:00401554 push 00000010
:00401556 push 0040408C
:0040155B push 00404070
:00401560 mov ecx, esi
:00401562 Call 00401C2E....................Chiamata alla nag
:00401567 mov ecx, dword ptr [esp+04]......Qui approdate con il Sice
:0040156B push ecx
:0040156C Call dword ptr [0040528C]
:00401572 pop esi
:00401573 pop ecx
:00401574 ret
:00401575 push 00000030
:00401577 push 00404064
:0040157C push 00404020
:00401581 mov ecx, esi
:00401583 Call 00401C2E...................finestra delle congratulazioni
Come vedete siamo atterrati sotto una call che se viene eseguita è quella che vi
sbatte in faccia la nag; quindi vuol dire che qualcosa precedentemente è andato storto.
Proviamo a vedere cosa spulciando il codice un pò più sù.......... Vi accorgerete che
poco prima c'è la chiamata all'Api "RegOpenKey". Cosa fa di bello quest'Api?
beh.......un po' di fantasia.......apre il registro di windows per la ricerca di chiavi.
Dovete sapere che prima di eseguire la chiamata all'Api è necessario passare alla
funzione alcune informazioni (parametri). Queste ultime vengono passate (o fissate in
memoria) attraverso una serie di istruzioni "push". Tenete a mente che
il penultimo push prima della chiamata RegOpenKey contiene la locazione dove è
memorizzato il nome della chiave da ricercare nel registro.
E' sufficiente quindi andare in Sice, dare il comando "d 404094",
(senza le apicine) per veder apparire nella finestra dati in caratteri ASCII il nome della
chiave che verrà ricercata. Nel nostro caso l'autore del crackme è un po
megalomane (come tutti i coders e reverser :))) e la chiave si chiama: Andreageddon
Se la chiave verrà trovata il valore ritornato in eax sarà zero, il test sara
positivo ed il jz successivo verrà effettuato portandovi ad un altro punto del proggy.
Viceversa se il risultato in eax è diverso da zero e la chiave non è stata trovata, il
programma continuerà verso la prossima call, che è quella della nag "Lamah".
Allora dobbiamo solamente creare la chiave "AndreaGeddon" per
superare il primo livello?.....si certo...apriamo il registro con regedit e....azzo quanti
gruppi di chiavi!! dove la creamo??? Humm....oltre alla possibilità di farvi aiutare da
Regmon che potrà rivelare la chiave che il proggy tenta di aprire, potete anche rilevarlo
attraverso i famosi parametri passati prima della call RegOpenKeyExeA. Infatti in questo
caso il gruppo di chiavi è definito dall'ultimo push all'indirizzo 401545 : push
80000001. Questo valore corrisponde al gruppo HKEY_CURRENT_USER. E' lì che la chiave va
creata............avete fatto? si.... eccovi le prime congratulazioni.. Uff...e questa è
andata! A proposito visto che sono andato a rivedermi la guida all'Api vi farà comodo
sapere che:
80000001 corrisponde a: HKEY_CURRENT_USER
80000000 =HKEY_CLASSES_ROOT
80000002= HKEY_ LOCAL_MACHINE
80000003= HKEY_USER
80000004=:HKEY_PERFORMANCE_DATA
80000005=HKEY_CURRENT_CONFIG
80000006=HKEY_DYN_DATA.
Passiamo al 2° livello. questa volta cliccando sul 2° pulsante, di
ritorno dalla MessageboxA si atterra nel programma all'indirizzo 4016CC. Guardiamo cosa
avviene prima. Risalendo fino a ritrovare la chiamata RegOpenkeyexeA potremo accorgerci
che all'indirizzo 4015F3 la funzione viene messa in ESI e poi abbiamo il solito passaggio
dei parametri con la serie di push. Anche qui il penultimo indirizzo pushato contiene il
nome della chiave che verrà ricercata. Digitiamo in Sice D 404308 e troveremo nella
datawindow: AndreaGeddon\1 questo vuol dire che verrà cercata la chiave
AndreaGeddon e poi la sottochiave 1 e se trovate dovremmo passare di livello.
Proviamo...creamo la sottochiave 1 e..........ci ribecchiamo di nuovo del
"Lamah". Azz ma cosa è successo!!??? ritorniamo in Sice, settiamo un Bpx
all'inizio della routine all'indirizzo 4015F0 e steppiamo
:004015F0 push ecx
:004015F1 push ebx
:004015F2 push esi
:004015F3 mov esi, dword ptr [00405290].....Esi punta all'indirizzo della Api RegOpenKey
:004015F9 lea eax, dword ptr [esp+08]
:004015FD push edi
:004015FE push eax
:004015FF push 000F003F
:00401604 push 00000000
:00401606 push 00404308.....................Viene salvata la locazione che punta alla
chiave da aprire
:00401699 je 004016B0......................Salta alla finestra delle congratulazioni se
trovata
:0040169B push 00000010
:0040169D push 0040408C
:004016A2 push 00404260
:004016A7 mov ecx, edi
:004016A9 Call 00401C2E
:004016AE jmp 004016D0|
:004016B0 push 00000030
:004016B2 push 00404258
:004016B7 push 00404230
:004016BC mov ecx, edi
:004016BE Call 00401C2E....................Chiamata alla finestra delle Congratulation
Dunque come potete vedere dalle istruzioni, viene cercata la sottochiave
AndreaGeddon\1, il primo test è positivo ma il programma continua e ci ritroviamo di
fronte ad una serie di push prima della call ESI alla RegOpen.... Questa volta il push
della locazione di memoria 4042D4 salva ancora una chiave che verrà ricercata : AndreaGeddon\1\2
e che se non trovata....nisba. Ok creamo anche la "2" e
proviamo.........."Lamah" (ma sulla buona strada)....ecchepalle!!! Ripercorrendo
la routine ci accorgiamo che il proggy continua ancora ed, anche in questo caso, il
penultimo push salva un'ulteriore sottochiave: AndreaGeddon\1\2\4.
Creiamo anche la "4" e... Pam!!........"Cool".... si passa al
terzo.
Eseguendo la stessa procedura anche per questo nuovo livello, questa volta approderemo
all'indirizzo 40176D. Spostatevi più sù e settate un bpx al 401729 che è l'inizio della
routine. Steppando riusciremo ad individuare facilmente i famosi push che passano i
parametri prima della chiamata all'Api. Questa volta la locazione di memoria dove viene
salvato il nome della chiave è la 4044E4 e lì potremo ritrovare: AndreaGeddon\WhatIsTheMatrix.
Riapriamo il regedit e creamo sotto AndreaGeddon questa sottochiave........Senza molta
convinzione proviamo a vedere........infatti una nag ci comunica che non siamo gli eletti!
Ritorniamo in Sice e steppiamo.
:00401729 push eax
:0040172A push 000F003F
:0040172F push 00000000
:00401731 push 004044E4...................Salva la locazione della chiave
AndreaGeddon\WhatIsTheMatrix
:00401758 je 0040177B.....................Salta se trovata
potremo vedere che il primo test all'indirizzo 401756 è positivo ed il jz successivo
è eseguito. Andando avanti ci imbattiamo in un'altra serie di push.......controlliamo il
penultimo ed alla locazione 404444 leggeremo in ASCII: WelcomeToTheRealWorld.
qui cominceremo a pensare che il gioco si stia facendo monotono e che sia sufficiente
creare ancora quest'ultima sottochiave, invece no!.... se lo fate non otterrete nulla.
:0040177B mov edx, dword ptr [esp+0C]
:0040177F lea ecx, dword ptr [esp+10]
:00401783 push ecx
:00401784 push ebx
:00401785 push 00000000
:00401787 push 00000000...................Tipo di valore
:00401789 push 00404444...................Salva la locazione della chiave
AndreaGeddon\WhatIsTheMatrix
:00401797 je 004017AE.....................Salta se trovata
Infatti se avete fatto un po' di attenzione avrete visto che questa volta non è la
classica call RegOpenKey ad essere chiamata, ma bensì la RegQueryValue. Questa a
differenza della prima, legge anche il valore attribuito ad una chiave. Pertanto
"WelcomeToTheRealWorld" non e una chiave ma bensi il nome di un valore.Ok,
apriamo regedit ed alla chiave WhatIsTheMatrix clicchiamo con il destro ed alla voce
"nuovo" invece di scegliere chiave ci viene posto il dilemma: Stringa, Valore
binario, Valore Dword..... Cosa scegliamo??.....beh anche questa volta ci viene in aiuto
l'analisi dei push eseguiti prima della call. Infatti il tipo di valore lo deduciamo dal
push 00 all'indirizzo 401787. Se viene passato il parametro 00 che è uguale a NULL, vuol
dire che il tipo di valore puo' essere di qualsiasi tipo (03 =binario, 04=Dword). per
comodità scegliamo il tipo stringa e creamo il nome "WelcomeToTheRealWorld".
Bene a questo punto proviamo..... dovrebbe funzionare...........macché.... niente da fare
ancora, è cambiata la nag che ci segnala che dovremmo essere vicini ma..... ancora nulla.
Ritorniamo in Sice, questa volta vedremo che il test all'indirizzo 401795 è positivo
quindi il prog. salta la call alla nag e ci porta a 4017AE.
:004017AE push edi
:004017AF xor edi, edi.....................Viene azzerato edi
:004017B1 mov al, byte ptr [edi+ebx].......In al il byte letto dall'Api e puntato nella
locazione edi+ebx
:004017B4 mov cl, byte ptr [esp+edi+18]....In cl il byte puntato dalla locazione in
esp+edi+18
:004017B8 cmp al, cl.......................Confronta se sono uguali
:004017BA jne 004017E9.....................Salta alla nag se diversi, altrimenti continua
:004017BC cmp edi, 00000007................Verifica se le iterazioni sono arrivate a 7
:004017BF jne 004017E1.....................Salta se inferiori, altrimenti continua
:004017C1 push 00000030
:004017C3 push 004043C4
:004017C8 push 00404378
:004017CD mov ecx, esi
:004017CF Call 00401C2E...................Chiamata alla finestra delle congratulation
:004017D4 push 00000001
:004017D6 lea ecx, dword ptr [esi+000000E0]
:004017DC Call 00401C28
:004017E1 inc edi..........................Incrementa il contatore
:004017E2 cmp edi, 00000007................Verifica il n° delle iterazioni
:004017E5 jle 004017B1
:004017E7 jmp 00401803
:004017E9 push 00000010
:004017EB push 00404360
:004017F0 push 00404318
:004017F5 mov ecx, esi
:004017F7 Call 00401C2E....................Chiamata alla nag
Comincia una routine dove vengono mossi dei byte in AL e CL che poi vengono
confrontati. In CL viene messo inizialmente 54 che in ASCII è la lettera T, il confronto
fallisce xchè AL=0 (non abbiamo inserito alcun dato). Supponendo che il confronto fosse
positivo il jnz che ci porta verso la nag non avverrebbe ( lo possiamo simulare invertendo
il flag Z). Viene verificato se EDI(contatore dei cicli) è = a 7, altrimenti viene
incrementato ed il ciclo si ripete. Possiamo eseguire tutte le iterazioni annotando tutte
le volte le lettere che vengono caricate in CL oppure, visto che i byte caricati in CL
sono memorizzati nella locazione EDI+ESP+18, se controllate con il solito comando "d
edi+esp+18" leggerete la stringa "Trinityy". Chiaro
no!!??........apriamo regedit ed al nome "WelcomeToTheRealWorld" inseriamo il
valore Trinityy.........e saremo eletti!!!
Siamo all'ultimo livello. Questa volta la nag ci fà cadere
nell'oblio. Solita procedura e.......atterriamo all'indirizzo 401871 spostiamoci + sù e
settiamo il bpx all'inizio della routine precisamente su 401842. Steppiamo fino alla serie
di push che ormai conosciamo bene e li troveremo che il penultimo salva la chiave "AndreaGeddon\Sergej\Rachmaninov"
:00401842 push eax
:00401843 push 000F003F
:00401848 push 00000000
:0040184A push 00404674...................Cosa farà questo push????
:004018A0 je 004018B3.....................Salta se trovata
Per l'ultima volta leggiamo in memoria qual'è il nome del valore che
verrà aperto dall'Api RegQueryValue. Vedremo che è
"QualBuonvento"................creamolo scegliendo il tipo "stringa" e
potremo procedere verso l'algoritmo che valuterà se il dato letto in
"Qualbuovento" è correto. Per comodità ho inserito preventivamente il valore
"Spin0"
:004018B3 mov edi, esi.................Muove in edi la locazione di esi che contiene
Spin0
:004018B5 or ecx, FFFFFFFF
:004018B8 xor eax, eax.................Azzera eax
:004018BA xor edx, edx.................Azzera edx
:004018BC repnz........................Passa in rassegna i byte e ne fa il conteggio
:004018BD scasb
:004018BE not ecx
:004018C0 dec ecx......................In Ecx il n° dei char
:004018C1 je 004018DC..................Se ecx=0 salta alla nag (controlla se ci cono
dati)
Dunque vediamo di chiarire cosa fa questa prima routine La locazione della stringa
letta dall'Api viene messa in Esi. l'istruzione rpz scasb fa un conteggio dei byte che la
compongono (+1 per il carrage return) il risultato è poi messo in ecx che se uguale a 0
(nessun dato rilevato) setta il flag Z che fa eseguire il jz a 4018DC e........siamo
fuori. Viceversa il programma continua:
:004018C3 mov al, byte ptr [edx+esi]...Mette in al il byte della stringa Spin0
puntato (edx viene incrementato di volta in volta e funge anche da puntatore al byte)
:004018C6 mov edi, esi
:004018C8 add al, dl...................Aggiunge al byte in al la sua posizione
:004018CA or ecx, FFFFFFFF
:004018CD mov byte ptr [edx+esi], al...Il risultato di al sovracrive il byte che è
stato considerato
:004018D0 xor eax, eax
:004018D2 inc edx......................Sposta il puntatore al prosimo byte da
trattare
:004018D3 repnz........................Ripete il conteggio dei byte componenti la
stringa
:004018D4 scasb
:004018D5 not ecx
:004018D7 dec ecx
:004018D8 cmp edx, ecx.................Confronta il n° dei char con il contatore
:004018DA jb 004018C3..................Se non è = riprendi il ciclo, altrimenti
continua
Come avete intuito viene messo in al il byte della stringa letta dall'Api al quale
verrà poi aggiunto il valore della sua posizione che ha la seguente logica:
posizione 1° byte: dl = 0
posizione 2° byte: dl = 1
posizione 3° byte: dl = 2
posizione 4° byte: dl = 3
..............................
..............................
il risultato dell'addizione viene messo nella stessa locazione di memoria del byte
trattato che verrà quindi sovrascritto. Il ciclo si ripete sino a quando il contatore in
dl sarà = a cl che contiene il n° di char che compone la stringa. vediamo come
l'agoritmo continua a trattare la nostra stringa:
:004018DC mov edi, esi................Muove in edi la locazione di esi che contiene
la stringa precedentemente già manipolata
:004018DE or ecx, FFFFFFFF
:004018E1 xor eax, eax................Azzera eax
:004018E3 xor edx, edx................Azzera edx
:004018E5 repnz.......................Conteggio dei byte componenti la stringa
:004018E6 scasb
:004018E7 not ecx
:004018E9 dec ecx.....................In ecx il n° dei char
:004018EA je 00401902.................Salta alla nag se ecx=0
:004018EC mov al, byte ptr [edx+esi]..Mette in al il byte puntato della stringa
:004018EF mov edi, esi
:004018F1 add bl, al..................Addiziona a bl il byte contenuto in al ( ad
ogni ciclo cunula tutti i byte)
:004018F3 or ecx, FFFFFFFF
:004018F6 xor eax, eax................Azzera eax
:004018F8 inc edx.....................Azzera edx
:004018F9 repnz.......................Nuova scansione per conteggio byte
:004018FA scasb
:004018FB not ecx
:004018FD dec ecx.....................In ecx il n° dei char
:004018FE cmp edx, ecx................Confronta il n° dei char con il contatore
:00401900 jb 004018EC.................Riprendi se non ha finito, altrimenti...
:00401902 cmp bl, D1..................Confronta se dl = a D1
:00401905 jne 0040195A................Salta alla nag se diverso
:00401907 push 00000030
:00401909 push 004045BC
Intuito qualcosa?.....vediamo.....dopo aver nuovamente eseguito il conteggio dei byte
della stringa quest'ultimi, di volta in volta puntati (l'incremento di edx sposta il
puntatore al byte sucessivo) vengono messi in al e poi addizionati a bl secondo il
seguente schemino:
Alla fine il risultato è confrontato con il valore D1 quindi per poter registrare il
programma e necessario soddisfare questa unica condizione ed il gioco è fatto!! Proviamo
a ricercare un valore che dopo le manipolazioni dia come risultato D1. Inseriamo come
valore 1234 e monitoriamo in Sice il risultato.....eccolo bl=D0 vicinissimo!!!!
sostituiamo l'1 con un 2 e con il valore 2234 diventiamo....."Mister Cracker".
Non ho provato altre combinazione ma ritengo che non debba essere difficile trovarne
altre........Buon divertimento
See you next
Note finali
Bene anche questo tute è finito. Un saluto a tutti i ragazzi della UIC ma un
ringraziamento speciale và a Quequero TinMan ed AndreGeddon che si sbattono come dei
matti x fare i corsi x noi newbies totali. Ciauzzzzzzzzz
Disclaimer
vorrei ricordare che il software va comprato e non rubato, dovete registrare il
vostro prodotto dopo il periodo di valutazione. Non mi ritengo responsabile per eventuali
danni causati al vostro computer determinati dall'uso improprio di questo tutorial. Questo
documento è stato scritto per invogliare il consumatore a registrare legalmente i propri
programmi, e non a fargli fare uso dei tantissimi file crack presenti in rete, infatti
tale documento aiuta a comprendere lo sforzo immane che ogni singolo programmatore ha
dovuto portare avanti per fornire ai rispettivi consumatori i migliori prodotti possibili.
Noi reversiamo al solo scopo informativo e di miglioramento del linguaggio Assembly.