CrackMe v1.0 Benek'99 by Tymon

.: Intro :.

Witajcie w moim kolejnym tutku, opisujcym crackme. Tym razem znalazem co zwizanego troch z kryptografia (a nawet do duo). Co jak co, ale tutorw o crypto w pl jest nadal bardzo mao. Najwicej mona przeczyta o RSA, ale pozostae algorytmy s troch pomijane. Oki, moe teraz troch o samym crackme. Napisane zostao ono przez Benka z AAoCG i opiera si gwnie na dwch algorytmach kryptograficznych: MD5 i IDEA. Samo cm napisane jest najprawdopodobniej w c++ i jest czym spakowane (niestety nie udao mi si ustali, co to za packer/protector). Oki, chyba koniec tego biadolenia, czas zaj si samym crackmesem.

.: IDEA :.

Waciwie to bdzie lepiej jak opisz troch IDEA przed samym amaniem. Jak si zrozumie sam algorytm, to crackme wydaje si cakiem atwe. Oki, IDEA operuje na blokach 64 bitowych (8 bajtowych). Jest ona skadnikiem pakietu PGP i uywa do szyfrowania kluczy 128 bitowych (16 bajtowych, 8 bitw = 1 bajt, pamitacie, nie?). Algorytm ten wykorzystuje 3 rne operacje: xor, dodawanie modulo 2^16 oraz mnoenie modulo 2^16+1. Podczas szyfrowania IDEA wykonuje 8 rund, a w kadej rundzie operuje na 4 blokach 16 bitowych (2 bajty - word). W kadej rundzie wykorzystywane jest take 6 podkuluczy (kady wielkoci 16 bit). Jak atwo si domyle potrzebne jest nam 8*6=48 podkluczy. Nie jest to jednak prawda, poniewa po wykonaniu rund, na kocu IDEA potrzebuje jeszcze 4 podkluczy do przeksztace kocowych, co daje nam rezultat 48+4=52. W wyniku tego otrzymujemy 4*16bit=64bit, czyli nasz szyfrogram. Oki, pewnie zastanawiasz si, jak to moliwe, e algorytm uywa 52 podkluczy (co daje wielko 52*16bit = 832 bity), jak klucz podany do szyfrowania wynosi tylko 128 bitw. No i tutaj dochodzimy do przeksztace klucza. Przed wykonaniem szyfrowania, IDEA przeksztaca odpowiednio nasze 128 bitw klucza na 52 podklucze. Na pocztku dzieli klucz na 8 podkluczy, a potem z tych 8 uzyskanych, generuje nastpne. Oki, teraz troch o deszyfrowaniu. Co dziwne, za t operacj, odpowiedzialny jest dokadnie ten sam algorytm, z drobn rnic. Po obliczeniu 52 podkluczy, wywoana jest jeszcze jedna procedurka, ktra przystosowuje je odpowiednio do deszyfrowania. Procka ta przeksztaca kady podklucz wedug ustalonego algorytmu. Sam algorytm jest troch skomplikowany, wic nie bd go tutaj opisywa. Nastpnie zostaje wykonana ta sama procedura, ktra jest odpowiedzialna za szyfrowanie. Nom mam nadziej, e co z tego zrozumiae, jeeli nie to przeled algorytmy pod SoftIce (to zawsze pomaga).

.: MD5 :.

Skoro napisaem cosik o IDEA, to moe wspomn te o popularnym MD5. Jest to nic innego jak algorytm hashujcy, czyli przeksztaca kady blok danych (dowolnej dugoci) w 128 bitow warto (unikaln, dla kadych danych). Powoli odchodzi si od tego algorytmu. Aha, oczywicie algorytm MD5 jest funkcj jednokierunkow, czyli nie da si jej odwrci.

.: CrackMe :.

Oki, czas wzi si za crackme. Wpisujemy jakie tam dane i zakadamy bpx'a na GetDlgItemTextA. Oki mamy takie cosik:

0167:004013B3  FFD7           CALL      EDI        ; get name
0167:004013B5  8BF0           MOV       ESI,EAX
0167:004013B7  83FE02         CMP       ESI,02     ; if < 2
0167:004013BA  0F8CF7020000   JL        004016B7   ; bye bye
0167:004013C0  83FE27         CMP       ESI,27     ; if > 39
0167:004013C3  0F8FEE020000   JG        004016B7   ; bye bye
0167:004013C9  8D4C240C       LEA       ECX,[ESP+0C]
0167:004013CD  6A28           PUSH      28
0167:004013CF  51             PUSH      ECX
0167:004013D0  68F2030000     PUSH      000003F2
0167:004013D5  53             PUSH      EBX
0167:004013D6  FFD7           CALL      EDI        ; get serial
0167:004013D8  83F827         CMP       EAX,27     ; length == 39
0167:004013DB  742B           JZ        00401408   ; good

Oki, powyszy kawaek sprawdz, czy dugo name jest wiksza od 1, ale mniejsza od 39 (wiksza od 39 nie moe by, poniewa edit ma ustawione ograniczenie). Nastpnie jest sprawdzane czy serial ma 39 znakw, jeeli tak, to przechodzimy dalej:

0167:00401408  8D842484000000 LEA       EAX,[ESP+00000084] ; name
0167:0040140F  55             PUSH      EBP
0167:00401410  8B2D0C604000   MOV       EBP,[0040600C]
0167:00401416  8D8C24E4000000 LEA       ECX,[ESP+000000E4]
0167:0040141D  50             PUSH      EAX
0167:0040141E  51             PUSH      ECX       ; buffer
0167:0040141F  FFD5           CALL      EBP       ; lstrcpy
0167:00401421  83FE10         CMP       ESI,10    ; if > 16
0167:00401424  7D2F           JGE       00401455  ; omi nastpn prock

Tutaj nasz name jest kopiowany do drugiego buffera, oraz sprawdzane jest czy jego dugo jest wiksza lub rwna 16, jeeli nie to przejd do poniszego kawaka:

0167:00401426  8B3D08604000   MOV       EDI,[00406008]
0167:0040142C  8B1D04604000   MOV       EBX,[00406004]
0167:00401432  8D942488000000 LEA       EDX,[ESP+00000088]
0167:00401439  8D8424E4000000 LEA       EAX,[ESP+000000E4]
0167:00401440  52             PUSH      EDX                ; orginal name
0167:00401441  50             PUSH      EAX                ; buffer ze
                                                           ; skopiowanym
                                                           ; name
0167:00401442  FFD7           CALL      EDI                ; lstrcat
0167:00401444  8D8C24E4000000 LEA       ECX,[ESP+000000E4]
0167:0040144B  51             PUSH      ECX                ; name po
                                                           ; poczeniu
0167:0040144C  FFD3           CALL      EBX                ; lstrlen
0167:0040144E  8BF0           MOV       ESI,EAX
0167:00401450  83FE1          CMP       ESI,10             ; if < 16
0167:00401453  7CDD           JL        00401432           ; to powtarzaj

Hehehe, powysza procka w asm zajmuje kilka linijek. A o co tu chodzi? Algorytm czy nasze name, a przekroczy ono dugo 16. Dla przykadu:

mj name:          Tymon
po tym algorytmie: TymonTymonTymonTymon

Chyba ju rozumiesz, nasze name jest powtarzane, a przekroczy dugo 16. oki:

0167:00401455  8D9424E4000000 LEA       EDX,[ESP+000000E4]
0167:0040145C  8D842488000000 LEA       EAX,[ESP+00000088]
0167:00401463  52             PUSH      EDX               ; przeksztacone
                                                          ; name
0167:00401464  50             PUSH      EAX               ; name
0167:00401465  FFD5           CALL      EBP               ; lstrcpy

Chyba no comments (odtd, kiedy bd pisa name, to bd mia na myli
to name przeksztacone), dalej:

0167:00401467  8D8C2434010000 LEA       ECX,[ESP+00000134]
0167:0040146E  51             PUSH      ECX                ; buffer
0167:0040146F  E87C060000     CALL      00401AF0           ; inicjacja
                                                           ; staych MD5
0167:00401474  8D94248C000000 LEA       EDX,[ESP+0000008C]
0167:0040147B  56             PUSH      ESI                ; length(name)
0167:0040147C  8D84243C010000 LEA       EAX,[ESP+0000013C]
0167:00401483  52             PUSH      EDX                ; name
0167:00401484  50             PUSH      EAX                ; stale MD5
0167:00401485  E896060000     CALL      00401B20
0167:0040148A  8D8C2444010000 LEA       ECX,[ESP+00000144]
0167:00401491  8D942488000000 LEA       EDX,[ESP+00000088]
0167:00401498  51             PUSH      ECX                ; stale MD5
0167:00401499  52             PUSH      EDX                ; buffer
0167:0040149A  E831070000     CALL      00401BD0           ; MD5 hash

No tutaj chyba te bez zbdnych komentarzy. Po prostu z naszego name wyliczany jest hash MD5. Co dalej?

0167:004014A2  8D442478       LEA       EAX,[ESP+78]       ; MD5(name)
0167:004014A6  8D8C24C4000000 LEA       ECX,[ESP+000000C4] ; buffer
0167:004014AD  BE08000000     MOV       ESI,00000008
0167:004014B2  33D2           XOR       EDX,EDX
0167:004014B4  83C104         ADD       ECX,04
0167:004014B7  8A30           MOV       DH,[EAX]
0167:004014B9  40             INC       EAX
0167:004014BA  8951FC         MOV       [ECX-04],EDX       ; zapisz
0167:004014BD  8B69FC         MOV       EBP,[ECX-04]
0167:004014C0  33D2           XOR       EDX,EDX
0167:004014C2  8A10           MOV       DL,[EAX]
0167:004014C4  03EA           ADD       EBP,EDX
0167:004014C6  40             INC       EAX
0167:004014C7  8969FC         MOV       [ECX-04],EBP       ; zapisz
0167:004014CA  4E             DEC       ESI
0167:004014CB  75E5           JNZ       004014B2           ; next ;)

Co robi ta procka? Jest ona odpowiedzialna za przetworzenie naszego hasha MD5 na format uywany dalej w crackme. Wyglda to mniej, wicej tak:

Normalny hash:

0063F7F4 69 5C 29 51 D2 2D 6C BC-C4 86 AD A9 3D 20 12 5B  i\)Q.-l.....= .[

Po powyszej procedurze:

0063F840 5C 69 00 00 51 29 00 00-2D D2 00 00 BC 6C 00 00  \i..Q)..-....l..
0063F850 86 C4 00 00 A9 AD 00 00-20 3D 00 00 5B 12 00 00  ........ =..[...

Tak na prawd, jedyn wan rzecz jak robi ta procka, jest to, e zamienia midzy sob dwie kolejne liczby w hashu (69 5C , 5C 69). Oki, next:

0167:004014CF  6A10           PUSH      10
0167:004014D1  8D442414       LEA       EAX,[ESP+14]
0167:004014D5  53             PUSH      EBX                ; zero
0167:004014D6  50             PUSH      EAX                ; serial
0167:004014D7  885C2420       MOV       [ESP+20],BL
0167:004014DB  885C2425       MOV       [ESP+25],BL
0167:004014DF  885C242A       MOV       [ESP+2A],BL
0167:004014E3  885C242F       MOV       [ESP+2F],BL
0167:004014E7  885C2434       MOV       [ESP+34],BL
0167:004014EB  885C2439       MOV       [ESP+39],BL
0167:004014EF  885C243E       MOV       [ESP+3E],BL

Hehehe, miejsce na watemarka w naszym keygenie. Powyszy kod, wstawia w miejsce co pitego znaku zero. Oznacza to, e co pity znak nie bierze udziau w sprawdzeniu. Ja w tych miejscach wstawiem kropk. Oki:

0167:004014F3  E890130000     CALL      00402888           ; HexStr2Dword
0167:004014F8  6A10           PUSH      10
0167:004014FA  8D4C2425       LEA       ECX,[ESP+25]
0167:004014FE  53             PUSH      EBX
0167:004014FF  51             PUSH      ECX
0167:00401500  89842480000000 MOV       [ESP+00000080],EAX ; zapisz

Takich proceadur jest duo wicej w crackme. Wszystkie one odpowiedzialne s za zamian kadych 4 znakw seriala na dword, np. '2538' -> 2538h (oczywicie tutaj zostaje pominity co pity znak). Oki, a co po nich?

0167:00401585  8D9424A4010000 LEA       EDX,[ESP+000001A4]
0167:0040158C  8D8424DC000000 LEA       EAX,[ESP+000000DC]
0167:00401593  52             PUSH      EDX                ; buffer
0167:00401594  50             PUSH      EAX                ; hash MD5
0167:00401595  E866FAFFFF     CALL      00401000           ; IdeaExpandKey

Warto zajrze do rodka tego call'a:

0167:0040105A  8D7024         LEA       ESI,[EAX+24]
0167:0040105D  8B3C0F         MOV       EDI,[ECX+EDI]   ; ecx = offset MD5
0167:00401060  8B340E         MOV       ESI,[ECX+ESI]
0167:00401063  83E77F         AND       EDI,7F
0167:00401066  83C004         ADD       EAX,04
0167:00401069  C1EE07         SHR       ESI,07
0167:0040106C  C1E709         SHL       EDI,09
0167:0040106F  81E6FFFF0000   AND       ESI,0000FFFF
0167:00401075  83C204         ADD       EDX,04
0167:00401078  0BFE           OR        EDI,ESI
0167:0040107A  43             INC       EBX
0167:0040107B  897AFC         MOV       [EDX-04],EDI       ; zapisz
0167:0040107E  3D94000000     CMP       EAX,00000094
0167:00401083  7CA7           JL        0040102C

Tutaj wanie piknie wida na czym polegaj przeksztacenia klucza w IDEA. Teraz ju si pewnie domylasz, e MD5(name) jest uywane jako klucz w algorytmie IDEA. W miejscu bufferu podanego w argumentach do call'a powstan wanie 52 podklucze. Wszystkie one zapisane s w formacie uywanym oglnie w crackme. Oki, czas przej dalej:

0167:0040159A  8D8C247C020000 LEA      ECX,[ESP+0000027C]
0167:004015A1  8D9424AC010000 LEA      EDX,[ESP+000001AC]
0167:004015A8  51             PUSH     ECX                ; buffer
0167:004015A9  52             PUSH     EDX                ; podklucze IDEA
0167:004015AA  E8E1FAFFFF     CALL     00401090           ; IdeaInvertKey

Hmm... powysza procka przerabia jeszcze raz podklucze? Pamitasz co mwiem o szyfrowaniu/deszyfrowaniu w IDEA. Tak, tak rni si one prock, ktra jeszcze raz przerabia podklucze. Hehe.. to chyba wanie to. Co z tego wynika. No ale oczywicie, w crackme bdzie uyte deszyfrowanie IDEA. Warto zajrze do tego call'a, by lepiej zrozumie problem:

0167:00401096  8B8424D4000000 MOV       EAX,[ESP+000000D4]
0167:0040109D  53             PUSH      EBX
0167:0040109E  56             PUSH      ESI
0167:0040109F  57             PUSH      EDI
0167:004010A0  8B08           MOV       ECX,[EAX]
0167:004010A2  8D5C240C       LEA       EBX,[ESP+0C]
0167:004010A6  51             PUSH      ECX
0167:004010A7  8D7004         LEA       ESI,[EAX+04]
0167:004010AA  E801010000     CALL      004011B0           ; mnoenie
                                                           ; modulo 2^16+1
0167:004010AF  8B4E04         MOV       ECX,[ESI+04]

itd.

Oki, co dalej:

0167:004015AF  8D842484020000 LEA       EAX,[ESP+00000284]
0167:004015B6  8D4C2460       LEA       ECX,[ESP+60]
0167:004015BA  50             PUSH      EAX                ; zmodyfikowane
                                                           ; podklucze
0167:004015BB  8D942494000000 LEA       EDX,[ESP+00000094]
0167:004015C2  51             PUSH      ECX                ; buffer
0167:004015C3  52             PUSH      EDX                ; serialinhex
0167:004015C4  E847FCFFFF     CALL      00401210           ; IdeaDecrypt

No i doszlimy waciwie do serca crackme. Jak wida, za pomoc przeksztaconych podkluczy wygenerowanych z MD5(name) deszyfrowany jest nasz serial. Ale waciwie, co dokadniej? Dokadnie pierwsze 16 znakw zapisanych w hex. Oczywicie, 16 znakw ASCII w hex zajmuje 8 bajtw, czyli tyle ile IDEA moe zaszyfrowa/odszyfrowa za jednym razem (pamitasz, e operuje ona na blokach 8 bajtowych?). Oki, oczywicie odszyfrowane dane s przechowywane w bufferze podanym w argumentach. Dalej:

0167:004015C9  8D8424C0010000 LEA       EAX,[ESP+000001C0]
0167:004015D0  8D8C24F8000000 LEA       ECX,[ESP+000000F8]
0167:004015D7  50             PUSH      EAX                ; buffer
0167:004015D8  51             PUSH      ECX                ; MD5 hash
0167:004015D9  E822FAFFFF     CALL      00401000           ; IdeaExpandKey

Ke? Poznajesz to? Tak to ju si wykonywao kilka linijek wyej. Tak, tak, oczy Ci nie myl. Jest to pewnie zwizane z tym, e crackme jest pisane w jzyku wysokiego poziomu (chyba c++). Z tego wanie wynikaj te mieci. Rwnie dobrze mgby wykasowa ten kod, a crackme dziaao by take poprawnie. Zauwaye co jeszcze? Skoro, znowu zostaj obliczone podklucze, to znaczy, e bdzie co jeszcze odszyfrowane. Pamitasz, e ostatnia procka odszyfrowaa tylko 16 znakw seriala? Tak, tak, teraz czas na nastpne. look:

0167:004015DE  8D942498020000 LEA       EDX,[ESP+00000298]
0167:004015E5  52             PUSH      EDX
0167:004015E6  8D8424CC010000 LEA       EAX,[ESP+000001CC]
0167:004015ED  50             PUSH      EAX
0167:004015EE  E89DFAFFFF     CALL      00401090           ; IdeaInvertKey
0167:004015F3  83C444         ADD       ESP,44
0167:004015F6  8D8C245C020000 LEA       ECX,[ESP+0000025C]
0167:004015FD  8D542448       LEA       EDX,[ESP+48]
0167:00401601  8D442458       LEA       EAX,[ESP+58]
0167:00401605  51             PUSH      ECX                ; podklucze
0167:00401606  52             PUSH      EDX                ; buffer
0167:00401607  50             PUSH      EAX                ; serialinhex
0167:00401608  E803FCFFFF     CALL      00401210           ; IdeaDecrypt

Next:

0167:0040160D  8D4C2460       LEA       ECX,[ESP+60]
0167:00401611  8D54245C       LEA       EDX,[ESP+5C]       ; poszczeglne
0167:00401615  51             PUSH      ECX                ; czci
0167:00401616  8D44245C       LEA       EAX,[ESP+5C]       ; seriala
0167:0040161A  52             PUSH      EDX                ; po
0167:0040161B  8D4C245C       LEA       ECX,[ESP+5C]       ; deszyfrowaniu
0167:0040161F  50             PUSH      EAX
0167:00401620  8D54245C       LEA       EDX,[ESP+5C]
0167:00401624  51             PUSH      ECX
0167:00401625  8D44245C       LEA       EAX,[ESP+5C]
0167:00401629  52             PUSH      EDX
0167:0040162A  8D4C245C       LEA       ECX,[ESP+5C]
0167:0040162E  50             PUSH      EAX
0167:0040162F  8D54245C       LEA       EDX,[ESP+5C]
0167:00401633  51             PUSH      ECX
0167:00401634  52             PUSH      EDX
0167:00401635  8D8424DC000000 LEA       EAX,[ESP+000000DC]
0167:0040163C  68CC704000     PUSH      004070CC           ; format
0167:00401641  50             PUSH      EAX                ; buffer
0167:00401642  FF15D8604000   CALL      [004060D8]         ; wsprintfA

Powysza procka odpowiedzialna jest za poczenie po deszyfrowaniu wszystkich czci serial w jedn 16 bajtow cao. Wykonywane jest to poprzez wywoanie api wsprintfA z odpowiednim formatem. A co dalej? Mona si chyba domyla ... :)

