Nazwa Progu	: Crackme 8.1 by JuBE
Data        	: 07/10/2001
Napisal   	: Kwasek ...::[ HTBteam ]::...
Co        	: tutorial
Skill		: Medium



HI witam was w moim nastepnym tutorialku. Zajmiemy sie Crackme 8.1 by JuBE, jest to wedlug mnie
ulepszony FightMe3.0. Takze najlepiej jakbys obadal najpierw FightMe3.0, a pozniej przystapil 
do lamania Crackme 8.1. Tutorial do FightMe3.0 znajdziesz na mojej stronce:
http://www.kwasek2.prv.pl lub na znanej wszystkim stronie: http://www.crackmes.prv.pl

No dobra odpalamy CrackMe wpisujemy jakies byle jakie dane, zakladamy pulapke na bpx hmemcpy
i naciskamy Register. Teraz naciskaj tyle razy F10 az znajdziesz sie w kodzie CrackMe:

		push	offset _Name
		push	1F4h
		push	0Dh
		push	12Dh
		push	dword ptr [ebp+8]
		call	SendDlgItemMessageA
		cmp	eax, 0
		jz	loc_401892		
		cmp	eax, 4
		jb	loc_401881		; name minimum 4 znaki
		push	offset _serial
		push	1F4h
		push	0Dh
		push	12Eh
		push	dword ptr [ebp+8]
		call	SendDlgItemMessageA
		cmp	eax, 0
		jz	loc_4018A3 		; czy cos wpisano w serial


		mov	edi, offset _serial
		dec	edi
		xor	ebx, ebx

loc_40138B:
		mov	al, [edi+ecx]
		cmp	al, 2Dh			; czy znakiem jest '-'
		jnz	short loc_401393
		inc	ebx

loc_401393:
		loop	loc_40138B
		cmp	ebx, 6			; serial musi zawierac 6 myslnikow
		jnz	loc_4018B4

Jak widac powyzej pobierane sa kolejno name i serial. Serial musi skladac sie z 6 myslnikow.
Name: Kwasek
Serial: 1212-2323-3434-4545-5656-6767
Nastepnie kazdy czlon seriala jest spawdzany czy jego znaki znajduja sie w granicach od
30h do 39h. Tak wiec jezeli sa to tylo cyfry, crackme zamienia je na wartosc hex.
Gdy cala zamian dobiegnie konca zobaczymy takie cos:

	mov     eax, _serial1	;	1 czesc seriala
	mov     ebx, _serial5	;	5 - || -- || -
	mov     edx, _serial7	;	7 - || -- || -
	mov     ecx, 0ABCDEh
	xchg    eax, edx
	
loc_401564:                           	
	rol     eax, 1
	xor     ah, bl
	ror     ebx, 3
	rol     eax, 2
	add     eax, ecx
	rol     eax, 2
	add     eax, edx
	inc     edi
	loop    loc_401564
	cmp     eax, 0BACA6581h
	jnz     loc_4018B5

Ta procedura narazie nie jest wazna, wiec r fl z i jedziemy dalej.

		mov	edi, offset a111111111111	; miejsce klucza
		mov	eax, _serial1		;
		xor	eax, _serial4		; _serial1^_serial4 = x
		mov	[edi], eax		; kopiuj x do edi(miejsce klucza)
		mov	eax, _serial2
		xor	eax, _serial5		; _serial2^_serial5 = y
		add	edi, 4			; zwieksz edi o 4
		mov	[edi], eax		; kopiuj y do edi(miejsce klucza)
		mov	eax, _serial3
		xor	eax, _serial6		; _serial3^_serial6 = z
		add	edi, 4			; zwieksz edi o 4
		mov	[edi], eax		; kopiuj z do edi(miejsce klucza)
		mov	ebx, offset loc_401864
		dec	ebx
		mov	ds:dword_40201C, eax
		push	offset a111111111111
		push	ebx
		push	offset dword_4015F3	; tu znajduje sie zakodowana pocedura
		call	sub_401ADE		; wywolanie procedury

Jak juz spotkales sie z FightMe3.0 to napewno wiesz ze tutaj jest obliczany z seriala klucz. 
Klucz ten jednak moze miec maksymalna dlugosc az 96 bitow. Zobaczmy co sie znajduje w 
call	sub_401ADE

sub_401ADE	proc near

arg_0		= dword	ptr  8
arg_4		= dword	ptr  0Ch
arg_8		= dword	ptr  10h

		enter	0, 0
		push	ebx
		push	edi
		push	esi
		mov	edi, [ebp+arg_0]	;kopiuj adres zakodowanej procki

loc_401AE8:
		mov	esi, [ebp+arg_8]	;kopiuj adres klucza

