Tentativo di soluzione al 6° Corso di Quequero
Brute Force


26/12/99

by "AndreaGeddon "

 

 

UIC's Home Page

Published by Quequero



Bravo andrea, bel tute....Buona la teoria di riduzione, ad ogni modo il tuo bruteforcer poteva essere migliorato di molto sfruttando il fatto della periodicità dei ROL...Ma forse non ci hai pensato :).....Inoltre alcune routine sono estremamente meglio, le potevi infatti ottimizzare molto ma molto di più

 
UIC's form
Home page: AndreaGeddon.8m.com
E-mail: AndreaGeddon@hotmail.com
UIC's form

Difficoltà

( )NewBies (X)Intermedio ( )Avanzato ( )Master

 

Ecco un tentativo di soluzione del 6° corso di Quequero. Dico tentativo perchè la soluzione sarebbe impossibile, almeno stando alle regole: NIENTE PATCHING. Qui abbiamo un chiaro esempio di algoritmo irreversibile, semplice ma letale. L'unico attacco possibile è un brute force. Il crackme si trasforma quindi nella ricerca di un modo per trovare il minor numero di combinazioni possibili.


Soluzione al 6° Corso di Queqeuro
Mamma, che vuol dire Brute Force?
Written by AndreaGeddon

 

Introduzione

Io ho classificato il crackme come intermedio nel suo insieme. A livello di codice sarebbe un Newbie, a livello di soluzione sarebbe un Avanzato. Bohh.. Fate voi. A livello di codice in realtà è per ragazzini delle elementari...è questo il bello della crittografia :) NdQue

Lo scopo principale di questo tutorial è quello di scrivere un brute force che provi il minor numero di combinazioni possibili, ed è quello che ho fatto.

 

Tools usati

SoftIce

WinDASM

La bambolina Voodoo (non la scheda video) che ci permetterà di sfogare le nostre frustrazioni!

URL o FTP del programma

http://linox.tecnoprogress.it/quequero/prj/corsosei.html
Lo trovate nella sezione Lezioni del sito di Quequero

Notizie sul programma 

Solo un seriale fisso. Solo.

Essay

Bene. Vi riporto il codice completo della routine di crittazione/confronto del seriale. Sono solo tre paginette, quindi vi conviene stamparlo ed averlo sempre sotto gli occhi quando leggete questo tute e quando debuggate. Trovare il serial in modo semplice, cioè ricalcolandolo a ritroso è impossibile. L'unica via che rimane è quella del brute force. Più giù riporto anche il codice completo del brute force che ho scritto, perfettamente funzionante. Intanto iniziate l'analisi del codice.

Prima di iniziare dichiariamo un pò di termini:

userò la parola SERIAL per indicare il seriale inserito da NOI

userò la parola IRREV per indicare il valore di irreversibilità (00401479)

userò la parola CRITT per indicare il serial giusto crittato

userò la parola DWORD per indicare le varie DWORD del serial

così mi risparmio un pò di scrittura :-)

 

:00401263 Call 004014C5 USER32.GetWindowTextA  --> Questa sarà la PRIMA ROUTINE

:00401268 mov  eax, dword ptr [004020CC]           |---> 1° DWORD del SERIAL

:0040126D imul eax, 93572678                       |

:00401273 mov  ebx, dword ptr [004020D0]           |---> 2° DWORD

:00401279 imul ebx, 26547305                       |

:0040127F mov  ecx, dword ptr [004020D4]           |---> 3° DWORD

:00401285 imul ecx, 37569814                       |

:0040128B mov  edx, dword ptr [004020D8]           |---> 4° DWORD

:00401291 imul edx, 89653715                       |         tutta questa routine

:00401297 add  eax, ebx                             |        serve a determinare

:00401299 add  eax, ecx                             |        il valore di IRREV

:0040129B add  eax, edx                             |        che poi sarà salvato

:0040129D push eax                                  |        nella locazione

:0040129E mov  dword ptr [0040145D], eax            |        00401479