0167:00401648  83C434         ADD       ESP,34
0167:0040164B  8D8C24B0000000 LEA       ECX,[ESP+000000B0]
0167:00401652  8D9424E4000000 LEA       EDX,[ESP+000000E4]
0167:00401659  889C24F4000000 MOV       [ESP+000000F4],BL
0167:00401660  51             PUSH      ECX                ; serial po
                                                           ; deszyfrowaniu
0167:00401661  52             PUSH      EDX                ; name
0167:00401662  FF1568604000   CALL      [00406068]         ; cmp
0167:00401668  85C0           TEST      EAX,EAX            ; jeeli
                                                           ; nierwne
0167:0040166A  5D             POP       EBP
0167:0040166B  751A           JNZ       00401687           ; to bye bye

He.. i ju prawie koniec. Jak wida nasz serial (in hex) po deszyfrowaniu IDEA jest porwnywany z pierwszymi 16 bajtami naszego name (pamitasz, e piszc name, mam na myli to name po powieleniu?). Oki, teraz jak to rozwiza? Zobacz, zabezpieczenie przedstawia si tak:

IDEA_DECRYPT(serialinhex,MD5_NAME) == NAME

Jak pamitasz, klucz w algorytmach symetrycznych (a takim jest IDEA) uywany jest zarwno do szyfrowania jak i deszyfrowania, wic rozwizanie to:

serialinhex = IDEA_CRYPT(NAME,MD5_NAME)

Teraz tylko serialinhex trzeba zamieni na ASCII i mamy serial (aha, pamitasz, e co pity znak seriala jest pomijany i nie bierze udziau w IDEA_CRYPT? Musisz wic w to miejsce powstawia jakie inne dane - ja wstawiem kropk). Oki, najlepiej napisa od razu keygena. Mam nadziej, e do tutoriala bdzie doczony mj keygen wraz z src, wic jak czego nie zrozumiae to przeled rda. Najlepiej jednak obejrze sobie to pod SI.

NAME:   Tymon
SERIAL: 2538.6E5C.29F5.1116.80A2.E114.A66E.3FFE

.: OUTRO :.

Nom i ju :) W sumie crackme byo cakiem proste :) Wystarczy tylko zrozumie algorytm IDEA i to wystarcza. Ostatnio coraz czciej mona spotka crackme&soft z zabezpieczeniem wykorzystujcym algorytmy kryptograficzne, warto wic powici na nie troch czasu (przewanie, e s dosy interesujce). Oki, co tu mona jeszcze powiedzie? Oczywicie jak masz jakie pytania to tymon_crk@wp.pl, albo zap mnie na irc'u. Oki, do nastpnego tutka.

.: GREETZ [a..z] :.

Agent - your crypto-book is very useful ;)
Cybult - next crackmeman ;)
Czajnick - thnx for your books
ged_//TKM! - thnx for help ;)
hauer - yo mr. president ;)
Kwasek - do you like chess? :)
smola - xor eax, eax - yee, i'm fucking lamer !
ToMKoL - c4u rox ;)
Ved - yo ninja ;)
Veneta  - good luck in a new school :)
WiteG - man, you are really good. Thanx for your crypto in asm

all HTBTeam members