loc_401AEB:
		mov	al, [esi]		;kopiuj znak klucza
		cmp	al, 0			;jezeli znakiem jest 0h 
		jz	short loc_401AE8	;to przejdz do poczatku klucza
		cmp	edi, [ebp+arg_4]	;czy zostaly odszyfrowane wszystkie znaki
		ja	short loc_401AFC
		xor	[edi], al	    ;xoruj znak zaszyfrowanej procki ze znakiem klucza
		inc	edi			; zwieksz o 1 adres zaszyfr.procki
		inc	esi			; zwieksz adres klucza
		jmp	short loc_401AEB	

loc_401AFC:
		pop	esi
		pop	edi
		pop	ebx
		leave
		retn	0Ch

Kod ten xoruje kolejno znaki klucza ze znakami zaszyfr. procki. Ciekawostka jest to, ze nie
znamy dokladnej dlugosci klucza. Np. moze to byc klucz o dl. 8bit. Przypuscmy ze jest to
litera'A'. Znak'A' jest kopiowany do Al sprawdzany czy nie jest to 0h jesli nie to pierwszy
znak zaszyfr. procki xorowany jest z al('A').Dalej pobierany jest nastepny znak klucza, w naszym
przypadku go niema czyli do al jest kopiwane 0 i jesli jest to 0 to nastepnym znakiem, przez
ktory zostanie zxorowany znak z zaszyfr.procki jest znow znak 'A'.Dla klucza 16 bitowego np.
'AB' jak juz sie domysliles bedzie wygladalo tak: p1^'A', p2^'B', p3^'A', p4^'B' itd. Podobnie
ma sie sprawa z kluczem o dl. 24,32,40,48,56,64,72,80,88,96 bitow.

Tak wiec podsumowujac: 
- dlugosc klucza moze znajdowac sie w granicach od 8 do 96 bitow
- (i najgorsze) nie znamy dokladnej dl. klucza

  
----------------------------------------------------------------------------------------------
-----------------------------------Zaszyfrowana procedura-------------------------------------
----------------------------------------------------------------------------------------------

procka		dd 27505649h, 3C312420h, 56494C4Dh
		dd 255519CCh, 6EF88163h, 614756Ah, 4161115h, 10000C0Fh
		dd 16545953h, 1C0708h, 541C014Ah, 1C1A1F17h, 55101C0Fh
		dd 1F541B07h, 150D090Dh, 11095513h, 90D1F54h, 1F4A151Dh
		dd 17540E06h, 619120Ch,	1A120F0Bh, 543001Dh, 120F0501h
		dd 1737541Ch, 2050B02h,	5A4B550Fh, 484E4544h, 10100A04h
		dd 16541D1Fh, 0B4E0502h, 11075505h, 0C430A13h, 10101C01h
		dd 16111817h, 4F011C43h, 1A1C1E19h, 1C080400h, 64A051Bh
		dd 1F54111Ah, 1034806h,	151D550Bh, 0A160F54h, 1A1A2F0Bh
		dd 11A151Fh, 2010B4Dh, 1B531C4Ah, 12100C04h, 1E0B054Eh
		dd 654191Ah, 20B0C16h, 151D0F4Ah, 4190418h, 1E4A1C0Bh
		dd 1F17011Fh, 1A0343h, 541E0C18h, 1210040Eh, 1A180917h
		dd 181504h, 1D1E480Eh, 10161605h, 48061701h, 14181F1Dh
		dd 40E1004h, 0E0D0909h,	545D5B44h, 0B430A1Ah, 1E4A1501h
		dd 0F11181Ch, 24E0D0Dh,	54161F05h, 0B021717h, 550F0205h
		dd 120E1B01h, 1010402h,	545E550Fh, 0D191700h, 184A0E0Ch
		dd 18070Ah, 0E004800h, 151D550Eh, 18061107h, 55071600h
		dd 4B5A5D49h, 0E1A484Dh, 1D045501h, 0C430611h, 1E0F0614h
		dd 40E541Ah, 3070343h, 17531401h, 40A121Ch, 101A1C4Eh
		dd 0B1B0E17h, 4F060B1Ah, 0D09071Ah, 51A1154h, 1A181F4Eh
		dd 8150614h, 4F1B030Ah,	11195503h, 12001F07h, 14184F0Bh
		dd 17135409h, 31B1C02h,	1119160Bh, 68424455h, 7D73ECD6h
		dd 3BD4770h, 70E467E8h,	0B741B5BBh, 0A8A2AD7Bh,	0B4785B6Ch
		dd 0A47776B3h, 6A5D8681h, 7433503Fh, 689FE07Bh,	18D56F6Eh
		dd 0DD743452h, 7D5A3E1Bh, 745626D3h, 0E87CEF74h, 721F6F95h
		dd 255519CCh, 0BE9C8363h, 7BB047A2h, 0A9A256BCh, 0B5E96CA6h
		dd 84963376h, 4A376D50h, 0F17C752Ah, 686365B6h,	354B02D1h
		dd 7465CC73h, 6ED7F1FAh, 0FE73754Ah, 6898E56Bh,	18D5681Bh
		dd 8E743452h, 5DA6B991h, 47BB7AA9h, 6CABA4B5h, 326DAFEDh
		dd 60479591h, 6F2E4D3Eh, 74FBF065h, 30336574h, 0DC026F04h
		dd 9A74346Ah, 9046016h,	54734095h, 0CB8B6534h, 9E6A6F6Bh
		dd 4657577Fh, 4C2A2626h, 57505649h
		db  57h,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

