Copy Link
Add to Bookmark
Report

Come crackare Conseal PC Firewall in modo insolito

DrWatson's profile picture
Published in 
guide hacker
 · 28 Apr 2018

Tools usati:

- SoftIce v4.00
- BoundsChecker v6.01
- Hacker's View v6.15
- Procdump v1.5
- OpGen v1.0b
- Tasm v4.1

Parte 1: Premessa
Salve a tutti....

Che vuol dire "in modo insolito" ? Se ve lo siete chiesto dopo aver letto il titolo, eccovi la spiegazione...e' diverso tempo che non cracko piu', come i miei amici sanno, ma preferisco dedicarmi al (a mio modestissimo parere) molto piu' ricco, interessante e suggestivo scenario del Reverse Engineering... ecco che pero', tra uno scherzo e l'altro, una nukata ad un amico e una tranquilla chattata su Irc, mi capita di vedere che la mia preziosissima firewall (la Conseal, che penso sia una delle migliori, anche se non me ne intendo granche') va giu' d'un botto... finita la licenza ?? opporcodinci, che vor di' finita la licenza ?!?

Tipico background per un comune crackettino veloce (non uso dedicarmi a lunghe sessioni di cracking da un bel po'...), ciononostante mi sono presto accorto che c'erano i presupposti per qualcosa di piu' simpatico del solito jz/jnz o del seriale...

Lasciatemi premettere solo una cosa....sara' un tutorial il piu' breve possibile (non per il fatto che sono le 4 e mezza di notte e ho abbastanza sonno, ma perche' effettivamente non voglio rimpinzarvi con tonnellate di testo...let's try=)


Parte 2 : U Crackke.
la storia e' questa.

Il programma, una volta spirato, e una volta fatto partire, non da' adito a sospetti, quando, dopo un 2/3 secondi, voila' una messagebox che ci avverte che abbiamo sbagliato palazzo, come si usa dire a Napoli e provincia, insomma bisogna registra' il proggillo. Ci terrei a precisare che la versione che uso e' la 1.37... Dicevo, insomma la msgbox. Niente bpx messageboxa, vogliamo divertirci stavolta, niente delle solite robe... apriamo boundschecker e lanciamo frw.exe, prestando attenzione alle api che vengono utilizzate... Se state bene attenti e collapsate tutti i thread creati all'avvio, noterete 6 thread iniziali e, proprio un attimo prima che il nag compaia, la creazione di un settimo thread. Interessante, diamo un occhio a sto settimo thread... Noterete una sovrabbondanza di giochini e querate varie a divese chiavi di registro... niente di sconvolgente, ovvio. Ma diamo un'occhio ai valori controllati...uhm, noterete una certa frequenza di LicenseInfo, LicenseID etc... apriamo un attimino regedit e cerchiamo proprio LicenseID... toh, un bel trio di chiavi interessanti... LicenseCode con evidentemente la versione crittata della data di installazione+altre nefandezze varie, LicenseID con una stringhina di default per la nostra licensa universale, LicenseInfo con immondizia non meglio identificata... uhm, cosa facciamo ? un paio di bpm, ci cerchiamo la routine di decrittazione e ci scriviamo il nostro crackettino elite ?? NO :)

Abbiamo detto in modo insolito... ecco quindi che chiudiamo regedit (non so voi, ma io la routine di decrypt me la lascerei per qualche altra volta... potrebbe essere un algo interessante)... comunque, dicevamo. Torniamo al nostro settimo thread, ripoppando boundschecker. Scorrendo un po' tra le api chiamate, raggiungeremo una zona in cui viene allocato+liberato un heap... quando OH! cos'e' quel GetLocalTime :) gia' gia'... facile rendersene conto, GetLocalTime serve a pigliare data e ora attuale... percio' facile che il programma decripti la chiave LicenseCode, rilevi l'install time e quindi faccia i suoi dovuti calcoli. Cosa si fa ? Mah, direi che potremmo patchare i check per un qualcosa di sbrigativo... ma si parlava di divertirsi no?? Quindi... chiudiamo boundschecker dopo una rapida occhiata al resto delle api chiamate, nulla di realmente interessante... apriamo il file con Hiew... wow che sorpresina... c'e' una sezione .WWP32... il file e' packato con wwpack 32... procdump lo unpacka... ma noi siamo duri di capoccia... ce lo vogliamo packato il file, che fa piu' ganzo e occupa meno ;)... ecco che una sottile perversa ideuzza si comincio' a profilare nella mia mente bacata... vediamo. GetLocalTime. Rileva giorno, mese e anno... Io il Conseal l'ho installato il 17 Luglio 1999... Se gli faccio credere che e' sempre il 18 Luglio 1999 vivremmo tutti in pace... sarebbe interessante... ma come fare ? uhm, uhm... la soluzione e' semplice... un IAT hook che intercetti tutte le chiamate a GetLocalTime e che faki il risultato... facile da realizzare... solo che il file e' packato... quindi i problemi sono fondamentalmente due... uno, come installare l'hook e, due, DOVE iniettare la routine di intercettazione... beh... installare l'hook e' semplice quanto bere un bicchier d'acqua... ciononostante la situazione era abbastanza insolita, percio' ho deciso di continuare su questo sentiero :)