:004012A3 xor  eax, eax                             |

:004012A5 mov  eax, dword ptr [004020CC]            |

:004012AA add  eax, dword ptr [004020D0]            |

:004012B0 mov  dword ptr [00401461], eax            |

:004012B5 mov  eax, dword ptr [004020D4]            |

:004012BA add  eax, dword ptr [004020D8]            |

:004012C0 mov  dword ptr [00401475], eax            |

:004012C5 mov  eax, dword ptr [00401461]            |

:004012CA dec  eax                                  |

:004012CB mov  ebx, dword ptr [00401475]            |

:004012D1 dec  dword ptr [00401475]                 |

:004012D7 imul eax, ebx                             |

:004012DA mov  dword ptr [00401479], eax            |----> salva IRREV

:004012DF call 004012E9                             |

:004012E4 Call 00401495 KERNEL32.ExitProcess        |--> qui si esce dal prog

 

* Referenced by a CALL at Address: 004012DF        |--> Questa è la SECONDA ROUTINE

:004012E9 cmp  eax, FFFFFFFF                       |

:004012EC jg   004012F4                            |

:004012EE nop                                      |

:004012EF nop                                      |

:004012F0 nop

:004012F1 nop

:004012F2 neg  eax

:004012F4 mov  ecx, 00000014

:004012F9 cdq

:004012FA idiv ecx

:004012FC mov  ebx, dword ptr [004020CC]

:00401302 imul ecx, ebx

:00401305 mov  ecx, dword ptr [004020D4]

:0040130B imul ecx, ecx

:0040130E dec  eax

:0040130F rol  dword ptr [004020CC], 05               Questa routine serve

:00401316 ror  dword ptr [004020D4], 04               a modificare le

:0040131D test eax, eax                               DWORD 1° e 3°

:0040131F jne  004012FC                               Del SERIAL

:00401321 cmp  dword ptr [00401479], FFFFFFFF

:00401328 jg   00401334

:0040132A nop

:0040132B nop

:0040132C nop

:0040132D nop

:0040132E neg  dword ptr [00401479]

:00401334 sub  dword ptr [00401479], 0321CCFA

:0040133E cmp  dword ptr [00401479], FFFFFFFF

:00401345 jg   00401351

:00401347 nop

:00401348 nop

:00401349 nop

:0040134A nop

:0040134B neg  dword ptr [00401479]                 |

:00401351 call 00401357                             |

:00401356 ret                                       |

 

* Referenced by a CALL at Address: 00401351     --> Questa è la ROUTINE TERZA

:00401357 mov  eax, dword ptr [004020CC]

:0040135C call 004013FA

:00401361 call 004013D9

:00401366 sub  dword ptr [004020CC], ebx

:0040136C mov  eax, dword ptr [004020CC]        Questa è la routine principale

:00401371 mov  dword ptr [00401465], eax        dove viene eseguita la crittazione

:00401376 mov  eax, dword ptr [004020D0]        vera e propria. Da qui dovranno

:0040137B call 004013FA                          Uscire le DWORD che saranno

:00401380 call 004013D9                          Usate nel confronto finale

:00401385 sub  dword ptr [004020D0], ebx

:0040138B mov  eax, dword ptr [004020D0]

:00401390 mov  dword ptr [00401469], eax

:00401395 mov  eax, dword ptr [004020D4]

:0040139A call 004013FA

:0040139F call 004013D9

:004013A4 sub  dword ptr [004020D4], ebx

:004013AA mov  eax, dword ptr [004020D4]

:004013AF mov  dword ptr [0040146D], eax

:004013B4 mov  eax, dword ptr [004020D8]

:004013B9 call 004013FA

:004013BE call 004013D9

:004013C3 sub  dword ptr [004020D8], ebx

:004013C9 mov  eax, dword ptr [004020D8]

:004013CE mov  dword ptr [00401471], eax

:004013D3 call 00401409

:004013D8 ret

 

* Referenced by a CALL at Addresses: 00401361 :00401380 :0040139F :004013BE