No dobra, co moze znajdowac sie w zaszyfrowanej procce?. Na pewno znajduje sie informacja o
dobrym serialu. Ja rozpakowalem exeka, ktorego zaladowalem do exescope, tam znalazlem tak samo
jak w przypadku FightMe3.0 dialoga z informacja o dobrym hasle. Czyli jest wywolywana funkca
DialogBoxParamA  ,E8xxxx0000 (xxxx)- zaleza od adresu gdzie ten call sie znajduje.
Tak wiec mamy 3 bajty ktore na 100% znajduja sie gdzies zaszyfrowane.W przypadku klucza o
dlugosci od 8 do 32 bit. to male piwo. Zrobilo by sie brute force'a, ktory po xorowaniu szukalby
bajtu E8 i jezeli 3 i 4 bajt po bajcie E8 = 0 to dobry klucz. Tak bylo w FightMe3.0, w ktorym 
znalezienie klucza trwalo troche dlugo. Tu mamy podobna sytuacje, z ta roznica ze klucz moze
miec dlugosc az 96 bitow. Tak wiec znalezienie poprawnego klucza moze trwac wieki. Chyba ze :)
bedziemy mieli wiecej bajtow do porownania.
Zrob takie cos:
- odpal CrackMe, zaloz pulapke na  DialogBoxParamA, nacisnij About, teraz F12, nacisnij Ok,
  spisz cala procedure wywolujaca abouta:

  6A00		push	0
  68AA194000	push	offset loc_4019A9
  FF7508	push	dword ptr [ebp+8]
  6A65		push	65h
  FF3500204000	push	hInstance
  E8E9A00000	call	DialogBoxParamA

teraz napiszmy sobie jak moze wyglodac procedura wywolujaca info o dobrym serialu

  6A00		push	0			; to powinno byc takie same jak wyzej
  68AA194000	push	offset loc_4019A9	; tu moze byc inne
  FF7508	push	dword ptr [ebp+8]	; to powinno byc takie same jak wyzej
  6A66		push	66h			; zmieniamy id dialoga abouta na dialoga info
  FF3500204000	push	ds:hInstance		; to powinno byc takie same jak wyzej
  E8xxxx0000	call	DialogBoxParamA		; to samo za wyjatkiem xxxx

Tak wiec napisalismy sobie jak wyglada przypuszczalnie wywolanie dialoga w zaszyfrowanym kodzie

Zobaczmy na przykladzie naszego przypuszczalnego kodu jak wyglada xorowanie z kluczem o dl.
powyzej 32 bitow.

	   nasza procka	|6A0068AA19|4000FF7508|6A66FF3500|204000E8xx|xx0000
	   klucz 40 bit	|1234567890|1234567890|1234567890|1234567890|1234567890|

widzimy tu ze co piaty bajt procki jest xorowany przez ta sama wartosc klucza np.
przez bajt 12h xorowane sa bajty: 6ah,40h,6ah,20h,xx
Tak samo wyglada sprawa z wiekszymi kluczami np.48bit. co 6 znak, 56bit. co 7 znak itd.

No dobra, ale co nam to pomoglo. Otoz bardzo duzo. Mozna zrobic takiego brute forcea:

- zxoruj cala procke przez jakis 1 bajt 
- wyszukaj w zxorowanym kodzie pierwszy bajt naszego przypuszczalnego kodu(6ah)
- sprawdz czy 5 bajt(dla 40 bitowego klucza) po tym znalezionym to 40h
- jesli tak to: Spisz wartosc rejestru Ecx, jest to jakby adres znalezionych bajtow.
		Gdy wyjdziesz z SoftIce bajt przez ktory zostanie zxorowana procka zostanie
		zwiekszony o 1 i proces xorowania zacznie sie od poczatku. Jest tylko FFh 
		kombinacji. Miejsc w ktorym wystepuja poprawne bajty jest przewaznie kilka.
		Gdy wszystko spiszesz zmien w brute forsie bajt poczatkowy na drugi, ten po 
		6ah czyli 00 i wszystko zrob od poczatku spisujac wszystkie adresy znalezinych
		bajtow.