L'IAT hooking e' fondamentalmente molto, molto semplice nel concetto. Presumo che il lettore abbia una conoscenza media del PE header, e che sappia cosa e' una Import Table... In caso contrario, mi sento di consigliare qualche buon doc, i migliori sono quelli di Pietrek e di Luevelsmeyer (di cui ho incluso il famoso pe.txt in conseal.zip)... Ora, sappiamo che nella Import Table c'e' un array chiamato FirstThunk, che viene patchato a runtime con gli indirizzi delle funzioni che il programma in questione importa... Il concetto di IAT hooking si basa su questo: si ritrova lo spot della funzione che vogliamo hookare, e gli si patcha dentro il VA della nostra routine di intecettazione. Fatto cio', quando il programma chiamera' la funzione (e quindi passera' per lo smistamento relativo nella Import Address Table (aka FirstThunk Array), invece di lanciarsi in spericolate peripezie nel kernel si lancera' tra le fauci della nostra simpatica routine iniettata... alche' noi con tutta calma ci esaminiamo i parametri passati, li forwardiamo al kernel, oppure ce li teniamo, o resettiamo il sistema, o facciamo comparire una messagebox che dice "Moonshadow e' ghey =)" o quello che ci passa per la testa ;) (scherzo mun:P)... insomma avete capito. Chiaramente, possiamo parimenti fakare il risultato di una call, nel nostro caso a GetLocalTime, restituendo al nostro simpatico amico frw.exe la perpetua data del 18 Luglio 1999 :)

C'e' tuttavia un PERO'. Il problema ora e'... il file e' compresso... come e dove iniettare una routine di intercettazione? Beh, la prima idea che m'e' venuta e' stata quella di scrivere un mini hooker .exe, poi da un memory patcher (inevitabile come vedremo) mapparlo in memoria e accedervi dal processo unpackato... possibilissimo considerato il fatto che i MMF vengono mappati nella parte shared del linear address space, ergo non avevamo bisogno di nessuna routine addizionale di context switching eccetera... ma poi ho pensato, ne vale la pena ?? Non ci dilunghiamo troppo =)... volevo patchare fisicamente la routine all'interno di frw.exe, e c'era un solo posto al sicuro dalla furia della tempesta che si scatena quando il loader di un file cryptato procede con la sua fredda decompressione/distruzione dell'immagine iniziale del file... ovvero le cosiddette caves... termine decisamente familiare ai programmatori di virii... le caves sono quegli spazi 'vuoti' (in realta' riempiti con 0-bytes) all'interno di un file PE, insomma degli spazi 'morti' che possono venire sfruttati per qualsiasi scopo di iniezione di codice... nel nostro caso non di codice virale, ma della simpatica hooking routine :)

