6° Corso Newbies
Registry sniffing


15/09/2000

by "Spin0ne"

 
 

UIC's Home Page

Published by Quequero



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.

Tools usati

Softice

URL o FTP del programma

www.uic-spippolatori.com

Notizie sul programma 

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
:0040160B mov edi, ecx
:0040160D push 80000001
:00401612 call esi..........................Chiamata all'Api
:00401614 mov ebx, dword ptr [0040528C]
:0040161A test eax, eax
:0040161C je 0040163D.......................salta se trovata
:0040163D lea ecx, dword ptr [esp+0C]
:00401641 push ecx
:00401642 push 000F003F
:00401647 push 00000000
:00401649 push 004042D4....................Memorizza la locazione della chiave AndreaGeddon\1\2
:0040164E push 80000001
:00401653 call esi.........................Chiamata all'Api
:00401655 test eax, eax
:00401657 je 0040167F......................Salta se trovata
:0040167F lea edx, dword ptr [esp+0C]
:00401683 push edx
:00401684 push 000F003F
:00401689 push 00000000
:0040168B push 00404288....................Ultima chiave memorizzata:AndreaGeddon\1\2
:00401690 push 80000001
:00401695 call esi.........................Chiamata all'Api
:00401697 test eax, eax
: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
:00401736 push 80000001
:0040173B mov [esp+29], 72
:00401740 mov [esp+2B], 6E
:00401745 mov [esp+2D], 74
:0040174A Call dword ptr [00405290].......Chiamata all'Api RegOpenKey
:00401750 mov ebp, dword ptr [0040528C]
:00401756 test eax, eax
: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
:0040178E push edx
:0040178F Call dword ptr [00405294].......Chiamata all'Api RegQueryValue
:00401795 test eax, eax
: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????
:0040184F push 80000001
:00401854 call dword ptr [00405290].......Chiamata all'Api RegOpenKey
:0040185A test eax, eax
:0040185C je 00401883.....................Salta se trovata
 

Creamo le nuove chiavi e potremo così continuare verso la call RegQueryValue

:00401883 mov edx, dword ptr [esp+0C]
:00401887 lea ecx, dword ptr [esp+10]
:0040188B push edi
:0040188C push ecx
:0040188D push esi
:0040188E push 00000000
:00401890 push 00000000...................Tipo di valore
:00401892 push 0040461C...................Push della locazione valore "Qualbuonvento"
:00401897 push edx
:00401898 Call dword ptr [00405294].......Chiamata all'Api RegQueryValue
:0040189E test eax, eax
: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:

1° ciclo in bl = valore 1° byte+0
2° ciclo in bl = valore 2°byte+(0+1°)
3° ciclo in bl = valore 3°byte+(0+1°+2°)
4° ciclo in bl = valore 4°byte+(0+1°+2°+3°)
...................................................................

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.