:004013D9 mov  ebx, dword ptr [00401479]

:004013DF sub  ebx, 000000FF                 subroutine 3-1

:004013E5 cmp  ebx, 000000FF                

:004013EB jg   004013DF

:004013ED cdq

:004013EE idiv ebx

:004013F0 imul eax, dword ptr [00401479]

:004013F7 mov  ebx, eax

:004013F9 ret

 

* Referenced by a CALL at Addresses: 0040135C :0040137B :0040139A :004013B9

:004013FA imul eax, eax

:004013FD cmp  eax, FFFFFFFF

:00401400 jg   00401408

:00401402 nop                         subroutine 3-2

:00401403 nop

:00401404 nop

:00401405 nop

:00401406 neg  eax

:00401408 ret

 

* Referenced by a CALL at Address: 004013D3

:00401409 mov  eax, dword ptr [004020CC]    --> Routine QUARTA

:0040140E cmp  eax, 0C185C58                 --> CRITT1

:00401413 jne  0040147D

:00401415 nop

:00401416 nop                                qui vengono effettuati i confronti

:00401417 nop                                e viene deciso se il serial

:00401418 nop                                è giusto o meno

:00401419 mov  eax, dword ptr [004020D0]

:0040141E cmp  eax, 55F2600F                 --> CRITT2

:00401423 jne  0040147D

:00401425 nop

:00401426 nop

:00401427 nop

:00401428 nop

:00401429 mov  eax, dword ptr [004020D4]

:0040142E cmp  eax, 35CE68B2                 --> CRITT3

:00401433 jne  0040147D

:00401435 nop

:00401436 nop

:00401437 nop

:00401438 nop

:00401439 mov  eax, dword ptr [004020D8]

:0040143E cmp  eax, 1F3EECFA                 --> CRITT4

:00401443 jne  0040147D

:00401445 nop

:00401446 nop

:00401447 nop

:00401448 nop

:00401449 push 00000020

:0040144B push 0040236F

:00401450 push 00402376

:00401455 push 00000000

:00401457 Call 004014E3 USER32.MessageBoxA Serial Giusto

:0040145C ret

 

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00401413(C), :00401423(C), :00401433(C), :00401443(C)

:0040147D push 00000010

:0040147F push 00402348

:00401484 push 0040234F

:00401489 push 00000000

:0040148B Call 004014E3 USER32.MessageBoxA Serial Errato

:00401490 Call 00401495 KERNEL32.ExitProcess

 

Okay, abbiamo il codice. Dobbiamo trovare il seriale. Partiamo dai compare finali. Abbiamo i valori critt1 critt2 critt3 e critt4. Dobbiamo partire da questi. Innanzitutto, dal codice è evidente che il serial viene considerato come 4 dword. Soprattutto nella routine terza vediamo che la crittazione e successivamente il confronto avvengono proprio una dword alla volta. La prima cosa che si può fare è tentare di calcolarci all'indietro le 4 dword partendo dai valori critt. Ci troviamo subito in difficoltà perchè compare il riferimento al valore 00401479. Questo valore viene generato nella prima routine a partire proprio dal serial inserito. Siccome non conosciamo il serial inserito, non possiamo conoscere questo valore. E' per questo che lo chiamo irrev, perchè è il valore che assicura l'irreversibilità dell'algoritmo. Come procedere? Studiando bene il codice, mi sono tristemente ritrovato di fronte all'unica soluzione possibile: il brute force.

Per chi non lo sapesse il Brute Force è la tecnica usata per forzare tutte le combinazioni. Cioè, siccome noi non possiamo calcolarci il serial in modo matematico, ricorriamo al modo probabilistico e iniziamo a provare dalla prima all'ultima tutte le varie combinazioni possibili. Sappiamo che il serial deve essere di 16 char. Male! Non possiamo prendere e provare tutte le combinazioni perchè ci vorrebbe troppo tempo. Facciamo due conti:

Partiamo vedendo cosa succede se proviamo tutte le possibili combinazioni. Abbiamo 16 caratteri in tutto. Ogni carattere è un byte. Ogni byte sono 256 combinazioni. Ognuno dei 16 char può in teoria assumere 256 combinazioni. Le combinazioni totali saranno:

256^16 = 3,4028236692093846346337460743177e+38    (il simbolo ^ sta per elevazione a potenza)

Doh!! Più chiaramente questo significa abbreviato 3,402 * 10^38, cioè un numero di 38 cifre! Questo è il numero TOTALE di combinazioni che si devono provare! Cazzo, sono troppe. Ci vorrebbe troppo tempo. Anche teorizzando una velocità di porva di 1 milione di combinazioni al secondo, ci vorrebbero milioni di anni! Dovete tenere da conto il fatto che l'algoritmo di crittazione è stato create bastardamente lento quindi.....:)

Allora il nostro attacco adesso si basa sul modo di ridurre le combinazioni al minor numero possibile.

Beh, una prima riduzione che si potrebbe fare è questa: consideriamo solo i valori effettivi che un char può assumere. Cioè: non credo che Que abbia utilizzato i caratteri ASCII al di fuori dei 96 comunemente usati, quindi adesso consideriamo un char variabile di 96 combinazioni.

96^16 = 52040292466647269602037015248896  combs

Vaff... Ancora troppe. Che dobbiamo fare per ridurre ulteriormente il codice? Andiamo a studiare meglio l'algo. Que suggeriva di provare con le collisioni. Non essendo un esperto di crittografia, allora non sapevo cosa fossero ste collisioni. Adesso mi sono informato, e praticamente era il metodo che intuitivamente avevo provato a fare. Beh, quello che ho fatto io non sono proprio... collisioni, però gli somigliano. Vi riporto la seguente definizione di collisioni:

"Trovare 2 messaggi che diano lo stesso valore di hash è conosciuto come una collisione ed è exploitabile dal birthday attack. Si tratta di un problema di probabilità statistica preso da un documento del sito di aLT255. Se ne volete sapere di più, andate sul suo sito (http://kz.cjb.net/).

Torniamo a noi. Lo spunto ci viene dal fatto che l'algo tratta il serial come 4 dword diverse. Ci viene quindi in mente che forse possiamo sfruttare questo fatto per ridurre il lavoro su una sola dword invece che su tutto il resto. E così vado a fare. Se analizzate la terza routine, vedete che all'inizio il prog prende il valore irrev e la dword che deve calcolare, le critta, e mette in memoria un valore ottenuto sottraendo il valore crittato alla dword corrispondente. Il problema sarebbe di trovare il valore irrev. Alla terza routine vediamo che il serial entra come lo avevamo inserito solo per la dword2 e la dword4. La 1° e la 3° vengono infatti trasformate da dei ROL nella seconda routine. Il valore irrev usato per le 4 dword è sempre lo stesso. Ora, sebbene il ROL non sia un problema, non potremo utilizzare le dword 1 e 3 per i nostri calcoli. Poi vedremo come risolvere anche questo semplice problemino. Prendiamo in analisi la dword2. Dopo il trattamento di crittazione, viene comparata col valore critt2, che sarebbe 55F2600F. Dobbiamo fare quindi in modo che la dword alla fine del trattamento risulti uguale a critt2. Il problema è che siccome abbiamo questa funzione che è a due variabili, non possiamo esplicitare i calcoli per ottenere un calcolo diretto. Dobbiamo quindi considerare come variabili i due valori DWORD2 e IRREV. Il nostro discorso si può definire come segue: DOBBIAMO TROVARE I VALORI DI DWORD2 e IRREV PER I QUALI IL VALORE CHE ESCE DALLA FUNZIONE DI CRITTAZIONE SIA CRITT2. Abbiamo quindi gli elementi che ci servono, facciamo un paio di calcoli:

le due variabili sono dword2 e irrev. Sono entrambi di 4 byte. Il nostro brute non farà altro che provare tutte le combinazioni di dword2 per tutte le combinazioni di irrev. Essendo entrambe di 4 byte, 1 byte = 256 combs   abbiamo