Quale cave useremo ?? Mah, direi che quella tra la Object Table e la prima sezione puo' andare benissimo... aprite il file con Hiew, giusto per farvi un'idea... dopo lo stub (this proggie can't be run in dos mode) e la signature PE,0,0 abbiamo i primi dati del file header, poi l'optional header etc... scorrendo verso il basso troviamo la object table (.text coi relativi dati, .rdata idem etc...) ... poi abbiamo una serie di zero bytes (la nostra cave) a partire dall'offset 268h e infine si arriva alla sezione .text all'offset 1000h... tutto quello spazio non viene assolutamente toccato/rilocato/modificato dal loader del wwpack32... ora vi siete fatti un'idea di quello che faremo... a voi la scelta se continuare a leggere o cancellare questo html ;)

Allora, allora. Di cosa abbiamo bisogno ora ?? Beh... Considerato che dobbiamo installare un IAT hook, abbiamo bisogno dell'immagine decrittata del file... in realta' abbiamo solo 'nozionisticamente' bisogno di un paio di virtual addresses, che potremo inserire come patchspots da un memory patcher, anche se in realta' il file che useremo sara' sempre quello compresso... apriamo quindi procdump, e facciamo partire conseal... appena il processo e' stato lanciato, premiamo il tasto destro nella tasklist di procdump e selezioniamo Refresh list... eccoti frw.exe comparire miracolosamente tra i processi. Velocemente, tasto destro sul taskname e quindi "Dump (Full)"... salvate in un file ad cazzum, e chiudete frw e procdump. Quel file contiene l'immagine del file cosi' com'e' in memoria... ora il discorso e' risalire alla import table, e quindi scavarci dentro fino a trovare la dword del FirstThunk array contenente l'indirizzo di GetLocalTime... La qual cosa comporta DUE PALLE enormi, se volete la mia modesta opinione... Allora che si fa ?? Beh... qualche tempo fa mi ruppi decisamente di questa situazione (la dovevo affrontare in continuazione quando volevo patchare nei programmi chiamate a funzioni API importate dagli stessi, e mi dovevo cercare a mano l'indirizzo nella IAT...), e decisi di scrivere un piccolo Tool, che chiamai OpGen, che ha un'altra utile (almeno per me, e credo per chiunque faccia reversing) funzione, ovvero quella di generare gli opcodes da patchare per i far jumps, posti solo va di partenza e arrivo (hiew succhia quando si tratta dei far jumps)... ma a noi questa funzione non interessa, ciononostante il piccolo IT scanner che ho implementato in OpGen ci da' in un attimo il patchspot per ogni funzione... visto che l'ho incluso in questo zip, apritelo e scegliete Lookup Imports for patching... scegliete il nostro file dumpato con procdump, e quello che avrete e' questo (tra le altre cose):

GetLocalTime == call dword ptr [46459C]

Oh, ma che cosa interessante ;) quello ([46459c]) e' il posto dove piazzeremo l'indirizzo della nostra hooking routine... Eccoci quindi a dover affrontare la necessita' di un memory patcher. Dovendo patchare l'hook nell'immagine decryptata del file, apriamo il fido Ultraedit con supporto per Tasm (tm;) e cominciamo a buttare giu' un po' di codice...


 
.386p
.model flat, stdcall

extrn ReadProcessMemory :PROC
extrn WriteProcessMemory :PROC

UNICODE = 0
include winsux.inc




.DATA

exe_name DB "frw.exe",0

processInfo PROCESS_INFORMATION
ini_info STARTUPINFO

iat_hooking_routine DD 04002A0h ; VA DELLA HOOKING ROUTINE (NELLA CAVE TRA LA OBJECT TABLE E LA ; SEZIONE .TEXT)
funct_va DD 0
dummybuffer DB 0




.CODE

start:

call CreateProcessA, OFFSET exe_name, 0, 0, 0, 0, NORMAL_PRIORITY_CLASS,0 ,0 ,OFFSET ini_info,OFFSET processInfo
test eax, eax
jz @@end

; aspettiamo che frw.exe venga caricato e unpackato con un piccolo loop (anche se non riusciamo
; a hookare dal primo GetLocalTime non c'e' problema, quelli che servono effettivamente sono
; quelli del settimo thread, ricordate)

mov ecx, 100000000

.WHILE ecx != 0
dec ecx
.ENDW

; rileviamo l'indirizzo effettivo di GetLocalTime nel kernel direttamente dalla IAT del processo unpackato
call ReadProcessMemory, [processInfo].pi_hProcess, 046459Ch, OFFSET funct_va, 4, OFFSET dummybuffer

; ora patchiamo questo indirizzo in una dword (a 4002dd) che chiameremo dalla hooking routine quando vogliamo chiamare GetLocalTime
call WriteProcessMemory, [processInfo].pi_hProcess, 04002DDh, OFFSET funct_va, 4, OFFSET dummybuffer

; e infine installiamo effettivamente l'hook nel FirstThunk array, modificando l'indirizzo che il programma chiamera' nella Import Address Table
; con l'indirizzo della nostra funzione (nella dword iat_hooking_routine)
call WriteProcessMemory, [processInfo].pi_hProcess, 046459Ch, OFFSET iat_hooking_routine, 4, OFFSET dummybuffer

@@end:
call ExitProcess, 0 ; il nostro lavoro e' fatto...ora e' tutto nelle mani (bytes:) della hooking routine



end start

molto bene.

A questo punto, compilando il programma avremo il nostro mem patcher che crea il processo, aspetta un po', ne rileva l'indirizzo di GetLocalTime dalla IAT, lo patcha nella hooking routine, e infine installa l'IAT hook nell'immagine decryptata del programma.

adesso rimane il problema della hooking routine. Cosa bisogna metterci dentro ?