- jesli nie to: jak wogole nie pojawi sie SoftIce zmien odrazu bajt na nastepny (opisane wyzej)
- acha ustaw pulapke na int 3

Czego wogole szukamy?

Wyobraz sobie (wszystko na przykladzie klucza 40 bitowego) ze brute force znalazl dla pierwszego
bajtu oczekiwane bajty i znajduja sie pod adresem (6A) adresy np. 12h,36h,57h,143h,211h,100h.
nastepnie dla drugiego w takich adresach          (00) adresy np. 33h,67h,83h,101h,04h  
dla 3						  (68) adresy np. 102h,54h,62h,10h,149h
itd.

przyjrzyj sie tym adresom. 6A - adres 100h
			   00 - adres 101h
			   68 - adres 102h

no pewnie i tak powinno byc, zwiekszales bajty o 1, a tym samym zwiekszaly sie adresy o 1.
Pamietaj jest to narazie przyklad.
Tak wiec jesli adresy w ktorych znajduja sie szukane bajty zwiekszaja sie o 1 to masz 100%
pewnosci ze procka jest zxorowana tym wlasnie kluczem o tej dl. w tym przykladzie 40 bitowym


Teraz poszukamy ten prawdziwy klucz
Brute force jest dolaczony 
Oto jego najwazniejszy wycinek:
 

 
		mov	al,	[esi]
		cmp	al,	06ah	  ;poczatkowy bajt
		jnz	_dalej
		mov	al,	[esi+05h] ;5 - 40 bitow, 6 - 48 bitow itd.
		cmp	al,	040h	  ;


i co wyszlo dla 40 bitowego:

6a - 40  adresy: nie ma
00 - 00  adresy: 97,39,fe,4d,182,2a,26e,26d,26f,244
68 - FF  adresy: nie ma
AA - 75  adresy: 1fb,1cc
idt..
Nie ma sensu dalej sprawdzac poniwaz, jak zauwazyles nie ma adresow, ktore mialy by taka postac 
jak podana zostala w przykladzie

Teraz powiniwnes zwiekszyc dlugosc klucza czyli zamien 5 na 6. Postepuj tak az znajdziesz
zwiekszajace sie o 1 adresy.

Ja to zrobilem i znalazlem. Klucz jest 80 bitowy

6a - 6a  adresy: 243,214,1d1,c8,ed,0,18f,7e,1,265,36,33,c6,39,135,5a,38,117,13e,80,|24c|,172,dc,
		 2d,89,f3,3b
00 - 66  adresy: 257,|24d|
68 - FF  adresy: |24e|
aa - 35  adresy: 21c - tu powinno byc 24f wychodzi z tego ze oryginal rozni sie troche 
19 - 00  adresy: e1,181,16d,d6,b1,26a,268,26e,26f,26d,26c,26b,|250|
40 - 20  adresy: |251| 
00 - 40  adresy: 1a0,1d9,213,e,14d,1cf,209 - tu powinno byc 252
ff - 00  adresy: 26d,26f,244,|253|,258,249,26f,26d,26e,26b,26c,26a,268
75 - E8  adresy: |254|
08 - xx  adresy: nie znamy xx tu powinno byc 255
6a - xx  adresy: nie znamy xx tu powinno byc 256
66 - 00  adresy: 24d,26b,26c,26d,26f,26e,268,26a,|257|
ff - 00  adresy: 253,|258|,249,26f,26d,26e,26b,26c,26a,268

no dobra mamy 4 niewiadome trzeba cos z tym zrobic

wez sobie pierwszy adres czyli 24ch dodaj 1 i podziel go przez ilosc znakow klucza czyli 0ah
wyszlo reszty 9 wiec jest to 9 znak klucza 
teraz wejdz do brut force'a ustaw poczatkowy bajt na 6a koncowy na 6a naciskaj tyle razy ctrl+d
az progran znajdzie prawidlowe bajty pod adresem oczywiscie 24c. Teraz zobacz na Eax
?eax i masz 9 znak klucza. Postepuj tak z nastepnymi bajtami uwzgledniajac oczywiscie
znalezione adresy. Otzymasz take cos:


				j st ec	no
				
Ja odgadlem klucz, ale mozesz tez wykozystac tutorial do fightme3.0 tam jest opisane jak poznac
te xxxx w DialogBoxParamA. to nam da w tym przypadku tylko jedna literke 

				j st echno

Mozna napewno znalezc pozostale dwie litery, 
ale poco sie bawic, haslo widac na pierwszy rzut oka:      justtechno

Opisalem tu natrudniejsza czesc CrackMe jakim jest znalezienie klucza przez ktory szyfrowany
jest spory kawalek kodu. Znajac poprawny klucz mozesz juz przystapic do wykiczenia seriala.
Jesli cos ci nie wychodzi, obejrzyj source keygena.