(256^4)*(256^4) = 18446744073709551616 combs

Sono sempre molte, ma meno di quelle di prima!! Però possiamo ulteriormente ridurre: infatti la variabile irrev non la conosciamo e non possiamo dire nulla, ma la variabile dword2 sappiamo che contiene i secondi 4 char del serial, quindi per ogni char le combinazioni rientrano nel discorso dei 96 caratteri standard che facevo anche prima Anche se è solo un'ipotesti perchè io avrei potuto benissimo usare strani simboli NdQue.

Abbiamo adesso:

(256^4)*(96^4) = 364.791.569.817.010.176  combs

E questo è il minor numero possibile di combinazioni che sono riuscito a trovare.Come vedete all'inizio avevamo teorizzato un numero di combinazioni di 38 cifre, adesso ne stiamo considerando uno di 18 cifre! E' un ottima riduzione. Il problema rimane sempre, però: SONO ANCORA TROPPE!! Teorizzando la velocità di calcolo di 1 milione di combs al secondo, impiegheremmo 11567,4 anni per provarle tutte. Peccato che per allora nessuno di noi sarà più vivo per sapere quale è il risultato! Comunque, è il procedimento quello che conta (diceva sempre così il mio prof di mat alle superiori: ho sempre beccato 4!).

Bene, proviamo tutte le combinazioni. Che succede se troviamo il codice: semplice, mi mandate una mail! Se il crackme si ferma e vi scrive due valori, vuol dire che avete trovato la dword2 e irrev. Quindi avete già i secondi 4 char del serial, ma soprattutto avete IRREV! Con questo infatti potrete ricalcolarvi all'inidietro l'algo, infatti ora avrete una sola variabile (la dword da trovare). Oppure potete riusare il brute usando il valore di irrev trovato come valore di partenza. Sarà quindi questione di pochi secondi e troveremo tutte e 4 le dword. MA NON E' FINITA!!! Vi avevo accennato al problema dei ROL delle dword 1° e 3°. Le dword che avete ottenuto con il calcolo tramite irrev trovato, sono le dword modificate dal ROL. Oh nooo!!! Ancora?? Non disperate! Si tratta di un secondo! Infatti le dword vengono rollate (come le canne) di 5 la prima, di 4 la seconda. Ciò viene effettuato per irrev volte. Il calcolo è facile. O rollate tutto per irrev volte (con ror, però), visto che ora irrev lo conoscete, o fate in quest'altro modo: una simpatica caratteristica di ROL è la Periodicità! Infatti ad intervalli regolari la dword rollata riassume il suo valore originario. ROL dword1 , 5 vuol dire che il periodo del ROL è di 32, e cioè avete 32 possibili posizioni per dword1. E lo stesso vale per dword3, solo che lì avete un ROL 4 con periodo 8,e quindi 8 possibili combinazioni di dword3. Beh, ora o provate tutte le combinazioni (32*8 oohhhh), o provate a naso le combinazioni che diano un serial che abbia senso! Comunque, così avreste risolto!!!

Con questo si conclude l'arrembaggio al 6° corso. Adesso vi posto il brute force che ho scritto.

Scusate se il brute fa schifo, ma l'ho scritto di corsa e quindi non l'ho curato particolarmente!

Sotto vi troverete alcuni commenti sul suo miglioramento.

BEGIN OF CODE

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

; NOTE SULL'INSERIMENTO/LETTURA DEI VALORI
; il serial iniziale va inserito al contrario e viene visualizzato al contrario
; l'irrevers va inserito diritto ma viene visualizzato al contrario
; il final viene visualizzato al contrario e viene inserito diritto

.386                                  ; direttive per il compilatore
.MODEL SMALL
.STACK 200h
.DATA

titolo1        db 13,10,'Brute Forcer per il sesto corso di Quequero',13,10,'$'
titolo2        db 13,10,' Written by AndreaGeddon      ',13,10,'$'
inprova1    db 13,10,'Serial in prova:',13,10,'$'
inprova2    db 13,10,'Irrevers in prova:',13,10,'$'       ; le stringhe di testo che userò nel programma
trovato1    db 13,10,'Il seriale trovato:',13,10,'$'
trovato2    db 13,10,'Irrevers trovato:',13,10,'$'
trovato3    db 13,10,'Final torvato:',13,10,'$'

SERIAL        dd 13,10,'',13,10,'$'          ; Variabile in cui immettere la dword inserita
IRREVERS    dd 13,10,'',13,10,'$'       ; Variabile in cui mettere il valore di irreversibilità
FINAL        dd 13,10,'',13,10,'$'            ; Variabile che ci mostrerà la dword giusta nel
                                                             ; caso venga trovata
.CODE
start:
    mov    ax,@data
    mov    ds,ax                            ; faccio puntare ds al segmento DATA

;TITOLO---------------------------------------------------------------
    mov    dx, OFFSET titolo1
    mov    ah, 9
    int    21h
    mov    dx, OFFSET titolo2
    mov    ah,9
    int    21h
    mov    edi, 000000001h    ; serial iniziale
    mov    [SERIAL], edi
    mov    esi, 000000100h          ; irrevers iniziale
    mov    [IRREVERS], esi

;DISPLAY COMBINAZIONI IN PROVA----------------------------------------
calcoli:
    cmp    edi, 000001000h
    je    trovata
    inc    esi
    mov    [IRREVERS], esi
    mov    edi, 000000001h
   
calcoli2:
    mov    dx, OFFSET inprova1
    mov    ah,9
    int    21h
    mov    [SERIAL], edi
    mov    dx, OFFSET SERIAL
    mov    ah,9
    int    21h
    mov    dx, OFFSET inprova2
    mov    ah,9
    int    21h
    mov    dx, OFFSET IRREVERS
    mov    ah,9
    int    21h

;INIZIO CALCOLI------------------------------------------------------
    push    edi
    mov    eax, edi
    call    proc1                   ; come il crackme, qui chiama la proc1
    call    proc2                   ; e qui chiama la proc2
    sub    edi, ebx
    mov    eax, edi
    cmp    eax, 055F2600Fh    ; confronta se ci abbiamo azzeccato
    je    trovata                        ; se NO, ripeti tutto
    pop    edi
    inc    edi
    jmp    calcoli

trovata:                                     ; in caso la trovassimo...
    push    eax
    mov    dx, OFFSET trovato3             ; display di stringhe e del risultato
    mov    ah,9
    int    21h
    pop    eax
    mov    [FINAL], eax
    mov    dx, OFFSET FINAL
    mov    ah,9
    int    21h
    mov    dx, OFFSET trovato2
    mov    ah,9
    int    21h
    mov    dx, OFFSET IRREVERS
    mov    ah,9
    int    21h
    mov    dx, OFFSET trovato1
    mov    ah,9
    int    21h
    pop    edi
    mov    [SERIAL], edi
    mov    dx, OFFSET SERIAL
    mov    ah,9
    int    21h

;----------TERMINA PROGRAMMA-----------------------------------

mov ah,4ch             ; Dos terminate program
mov al,0                 ; return code = 0
int 21h                    ; termina l'esecuzione


;__________________PROCEDURA PRIMA________________________________________
proc1 proc
    imul    eax,eax          
    cmp    eax, 0FFFFFFFFh
    jg    aaaa
    neg    eax
aaaa:
    ret
proc1 endp
;__________________PROCEDURA SECONDA________________________________________
proc2 proc
    mov    ebx, esi
bbbb:
    sub    ebx, 0000000FFh             ; lentissimo... leggete dopo per vere
    cmp    ebx, 0000000FFh            ; come ottimizzare queste righe
    jg    bbbb
    cdq
    idiv    ebx
    imul    eax, esi
    mov    ebx, eax
    ret
proc2 endp
;_________________________________________________________________________
End start

END OF CODE

DUE PAROLE SUL MIGLIORAMENTO DEL BRUTE

Okay, niente di difficile. Ho copiato le routine del crackme e le ho riscritte con qualche modifica. Il codice è funzionante al 100%. Usate il TASM per compilarlo. L'unico problema è la lentezza. Infatti quando scrissi questo brute ero sotto esame, e così gli dedicai poco tempo. Però raggiunsi il mio obiettivo, che era di scrivere un brute funzionante. Poi visto che comunque le combinazioni sono troppe, non ho più ripreso questo progetto. Comunque vediamo dove doveva essere migliorato.

PROCEDURA SECONDA

In questa procedura viene effettuata una divisione con modulo seguendo il metodo delle sottrazioni successive. Cosa fà? Prende il valore di irreversibilità, gli sottrae di volta in volta il valore FF, fino a che ciò non è più bossibile. Per valori piccoli di IRREVERS questo non è un problema, ma quando il valore di irreversibilità diventa un pò più grande, il programma inizia a perdere anche fino a 3 secondi per questa routine! Beh, aggirarla non è un problema. Praticamente questa routine non fa altro che dividere il valore di irreversibilità e prenderne il modulo. Aritmeticamente sarebbe:

IRREVERS / FF = Risultato intero

Risultato intero * FF = (IRREVERS - MODULO)

IRREVERS - (IRREVERS - MODULO) = MODULO

Ecco un semplice metodo per ottenere il modulo. Così siamo sicuri che il programma effettua sempre 3 operazioni, qualunque sia IRREVERS. Però possiamo ulteriormente ottimizzare il tutto. Infatti, il MODULO è sempre uguale per lo stesso valore di irrevers, quindi siccome IRREVERS cambia solo una volta ogni 96^4 (cioè ogni volta che sono state provate tutte le combinazioni di SERIAL), possiamo fare una routine che calcola il MODULO solo quando viene cambiato il valore IRREVERS, e quindi potremmo eseguire questa routine una volta ogni 96^4 invece che ogni volta. Così risparmiamo un sacco di tempo.

DISPLAY COMBINAZIONI IN PROVA

Anche qui si può ottimizzare. Questo brute scrive sullo schermo tutte le combinazioni che prova. Siccome questa è una operazione che rallenta, sarebbe meglio fare un ciclo che scrive sullo schermo solo una combinazione ogni mille. Anche questo farebbe risparmiare molto tempo.

 

E sono finite le ottimizzazioni. Come vedete, il brute lo potete fare a vari passi: basta infatti interrompere il brute, ricordarsi gli ultimi valori di SERIAL e di IRREVERS provati, e poi scriverli nel sorgente come valori iniziali. La rottura è che bisogna ricompilare il codice ogni volta, ma si può benissimo aggiungere una routine che chiede da dove iniziare.

Comunque, anche provando il minor numero possibile di combinazioni teorizzato che era (256^4) * (52^4), impiegheremmo circa 995 anni e mezzo! E questo supponendo la velocità di calcolo di 1 milione di combinazioni al secondo (velocità assurda...). Comunque lo scopo di questa soluzione era quello di riuscira a capire come ridurre l'algoritmo. Non escludo che avendo un sistema di calcolo potente con molti porocessori in parallelo (per intenderci i sistemi che usa la NSA), questo crackme sarebbe stato risolto in un pò di giorni.

Se tutto questo vi ha lasciato insoddisfatti, prendete pure la bambolina voodoo di Que e pugnalatela senza pietà! E' colpa sua!! Dehihihi!

Ciauz

AndreaGeddon

 

Note Finali

Saluto tutti gli amici della mailing list (tutti tutti) con cui ho condiviso questo cracking.

Disclaimer

Queste informazioni sono solo a scopo puramente didattico.

 
UIC's page of reverse engineering, scegli dove andare:

Home   Anonimato   Assembly    CrackMe   ContactMe   Forum       
    Iscrizione   Lezioni    Links   NewBies   News   Playstation        
  Tools   Tutorial   Search   UIC Faq

UIC