entrate in Softice e mettete un bpx getlocaltime... fate partire conseal pc firewall, e premete f12 al primo pop. Scrivete DD e quindi D ESP-4. Questo vi mostra l'indirizzo che e' stato pushato nella stack prima della chiamata a GetLocalTime (potete trovarlo anche tracciando nel kernel fino a quel "mov ecx, esp-c" (la quinta codeline della funzione) dove troverete, in ecx, lo stesso indirizzo. Comunque, dicevo, fate "d indirizzo" e vi ritroverete davanti il dump della struttura SYSTEMTIME che viene riempita con i dati inerenti la data e ora attuali... ma diamo un'occhiata alla sua definizione:

 
typedef struct _SYSTEMTIME { // st
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME;

uhm, uhm... ricordate che noi dobbiamo far credere al programma che e' sempre il 18 luglio 1999, ergo dobbiamo modificare la prima, seconda e quarta Word della struttura... rendendole rispettivamente 7CFh (1999 dec), 7, e 12h (18 dec)... se volete dare un occhio da vicino alla struttura date un DW e poi analizzatela... capirete quanto e' semplice il concetto.

Allora, ricapitoliamo. Quello che succedera' e' questo: il programma chiama la IAT credendo di chiamare GetLocalTime, quando il controllo verra' passato alla nostra hook routine (a 04002A0h)... a quel punto la nostra situazione sara' questa: salveremo EAX pushandolo e quindi [ESP+4] conterra' il return address per il codice del programma, e lo salveremo in una dword fisica da chiamare poi per il ritorno (la stessa cosa che abbiamo fatto dal mempatcher per l'indirizzo di GetLocalTime)... poi ripristineremo EAX e incrementeremo di 4 bytes lo stack... a quel punto [ESP] puntera' alla struttura SYSTEMTIME... quindi chiameremo effettivamente GetLocalTime... al ritorno avremo, in [ESP-4], l'indirizzo della struttura SYSTEMTIME e passiamo alla sua modifica: salviamo in una terza dword fisica il valore di EAX (non possiamo pusharlo perche' spesso, se analizzate il flow del codice con softice, il VA della struttura e' pericolosamente adiacente allo stack, quindi una push piazzata male potrebbe rovinare la struttura e crashare il programma) e vi inseriamo il VA della struttura... alche' ne modifichiamo le word relative ad anno, mese e giorno, poi ripristiniamo EAX e jumpiamo al return address salvato all'inizio della routine... ora scriviamo il codice... aprite hiew e posizionatevi sull'offset 2A0h (che diventera' 4002A0h una volta mappato e aggiuntavi l'imagebase), e iniettate la nostra hooking routine:

 
push eax ; salviamo EAX
mov eax, [esp+4] ; return VA in EAX
mov [4002E3h], eax ; lo salviamo in una variabile X
pop eax ; ripristiniamo EAX
add esp, 4 ; [ESP] punta alla struttura SYSTEMTIME
call dword [4002DDh] ; == call GetLocalTime (dword patchata dal Mem Patcher)
mov [4002E9h], eax ; salviamo EAX in una variabile Y
mov eax, [esp-4] ; EAX contiene un puntatore alla struttura
mov word [eax], 07CFh ; WORD wYear
mov word [eax+2], 07h ; WORD wMonth
mov word [eax+6], 012h ; WORD wDay
mov eax, [4002E9h] ; ripristiniamo EAX da variabile Y
jmp dword [4002E3h] ; ritorniamo a .text tramite variabile X


andata :)

per quelli tra voi poco familiari con Hiew e il suo modo barbaro di interpredare byte, word e dword ptr, sappiate che essi sono rispettivamente B,[blabla] , W,[blabla] e D,[blabla].

una volta fatto cio', potete far partire il nostro mempatcher, e tutto funzionera' alla perfezione... il vostro Conseal PC firewall non espirera' piu', e abbiamo fatto qualcosa di davvero insolito... io mi sono divertito, e voi ?? ;)

Parte 3: Shout Outz

Un saluto per tutti i miei amici di ring0 e di #cracking4newbies e' d'obbligo...

E infatti l'avevo messo ma 1034 persone si erano lamentate per non essere state salutate e ho deciso molto democraticamente di lasciare un'alone di triste malinconia e lanciare un saluto a tutti quelli che sanno di dover essere salutati :)

Per qualsiasi domanda, commento, aggiunta, polemica etc etc la mia email e' neural_noise@hotmail.com

se invece mi cercate su irc, provate #cracking4newbies (EFNet) o #crack-it (IRCNet)... il mio nickname e' nuural_en.

altre vomitevoli nefandezze scritte da me le trovate su http://neudump.cjb.net/

mentre il miglior sito di reverse engineering in italia lo trovate a http://ringzer0.cjb.net/

'till next time,

NeuRaL_NoiSE 1999 for RingZ3r0.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT