You are on page 1of 61

Introduccin:

Me suelen llamar D3m0n3vX, y este es mi primer documento escrito para CLS


(CracksLatinoS), espero sepan perdonarme si hay algn tipo de error tanto en
escritura o en la explicacin de los Binarios que vamos a analizar. Gracias.

Sylkat nos propone tres retos, vamos a ver que nos dice sobre ello

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Anlisis:

Vemos lo que adjunta:


_ _

____

_| || |_ / ___| _ __ _ _
|_ .. _| | |
|_

__/ _` |/ __| |/ / \

_| | |___| | | (_| | (__| <

|_||_|

\____|_| \__,_|\___|_|

#########################################################
#
#

Cracknival 1 (Fcil)

PasswordZip: AfE3BhA5g1p

Consigue el password del zip Cracknival 2.

Puedes parchear

#
#

Cracknival 2 (Fcil)

PasswordZip:

Consigue el password del zip Cracknival 3.

Puedes parchear.

#
#

Cracknival 3 (Moderado)

PasswordZip:

Roba el cdigo fuente del proyecto CrackNival.

No puedes parchear.

#
#########################################################

Nosotros vamos a intentar NO Parchear nada y conseguir todos los retos, eso
espero.

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Ejecutamos el CrackNival_1.exe que es el primer reto, llenamos los campos y


vemos esto:

Vemos el clsico Bad Boy. Le pasamos un detector y observamos:

Un C++ Visual ha sido el encargado de crear este Binario.

Reversand0:

Lo abrimos con el Olly y buscamos el chico malo en Strings:->

Le damos y caemos aqu:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Podemos ver el CALL en verde que es ejecutado antes del chico malo e bueno, y es
con el TEST EAX,EAX que decide cual de los dos. Si entramos en dicho call vemos
esto:

Ponemos un BP en 00401389 le damos Run en el Olly, ponemos los datos y


pulsamos el botn Get Password, pero antes nos fijamos en el cdigo muerto que
nos muestra el Olly, y vemos un CMP EAX,0Ah esto como se puede ver al tracear
es el largo de la Key, y queda as:

Y Olly rompe aqu:

Ahora vamos traceando toda la rutina(+Bucle) y parados aqu:

Miramos el Buffer:

Y vemos la Key buena, quedando los datos as:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Le damos y

Consigue el password del zip Cracknival 2. ==>> 1135913192


Primer reto superad0;)

Anlisis:

Ejecutamos el CrackNival_2.exe:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Le pasamos un Detector:

Otro C++.
Podemos ver unos 4 == CheckBox, se pueden tildar todos, o uno, o dos etc, nosotros
vamos a trabajar siempre y es importante con el == Tildado el CheckBox
(Abajo/derecha).
Y metemos los datos:

Aqu hemos metido una Key de longitud de 0x10d Bytes, ya que viendo como
nuestro amigo Sylkat le gusta esa cifra 0x0Ah, del reto 1, vamos a ver si nuestra
Social Reversing nos funciona o no ?, le damos y vemos esto:

Reversand0:

Lo abrimos con el Olly y buscamos el chico malo en Strings:->

Le damos y caemos en esta Zona:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

Vemos otro CALL importante antes del Bad Boy, y el tpico TEST EAX, EAX,
vamos a probar a forzar el salto de 00401C2A == JE y vemos lo que nos tiene
reservado nuestro amigo Sylkat:->

Y vemos como nos saca un Password totalmente malo y no vlido para el ZIP.
As que no se puede parchear, ni tampoco era nuestra la idea de hacerlo, nos
vetemos de lleno dentro del CALL antes de decidir y vemos esto:
00401340 /$ 55

PUSH EBP

00401341 |. 57

PUSH EDI

00401342 |. 31C9

XOR ECX,ECX

00401344 |. 56

PUSH ESI

00401345 |. 53

PUSH EBX

00401346 |. 83EC 38

SUB ESP,38

00401349 |. A1 54604000

MOV EAX,DWORD PTR DS:[406054]

0040134E |. 8B2D 50604000

MOV EBP,DWORD PTR DS:[406050]

00401354 |. 8B35 4C604000

MOV ESI,DWORD PTR DS:[40604C]

0040135A |. 8B3D 48604000

MOV EDI,DWORD PTR DS:[406048]

00401360 |. C70424 20000000

MOV DWORD PTR SS:[ESP],20

00401367 |. 8D1C28

LEA EBX,DWORD PTR DS:[EAX+EBP]


Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

0040136A |. 894424 08

MOV DWORD PTR SS:[ESP+8],EAX

0040136E |. 0FBE05 29604000

MOVSX EAX,BYTE PTR DS:[406029]

00401375 |. 897424 0C

MOV DWORD PTR SS:[ESP+C],ESI

00401379 |. 897C24 04

MOV DWORD PTR SS:[ESP+4],EDI

0040137D |. 01F3

ADD EBX,ESI

0040137F |. 31F6

XOR ESI,ESI

00401381 |. 01FB

ADD EBX,EDI

00401383 |. BF 56555555

MOV EDI,55555556

00401388 |. 894424 10

MOV DWORD PTR SS:[ESP+10],EAX

0040138C |. 0FBE05 2A604000


00401393 |. 894424 14

MOVSX EAX,BYTE PTR DS:[40602A]


MOV DWORD PTR SS:[ESP+14],EAX

00401397 |. 0FBE05 2C604000

MOVSX EAX,BYTE PTR DS:[40602C]

0040139E |. 894424 18

MOV DWORD PTR SS:[ESP+18],EAX

004013A2 |. 0FBE05 2D604000


004013A9 |. 894424 1C

MOVSX EAX,BYTE PTR DS:[40602D]


MOV DWORD PTR SS:[ESP+1C],EAX

004013AD |. 0FBE05 2F604000


004013B4 |. 894424 20

MOVSX EAX,BYTE PTR DS:[40602F]


MOV DWORD PTR SS:[ESP+20],EAX

004013B8 |. 0FBE05 30604000


004013BF |. 894424 24

MOVSX EAX,BYTE PTR DS:[406030]


MOV DWORD PTR SS:[ESP+24],EAX

004013C3 |. 0FBE05 32604000


004013CA |. 894424 28

MOVSX EAX,BYTE PTR DS:[406032]


MOV DWORD PTR SS:[ESP+28],EAX

004013CE |. 0FBE05 33604000


004013D5 |. 894424 2C

MOVSX EAX,BYTE PTR DS:[406033]


MOV DWORD PTR SS:[ESP+2C],EAX

004013D9 |. 0FBE05 35604000


004013E0 |. 894424 30

MOVSX EAX,BYTE PTR DS:[406035]


MOV DWORD PTR SS:[ESP+30],EAX

004013E4 |. 0FBE05 36604000


004013EB |. 894424 34

MOVSX EAX,BYTE PTR DS:[406036]


MOV DWORD PTR SS:[ESP+34],EAX

004013EF |. EB 16

JMP SHORT CrackNiv.00401407

004013F1 |> 31C0

/XOR EAX,EAX

004013F3 |. 80B9 28604000 2D


004013FA |. 0F95C0

|CMP BYTE PTR DS:[ECX+406028],2D


|SETNE AL

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

004013FD |. 83C1 01

|ADD ECX,1

00401400 |. 01C3

|ADD EBX,EAX

00401402 |. 83F9 0F

|CMP ECX,0F

00401405 |. 74 6B

|JE SHORT CrackNiv.00401472

00401407 |> 89C8

MOV EAX,ECX

00401409 |. F7EF

|IMUL EDI

0040140B |. 89C8

|MOV EAX,ECX

0040140D |. C1F8 1F

|SAR EAX,1F

00401410 |. 29C2

|SUB EDX,EAX

00401412 |. 8D0452

|LEA EAX,DWORD PTR DS:[EDX+EDX*2]

00401415 |. 39C1

|CMP ECX,EAX

00401417 |.^ 74 D8

\JE SHORT CrackNiv.004013F1

00401419 |. 83F9 01

CMP ECX,1

0040141C |. 74 5E

JE SHORT CrackNiv.0040147C

0040141E |. 83F9 02

CMP ECX,2

00401421 |. 0F84 A8010000


00401427 |. 83F9 04

CMP ECX,4

0040142A |. 0F84 76010000


00401430 |. 83F9 05

00401439 |. 83F9 07

00401442 |. 83F9 08

JE CrackNiv.00401555
CMP ECX,8

00401445 |. 0F84 E2000000


0040144B |. 83F9 0A

JE CrackNiv.0040152D
CMP ECX,0A

0040144E |. 0F84 B3000000


00401454 |. 83F9 0B

JE CrackNiv.00401507
CMP ECX,0B

00401457 |. 0F84 82000000

00401462 |. 83F9 0E

JE CrackNiv.0040157D
CMP ECX,7

0040143C |. 0F84 13010000

00401460 |. 74 57

JE CrackNiv.004015A6
CMP ECX,5

00401433 |. 0F84 44010000

0040145D |. 83F9 0D

JE CrackNiv.004015CF

JE CrackNiv.004014DF
CMP ECX,0D
JE SHORT CrackNiv.004014B9
CMP ECX,0E

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

00401465 |. 74 31

JE SHORT CrackNiv.00401498

00401467 |> 83C1 01

ADD ECX,1

0040146A |. 83C6 01

ADD ESI,1

0040146D |. 83F9 0F

CMP ECX,0F

00401470 |.^ 75 95

JNZ SHORT CrackNiv.00401407

00401472 |> 83C4 38

ADD ESP,38

00401475 |. 89D8

MOV EAX,EBX

00401477 |. 5B

POP EBX

; 00A10B40

00401478 |. 5E

POP ESI

; 00A10B40

00401479 |. 5F

POP EDI

; 00A10B40

0040147A |. 5D

POP EBP

0040147B |. C3

RETN

; 00A10B40

Podemos ver como la longitud de la Key == 0x0Ah estbamos en lo correcto, y voy


a explicar cmo se genera todo correctamente:

Buffer:
0022F8F4 00406038 ASCII "asdfghjklz"
0022F8F4 00406038 ASCII "1234567890" == ID !!

GET == 0040601A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 73 ..............as


0040602A 64 66 67 68 6A 6B 6C 7A 00 77 65 72 74 00 31 32 dfghjklz.wert.12
0040603A 33 34 35 36 37 38 39 30 00 00 00

34567890...

Coge el 0x03 Byte == Key !!


00401397

0FBE05 2C604000

movsx eax,byte ptr ds:[0x40602C]

Coge el 0x05 Byte == Key !!


Coge el 0x06 Byte == Key !!
Coge el 0x08 Byte == Key !!
Coge el 0x09 Byte == Key !!
Coge el 0x06 Byte == Key !!

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

10

004013F3

80B9 28604000 2D

cmp byte ptr ds:[ecx+0x406028],0x2D

Coge 0x01 Byte == ID


0040147C

0FBE86 38604000

movsx eax,byte ptr ds:[esi+0x406038]

Aqu:
00401483

2B0424

sub eax,dword ptr ss:[esp]

00401486

034424 08

add eax,dword ptr ss:[esp+0x8]

0040148A

394424 10

cmp dword ptr ss:[esp+0x10],eax

ID = Key ?!
ID == 1234567890
Key == asdfghjklz

Tildado el CheckBox Abajo/derecha!!!

Para:->

0x01 Byte ID == +20h,+0x0h == Q == 51h

0x02 Byte Key == 31h

Q234567890
a1dfghjklz

a1d-ghjklz
-------

Para:->

0x02 Byte ID == 0x03 Byte Key == "!" 21h + 21 h == 42h

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

11

QB34567890
a1!-ghjklz

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

Para:->

0x03 Byte ID == 0x05 Byte Key == "3" = "g" == = 61h = "a" - 0x1F == 42h

QBa4567890
a1!-Bhjklz

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

Para:->

0x04 Byte ID == 0x05 Byte Key == "4" = "h" == -23h == 23h + 23h = 46h ="F"

QBaF567890
a1!-B#jklz

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

004013F3

80B9 28604000 2D

cmp byte ptr ds:[ecx+0x406028],0x2D

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

12

QBaF567890
a1!-B#-klz

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

Para:->

0x05 Byte ID == 0x05 Byte Key == "5" = "k" == 25h +25h == 4Ah

QBaFo67890
a1!-B#-Jlz

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

Para:->

0x06 Byte ID == 0x05 Byte Key == "6" = "l" == 27h+27h = 4E

QBaFou7890
a1!-B#-JNz

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

004013F3

80B9 28604000 2D

cmp byte ptr ds:[ecx+0x406028],0x2D

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

13

QBaFou7890
a1!-B#-JN-z

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

Para:->

0x07 Byte ID == 0x05 Byte Key == "7" = "z" == 37h + 1D == 54h

QBaFouq890
a1!-B#-JN-T

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

Para:->

0x08 Byte ID == 0x05 Byte Key == "8" = "x" == 21h + 21h == 42h

QBaFouqB90
a1!-B#-JN-T!

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

004013F3

80B9 28604000 2D

cmp byte ptr ds:[ecx+0x406028],0x2D

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

14

QBaFouqB90
a1!-B#-JN-T!-kl
-----------------------------------------

Para:->

0x09 Byte ID == 0x05 Byte Key == "9" = "k" = Byte 0x07 = "q" == 79h

QBaFouqB+0
a1!-B#-JN-T!-yl
-------------------------------------------------

Para:->

0x00 Byte ID == 0x05 Byte Key == "0" = "l" =

QBaFouqB+Q
a1!-B#-JN-T!-y6

Metemos los datos y en Buffer vemos esto:


0022F8F4 0022F900 |Text = "Zip password: -CLS-201."

Consigue el password del zip Cracknival 3. ==>> -CLS-2016.

Segundo reto superad0;)

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

15

Anlisis:

Ejecutamos el CrackNival_3.exe:

Y vemos una tpica consola de LinuX y estamos como usario Guest que lastima no
ser root je ;
Vamos a darle a un habitual comando de Linux como es help y vemos esto:

Bien, tenemos un ls == Lista archivos, un cat == Imprime en la consola, un


login como es lgico, un id y un exit, pero aqu lo curioso es que si le damos un
comando de Windows como es dir vemos esto:

Que sera lo mismo que el ls:

Nustro amigo Sylkat nos lo pone fcil por si no sabes como se hace en Linux un
dir, pero como veremos este detalle sin inportancia, es lo de menos, lo ms
complicado tiene que venir an.

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

16

Le pasamos un detector:

Otro C++.
El objetivo de este reto es conseguir el Cdigo Fuente de los tres retos, as que
probamos si hay suerte y hacemos un catas:

Y como es normal no tenemos acceso!


Vamos a ver una cosa antes de empezar, no podemos parchear nada, pero si
intentamos saltar el Acces Denied. En esta Zona con Olly:->

No saltamos con el JNZ y nos muestra esto:

Y podemos pensar que los Bytes estn, pero de momento no son visibles, luego lo
veremos, as que vamos a empezar por obtener los datos correctos de este reto.

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

17

Vamos a hacer un Login a ver si conseguimos ser Root, y dejaremos como


intuimos que el largo del Password ser == 0x0Ah o sea 10 Bytes, y metemos los
datos as:

Aqu nosotros con el valor de _User no le daremos importancia, pero si al


Password y traceamos con Olly y llegamos a esta zona:

Esta Zona es la encargada del :


1.- Check == Total Bytes Password == 0x0A Bytes PassWord = + (0x0A) Bytes ==
Total == 43A ! y lo vemos al salir del RETN aqu:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

18

Y en EAX == 0000020D ! Por lo cal no se cumple el HASH de EAX == 043Ah.


Solo nos queda sacar por Brute-Force un Password de 10 Bytes con ese HASH, y
esperamos que Sylkat nos lo haya puesto fcil para conseguirlo, ya que si hubier
toda la tabla ASCII sera muy largo, pero pondremos esta Tabla y hacemos nuestro
Brute-Force en ASM as:

B32Chars
db
"@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy
z-@",0

Y al rato nos da estos Passwords vlidos:

flepTrtlxu == 1082d
rhuzmnMglv == 1082d
zfAxqyyehq == 1082d

Lo metemos a la consola as:

Y parados en el 1 Check vemos como queda la cosa:

Y los registros:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

19

Bien ! Podramos pensar que el trabajo esta hecho, pero si vemos la consola, dando
a F9 en el Olly :->

Hemos pasado el 1 Check, pero algo sigue fallando, as que miramos a partir de
este control y caemos en esta zona:->

Este cdigo parece fcil a simple vista, pero nada ms lejos de la realidad, para
resumirlo, es otro control sobre el Password tipo HASH y coge cada 0x01 Byte del
Password introducido y le hace un XOR con una Tabla Hard-Codeada, que aqu
vemos:

2.- Check == HASH == B7h ! == 0x01 == F6h XOR 0x01 Byte PassWord == 0x48h
Xor 0xFFh !

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

20

Hasta aqu un Pasword con dos HASHs fijos, con uno se abre la venta de
posibilidades al hacer el Brute-Force, pero con dos se abren millones, as que
ajustamos nuestro cdigo en ASM, quedando as:

key db
00h,03Eh,07Ch,042h,0F8h,0C6h,084h,0BAh,095h,0ABh,0E9h,0D7h,06Dh,053h,01
1h,02Fh,04Fh,071h,033h,00Dh,0B7h,089h,0CBh,0F5h,0DAh,0E4h,0A6h,098h,022
h,01Ch,05Eh,060h
db
09Eh,0A0h,0E2h,0DCh,066h,058h,01Ah,024h,00Bh,035h,077h,049h,0F3h,0CDh,08
Fh,0B1h,0D1h,0EFh,0ADh,093h,029h,017h,055h,06Bh,044h,07Ah,038h,006h,0BC
h,082h
db 0C0h,
0FEh,059h,067h,025h,01Bh,0A1h,09Fh,0DDh,0E3h,0CCh,0F2h,0B0h,08Eh,034h,0
0Ah,048h,076h,016h,028h,06Ah,054h,0EEh,0D0h,092h,0ACh,083h,0BDh,0FFh,0C
1h
db 07Bh,045h,
007h,039h,0C7h,0F9h,0BBh,085h,03Fh,001h,043h,07Dh,052h,06Ch,02Eh,010h,0A
Ah,094h,0D6h,0E8h,088h,0B6h,0F4h,0CAh,070h,04Eh,00Ch,032h,01Dh,023h
db 061h,05Fh,0E5h,
0DBh,099h,0A7h,0B2h,08Ch,0CEh,0F0h,04Ah,074h,036h,08h,027h,019h,05Bh,065
h,0DFh,0E1h,0A3h,09Dh,0FDh,0C3h,081h,0BFh,05h,03Bh,079h,047h,068h
db 056h,014h,02Ah,
090h,0AEh,0ECh,0D2h,02Ch,012h,050h,06Eh,0D4h,0EAh,0A8h,096h,0B9h,087h,0
C5h,0FBh,041h,07Fh,03Dh,003h,063h,05Dh,01Fh,021h,09Bh,0A5h,0E7h,0D9h,0F
6h
db 0C8h,08Ah,
0B4h,00Eh,030h,072h,04Ch,0EBh,0D5h,097h,0A9h,013h,02Dh,06Fh,051h,07Eh,04
0h,002h,03Ch,086h,0B8h,0FAh,0C4h,0A4h,09Ah,0D8h,0E6h,05Ch,062h,020h,01E
h,031h,00Fh
db
04Dh,073h,0C9h,0F7h,0B5h,08Bh,075h,04Bh,009h,037h,08Dh,0B3h,0F1h,0CFh,0
E0h,0DEh,09Ch,0A2h,018h,026h,064h,05Ah,03Ah,004h,046h,078h,0C2h,0FCh,0B
Eh,080h,0AFh, 091h,0D3h,0EDh
db
057h,069h,02Bh,015h,0FFh,000h,000h,000h,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0
FFh,0FFh,00Ch,031h,040h,000h,002h,000h,000h,000h,0FFh,0FFh,0FFh,0FFh,
0F0h,02Fh,040h,000h,000h,030h,040h,000h,0BBh
db
04Ch,0D9h,08Fh,044h,0B3h,026h,070h,000h,000h,000h,000h,000h,000h,000h,000
h

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

21

B32Chars
db
"@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy
z-@",0

Y despus de un buen rato, Brute-Forceando, nos vamos a tomar una Birra bien
fra y unas tapas, y al volver vemos que nos da este Password vlido:->

wmnpexandh

Lo metemos a la consola as:

Le damos a Enter y vemos esto:

? Rompe la consola totalmente ! Vamos a ver si hemos pasado los 2 Checks y que
est pasando para que pase esto.
Abrimos el Olly y metemos los mismos datos que arriba y parados en los controles,
aqu:

Miramos EAX:

Nuestro Password ha pasado con xito el 1 control, y vemos aqu el segundo:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

22

Miramos ese HASH de Byte en:

Nuestro Password ha pasado con xito el 2 control, y traceamos hasta llegar aqu:

Esto pinta mal ! Una llamada a VirtualProtect para , seguimos hasta llegar
aqu:
004016E2 |> /8B45 F4
CrackNiv.00401594

/MOV EAX,[LOCAL.3]

004016E5 |. |0FB600

|MOVZX EAX,BYTE PTR DS:[EAX]

004016E8 |. |83F0 D8

|XOR EAX,FFFFFFD8

004016EB |. |0FBEC0

|MOVSX EAX,AL

004016EE |. |8945 D4

|MOV [LOCAL.11],EAX

004016F1 |. |8B55 F0

|MOV EDX,[LOCAL.4]

004016F4 |. |8B45 08

|MOV EAX,[ARG.1]

004016F7 |. |01D0
ntdll.KiFastSystemCallRet

|ADD EAX,EDX

004016F9 |. |0FB600

|MOVZX EAX,BYTE PTR DS:[EAX]

004016FC |. |83F0 D8

|XOR EAX,FFFFFFD8

004016FF |. |0FBEC0

|MOVSX EAX,AL

00401702 |. |8945 EC

|MOV [LOCAL.5],EAX

00401705 |. |837D F0 00
00401709 |. |75 04

|CMP [LOCAL.4],0
|JNZ SHORT CrackNiv.0040170F

0040170B |. |8345 EC 2D

|ADD [LOCAL.5],2D

0040170F |> |837D F0 01

|CMP [LOCAL.4],1

00401713 |. |75 04

|JNZ SHORT CrackNiv.00401719

00401715 |. |836D EC 11

|SUB [LOCAL.5],11

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

23

00401719 |> |837D F0 02


0040171D |. |75 04

|CMP [LOCAL.4],2
|JNZ SHORT CrackNiv.00401723

0040171F |. |8345 EC 4C

|ADD [LOCAL.5],4C

00401723 |> |837D F0 03

|CMP [LOCAL.4],3

00401727 |. |75 04

|JNZ SHORT CrackNiv.0040172D

00401729 |. |8345 EC 4B

|ADD [LOCAL.5],4B

0040172D |> |837D F0 04

|CMP [LOCAL.4],4

00401731 |. |75 04

|JNZ SHORT CrackNiv.00401737

00401733 |. |8345 EC 46

|ADD [LOCAL.5],46

00401737 |> |837D F0 05

|CMP [LOCAL.4],5

0040173B |. |75 04

|JNZ SHORT CrackNiv.00401741

0040173D |. |8345 EC 1D

|ADD [LOCAL.5],1D

00401741 |> |837D F0 06

|CMP [LOCAL.4],6

00401745 |. |75 04

|JNZ SHORT CrackNiv.0040174B

00401747 |. |8345 EC 12

|ADD [LOCAL.5],12

0040174B |> |837D F0 07

|CMP [LOCAL.4],7

0040174F |. |75 07

|JNZ SHORT CrackNiv.00401758

00401751 |. |8145 EC 9F000000


00401758 |> |837D F0 08
0040175C |. |75 04

|ADD [LOCAL.5],9F
|CMP [LOCAL.4],8

|JNZ SHORT CrackNiv.00401762

0040175E |. |836D EC 2E

|SUB [LOCAL.5],2E

00401762 |> |837D F0 09

|CMP [LOCAL.4],9

00401766 |. |75 04

|JNZ SHORT CrackNiv.0040176C

00401768 |. |8345 EC 3A

|ADD [LOCAL.5],3A

0040176C |> |8B45 EC


msvcrt.77C11854

|MOV EAX,[LOCAL.5]

0040176F |. |89C2

|MOV EDX,EAX

00401771 |. |8B45 F4
CrackNiv.00401594

|MOV EAX,[LOCAL.3]

00401774 |. |8810

|MOV BYTE PTR DS:[EAX],DL

00401776 |. |8345 F4 01

|ADD [LOCAL.3],1

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

24

0040177A |. |8B45 D4
msvcrt.77C0B991

|MOV EAX,[LOCAL.11]

0040177D |. |0145 E8

|ADD [LOCAL.6],EAX

00401780 |. |8345 F0 01

|ADD [LOCAL.4],1

00401784 |> |837D F0 09

CMP [LOCAL.4],9

00401788 |.^\0F8E 54FFFFFF

\JLE CrackNiv.004016E2

0040178E |> 90

NOP

0040178F |> C9

LEAVE

Y un RETN, todo eso lo que hace es con permisos por la llamada a


VirtualProtect es escribir un total de 10 Bytes, los del Password introducido y a
Fuego meterlo en el cdigo, y lo vemos saliendo del bucle y caemos aqu:

Vemos marcado los 10 Bytes sin sentido, aqu le escrib a Sylkat y como era de
esperar me respondi muy amablemente y gran persona, le coment que aqu tena
que ir algo, y me dijo que era un tipo de JMP o CALL a una zona donde se
supone que se dan permisos de root, le coment que un Brute-Force era inviable
al tener 3 controles, hemos pasados 2, pero el 3 que escriba unos 10 Bytes con
sentido, eso sucedera cuando el hombre haya evolucionado a una Ente superior y
el Universo sea solo un espacio para 01010100, en resumen, para encontrar el
Password que Sylkat puso para pasar los 3 controles ser siendo un misterio hasta
hoy, debido que son HASH Hard-Codeados, por eso nosotros, parados aqu con el
Olly, debemos obtener el Cdigo Fuente sin parchear nada, as que nos vamos a
una Zona que me llamo la atencin y es esta:
004017FD /$ 55
004017FE |. 89E5
00401800 |. 83EC 28

PUSH EBP
MOV EBP,ESP
SUB ESP,28

00401803 |. C745 F0 DC70C500


;|

MOV [LOCAL.4],0C570DC

0040180A |. C74424 04 70724300


SS:[ESP+4],CrackNiv.00437270

MOV DWORD PTR


; |ASCII "cr4ckn1v4L_1.cpp"

00401812 |. 8B45 08
MOV EAX,[ARG.1]
|CrackNiv.<ModuleEntryPoint>

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

25

00401815 |. 890424
;|

MOV DWORD PTR SS:[ESP],EAX

00401818 |. E8 4B180000
; \strcmp

CALL <JMP.&msvcrt.strcmp>

0040181D |. 85C0

TEST EAX,EAX

0040181F |. 75 41

JNZ SHORT CrackNiv.00401862

00401821 |. C745 F4 00000000


00401828 |. EB 2F

MOV [LOCAL.3],0

JMP SHORT CrackNiv.00401859

0040182A |> 8B45 F4


kernel32.7C8399F3

/MOV EAX,[LOCAL.3]

0040182D |. 8B0485 40404000


DS:[EAX*4+404040]
00401834 |. 83F8 FF
00401837 |. 75 03
00401839 |. 90

|MOV EAX,DWORD PTR


|CMP EAX,-1

|JNZ SHORT CrackNiv.0040183C


|NOP

0040183A |. EB 26

|JMP SHORT CrackNiv.00401862

0040183C |> 8B45 F4


kernel32.7C8399F3

|MOV EAX,[LOCAL.3]

0040183F |. 8B0485 40404000


DS:[EAX*4+404040]
00401846 |. 3345 F0
00401849 |. 89C2

|MOV EAX,DWORD PTR

|MOV EDX,EAX
|MOV EAX,[LOCAL.3]

0040184E |. 891485 40404000


DS:[EAX*4+404040],EDX

|ADD [LOCAL.3],1
CMP [LOCAL.3],98967F

\JLE SHORT CrackNiv.0040182A

00401862 |> C74424 04 81724300


SS:[ESP+4],CrackNiv.00437281

MOV DWORD PTR


; |ASCII "cr4ckn1v4L_2.cpp"

0040186A |. 8B45 08
MOV EAX,[ARG.1]
|CrackNiv.<ModuleEntryPoint>
0040186D |. 890424
;|

|MOV DWORD PTR


; ntdll.KiFastSystemCallRet

00401859 |> 817D F4 7F969800


00401860 |.^ 7E C8

|XOR EAX,[LOCAL.4]

0040184B |. 8B45 F4
kernel32.7C8399F3

00401855 |. 8345 F4 01

MOV DWORD PTR SS:[ESP],EAX

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

26

00401870 |. E8 F3170000
; \strcmp

CALL <JMP.&msvcrt.strcmp>

00401875 |. 85C0

TEST EAX,EAX

00401877 |. 75 48

JNZ SHORT CrackNiv.004018C1

00401879 |. C745 F0 54DA710E


00401880 |. C745 F4 00000000
00401887 |. EB 2F

MOV [LOCAL.3],0

JMP SHORT CrackNiv.004018B8

00401889 |> 8B45 F4


kernel32.7C8399F3

/MOV EAX,[LOCAL.3]

0040188C |. 8B0485 C02B4100


DS:[EAX*4+412BC0]
00401893 |. 83F8 FF

|MOV EAX,DWORD PTR

|JNZ SHORT CrackNiv.0040189B

00401898 |. 90

|NOP

00401899 |. EB 26

|JMP SHORT CrackNiv.004018C1

0040189B |> 8B45 F4


kernel32.7C8399F3

|MOV EAX,[LOCAL.3]

0040189E |. 8B0485 C02B4100


DS:[EAX*4+412BC0]
004018A5 |. 3345 F0

|MOV EAX,DWORD PTR

|XOR EAX,[LOCAL.4]

004018A8 |. 89C2

|MOV EDX,EAX

004018AA |. 8B45 F4
kernel32.7C8399F3

|MOV EAX,[LOCAL.3]

004018AD |. 891485 C02B4100


DS:[EAX*4+412BC0],EDX
004018B4 |. 8345 F4 01

|MOV DWORD PTR


; ntdll.KiFastSystemCallRet
|ADD [LOCAL.3],1

004018B8 |> 817D F4 7F969800

CMP [LOCAL.3],98967F

\JLE SHORT CrackNiv.00401889

004018C1 |> C74424 04 92724300


SS:[ESP+4],CrackNiv.00437292

MOV DWORD PTR


; |ASCII "cr4ckn1v4L_3.cpp"

004018C9 |. 8B45 08
MOV EAX,[ARG.1]
|CrackNiv.<ModuleEntryPoint>
004018CC |. 890424
;|

|CMP EAX,-1

00401896 |. 75 03

004018BF |.^ 7E C8

MOV [LOCAL.4],0E71DA54

MOV DWORD PTR SS:[ESP],EAX

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

27

004018CF |. E8 94170000
; \strcmp

CALL <JMP.&msvcrt.strcmp>

004018D4 |. 85C0

TEST EAX,EAX

004018D6 |. 75 48

JNZ SHORT CrackNiv.00401920

004018D8 |. C745 F0 E9E8D002


004018DF |. C745 F4 00000000
004018E6 |. EB 2F

MOV [LOCAL.3],0

JMP SHORT CrackNiv.00401917

004018E8 |> 8B45 F4


kernel32.7C8399F3

/MOV EAX,[LOCAL.3]

004018EB |. 8B0485 80784200


DS:[EAX*4+427880]
004018F2 |. 83F8 FF
004018F5 |. 75 03
004018F7 |. 90

|MOV EAX,DWORD PTR

|JNZ SHORT CrackNiv.004018FA


|NOP
|JMP SHORT CrackNiv.00401920

004018FA |> 8B45 F4


kernel32.7C8399F3

|MOV EAX,[LOCAL.3]

004018FD |. 8B0485 80784200


DS:[EAX*4+427880]
00401904 |. 3345 F0

|MOV EAX,DWORD PTR

|MOV EDX,EAX
|MOV EAX,[LOCAL.3]

0040190C |. 891485 80784200


DS:[EAX*4+427880],EDX

00401920 |> C9
00401921 \. C3

|MOV DWORD PTR


; ntdll.KiFastSystemCallRet
|ADD [LOCAL.3],1

00401917 |> 817D F4 7F969800


0040191E |.^ 7E C8

|XOR EAX,[LOCAL.4]

00401909 |. 8B45 F4
kernel32.7C8399F3

00401913 |. 8345 F4 01

|CMP EAX,-1

004018F8 |. EB 26

00401907 |. 89C2

MOV [LOCAL.4],2D0E8E9

CMP [LOCAL.3],98967F

\JLE SHORT CrackNiv.004018E8


LEAVE
RETN

Le decimos al Olly New Origin Here :

004017FD /$ 55

PUSH EBP

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

28

Y traceamos hasta aqu:

Miramos el Buffer:

Y aqu tenemos que no salirnos, aqu:

Evitamos que salte y caemos aqu:

Estamos en un Bucle Caliente que nos va a sacar el Cdigo Fuente desde 00404040,
del primer reto, pasamos todo con un BP al salir del JLE y vemos esto en el
Dump:>

Ah lo tenemos !!

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

29

Y para que nos lo muestre en la consola, haremos directamente un New Origin


here en Olly:

Y aqu igual no saltar en el TEST EAX;EAX y BP al salir y vemos esto en la


consola:

Copiamos todo el texto a un *.cpp quedando as:


#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

30

#include <psapi.h>
#include <excpt.h>

HINSTANCE hInst;
char userBuffer[16];
char keyBuffer[16];
char passwordBuffer[16];
char passwordZip[16];
int validate();
int list_processes( void );
void PrintProcessNameAndID( DWORD );
void getPasswordZip();

char *cls="...hello.cls..;)..";

BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam,


LPARAM lParam)
{
HWND handle;

switch(uMsg)
{
case WM_INITDIALOG:
{
}
return TRUE;

case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

31

return TRUE;

case WM_COMMAND:
{
//printf("Hello world window gui:%d\n",wParam);
switch(LOWORD(wParam))
{
case IDOK:
//list_processes();
handle=GetDlgItem(hwndDlg, PASS_TEXT);
GetWindowText(handle,keyBuffer,11);
handle=GetDlgItem(hwndDlg, USER_TEXT);
GetWindowText(handle,userBuffer,11);
handle=GetDlgItem(hwndDlg, CODE_NEXT_CRACK);
strcpy(passwordBuffer,"User:");
strcat(passwordBuffer,userBuffer);
if(validate()){
MessageBox(NULL, "Key incorrect :(", "Aissshh", NULL);
}else{
getPasswordZip();
MessageBox(NULL, "You did it ;)", passwordZip, NULL);
SetWindowText(handle,passwordZip);
}
break;
case 2:
break;
}
}
return TRUE;
}
return FALSE;

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

32

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,


LPSTR lpCmdLi
ne, int nShowCmd)
{
hInst=hInstance;
InitCommonControls();
return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL,
(DLGPROC)DlgMain);
}

int validate(){
char *buffer=".hot.hot.hot.";
int i=0;
for(i=0;i<10;i++){
passwordBuffer[i]=userBuffer[i]-1;
}
passwordBuffer[i]='\0';
//printf("%s\n%s\n",passwordBuffer,keyBuffer);
if(strcmp(passwordBuffer,keyBuffer)){
return 1;
}else{
return 0;
}
}

void getPasswordZip(){
char *palermo=".palermo.te.espera.";
int i;

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

33

char tmp;
passwordZip[0]='\0';
for(i=0;i<10;i++){
tmp=userBuffer[i]-passwordBuffer[i]+((i*i)/2);
sprintf(passwordZip,"%s%d",passwordZip,tmp);
//printf("%s\n",passwordZip);
}
passwordZip[i]='\0';
}
Seguimos, con el segundo, New Origin here en Olly aqu:

Aqu como antes, evitar que nos saque el JNZ y BP al salir y luego nos vamos a que
lo muestre aqu:
004019CA |> \C74424 04 81724300
SS:[ESP+4],CrackNiv.00437281

MOV DWORD PTR


; |ASCII "cr4ckn1v4L_2.cpp"

Aqu cabe decir que Sylkat no tuvo en cuenta un detalle, lo cantidad de bytes del
segundo *.cpp es muy alta y la CMD de Windows tiene un buffer de mximo, y no
los muestra todos, por eso haremos un truco, solo que en vez de golpe, haremos
poco a poco todos los Bytes para poder ser copiados, haba una Funcin en el cdigo
para escribir datos, pero lo haremos as es ms limpio, si nos fijamos aqu:
00401A12 |> \817D F4 7F969800

CMP [LOCAL.3],98967F

Es == 0x1000h ser la constante para mostrar el cdigo en la consola CMD,


paramos cuando llegue a esa cantidad, la forma de hacerlo la que prefieran, la
cuestin es que se incremente en 1000h, 2000h, etc hasta ver el final de todo el
Cdigo Fuente, una vez terminado vemos esto:
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "resource.h"
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
#include <excpt.h>

HINSTANCE hInst;
Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

34

int list_processes( void );


int PrintProcessNameAndID( DWORD );
inline void ErasePEHeaderFromMemory();
inline bool HideThread(HANDLE);
bool CheckForCCBreakpointXor55(void*, size_t);
int CheckHardwareBreakpoints();
void getZip();
int pruebas();
int validate();
int OLLY_DETECTED=0;
int SBP_DETECTED=0;
int HBP_DETECTED=0;
int NOT_ALLOW=0;
char userBuffer[16];
char keyBuffer[16];
char passwordBuffer[16];
char passwordZip[16];

BOOL CALLBACK DlgMain(HWND hwndDlg, UINT uMsg, WPARAM wParam,


LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
{
list_processes();
CheckHardwareBreakpoints();
int sizeCode=(int)&pruebas-(int)&DlgMain;
CheckForCCBreakpointXor55((void*)DlgMain,sizeCode);
}
return TRUE;

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

35

case WM_CLOSE:
{
EndDialog(hwndDlg, 0);
}
return TRUE;

case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDOK:

HERE_WE_ARE:

HWND hCheck = GetDlgItem(hwndDlg, CHECK_BOX_PROCESS);

hCheck = GetDlgItem(hwndDlg, CHECK_BOX_ALL_OK);


PostMessage(hCheck, BM_SETCHECK,BST_UNCHECKED,0);
if(list_processes()){
hCheck = GetDlgItem(hwndDlg, CHECK_BOX_PROCESS);
PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
hCheck = GetDlgItem(hwndDlg, CHECK_BOX_ALL_OK);
PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
}else{
PostMessage(hCheck, BM_SETCHECK,BST_UNCHECKED,0);
}

hCheck = GetDlgItem(hwndDlg, CHECK_BOX_HARD_BP);


if(CheckHardwareBreakpoints()>0){
PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
hCheck = GetDlgItem(hwndDlg, CHECK_BOX_ALL_OK);

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

36

PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
}else{
PostMessage(hCheck, BM_SETCHECK,BST_UNCHECKED,0);
}

hCheck = GetDlgItem(hwndDlg, CHECK_BOX_SOFT_BP);


int sizeCode=(int)&pruebas-(int)&DlgMain;
if(CheckForCCBreakpointXor55((void*)DlgMain,sizeCode)){
PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
//hCheck = GetDlgItem(hwndDlg, CHECK_BOX_ALL_OK);
//PostMessage(hCheck, BM_SETCHECK,BST_PUSHED,0);
}else{
PostMessage(hCheck, BM_SETCHECK,BST_UNCHECKED,0);
}
HWND handle=GetDlgItem(hwndDlg, PASS_TEXT);
GetWindowText(handle,keyBuffer,16);
handle=GetDlgItem(hwndDlg, USER_TEXT);
GetWindowText(handle,userBuffer,11);
if(validate()==0){
getZip();
char buffer[256];
strcpy(buffer,"Zip password: ");
strcat(buffer,passwordZip);
MessageBox(NULL, buffer, "1nf0", NULL);
}else{
MessageBox(NULL, "Bad boy XD", "1nf0", NULL);
}

break;
}
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

37

return TRUE;
}
return FALSE;
}

int validate(){
int i=0,e;
e=OLLY_DETECTED+SBP_DETECTED+HBP_DETECTED+NOT_ALLOW;
e=0;
int value=32;
int idxUser=0;
SBP_DETECTED=0;
HBP_DETECTED=0;
NOT_ALLOW=0;
//kryzoxyzzz
//-KQ-ZW-JQ-\Y-W_
for(i=0;i<15;i++){

if(i%3==0){
if(keyBuffer[i]!='-'){
//printf("Not detected sep: %c\n",keyBuffer[i]);
e++;
}
continue;
}else if(i==1){
if(keyBuffer[i]!=userBuffer[idxUser]-value+OLLY_DETECTED){
//printf("1-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==2){
value=33;

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

38

if(keyBuffer[i]!=userBuffer[idxUser]-value+SBP_DETECTED){
//printf("2-%c-->%c\n",userBuffer[idxUser]-value,keyBuffer[i
]);
e++;

}
}else if(i==4){
value=31;
if(keyBuffer[i]!=userBuffer[idxUser]-value+HBP_DETECTED){
//printf("3-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==5){
value=35;
if(keyBuffer[i]!=userBuffer[idxUser]-value+NOT_ALLOW){
//printf("4-%c\n",userBuffer[idxUser]-value+NOT_ALLOW);
e++;
}
}else if(i==7){
value=37;
if(keyBuffer[i]!=userBuffer[idxUser]-value-NOT_ALLOW){
//printf("5-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==8){
value=39;
if(keyBuffer[i]!=userBuffer[idxUser]-value-OLLY_DETECTED){
//printf("6-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==10){

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

39

value=29;
if(keyBuffer[i]!=userBuffer[idxUser]-value-SBP_DETECTED){
//printf("7-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==11){
value=33;
if(keyBuffer[i]!=userBuffer[idxUser]-value+HBP_DETECTED){
e++;
//printf("8-%c\n",userBuffer[idxUser]-value);
}
}else if(i==13){
value=35;
if(keyBuffer[i]!=userBuffer[idxUser]-value+NOT_ALLOW){
//printf("9-%c\n",userBuffer[idxUser]-value);
e++;
}
}else if(i==14){
value=27;
if(keyBuffer[i]!=userBuffer[idxUser]-value){
//printf("10-%c--->%c\n",userBuffer[idxUser]-value,keyBuf
[i]);
e++;
}
}
idxUser++;
}
//printf("Errors:%d\n",e);
return e;
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

40

void getZip(){
int manyints[10];
int clsints[10];
int idxUser=0;
int i=0;
for(i=0;i<15;i++){
if(i%3==0){
continue;
}else{
manyints[idxUser]=userBuffer[idxUser]-keyBuffer[i]+20;
printf("KeyZip:%d\n",manyints[idxUser]);
}
idxUser++;
}
manyints[0]=manyints[0]-7;
manyints[1]=manyints[1]+14;
manyints[2]=manyints[2]+25;
manyints[3]=manyints[3]+28;
manyints[4]=manyints[4]-12;
manyints[5]=manyints[5]-9;
manyints[6]=manyints[6]-1;
manyints[7]=manyints[7]-4;
manyints[8]=manyints[8]-1;
manyints[9]=manyints[9]-1;
printf("\n");
passwordZip[0]='\0';
for(i=0;i<10;i++){
sprintf(passwordZip,"%s%c",passwordZip,manyints[i]);
printf("KeyZip:%c\n",manyints[i]);
idxUser++;
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

41

printf("Password zip: %s\n",passwordZip);


}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,


LPSTR lpCm
ne, int nShowCmd)
{
hInst=hInstance;
InitCommonControls();
return DialogBox(hInst, MAKEINTRESOURCE(DLG_MAIN), NULL,
(DLGPROC)DlgMain
}

// CheckHardwareBreakpoints returns the number of hardware


// breakpoints detected and on failure it returns -1.
int CheckHardwareBreakpoints()
{

unsigned int NumBps = 0;


HBP_DETECTED=NumBps;
// This structure is key to the function and is the
// medium for detection and removal
CONTEXT ctx;
ZeroMemory(&ctx, sizeof(CONTEXT));

// The CONTEXT structure is an in/out parameter therefore we have


// to set the flags so Get/SetThreadContext knows what to set or get.
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;

// Get a handle to our thread

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

42

HANDLE hThread = GetCurrentThread();

// Get the registers


if(GetThreadContext(hThread, &ctx) == 0)
return -1;

// Now we can check for hardware breakpoints, its not


// necessary to check Dr6 and Dr7, however feel free to
if(ctx.Dr0 != 0)
++NumBps;
if(ctx.Dr1 != 0)
++NumBps;
if(ctx.Dr2 != 0)
++NumBps;
if(ctx.Dr3 != 0)
++NumBps;
if(NumBps>0){
HBP_DETECTED=NumBps;
NOT_ALLOW+=1;
}
return NumBps;
}

// HideThread will attempt to use


// NtSetInformationThread to hide a thread
// from the debugger, Passing NULL for
// hThread will cause the function to hide the thread
// the function is running in. Also, the function returns
// false on failure and true on success
inline bool HideThread(HANDLE hThread)
{

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

43

/*
typedef NTSTATUS (NTAPI *pNtSetInformationThread)
//

(HANDLE, UINT, PVOID, ULONG);

NTSTATUS Status;

// Get NtSetInformationThread
pNtSetInformationThread NtSIT = (pNtSetInformationThread)
GetProcAddress(GetModuleHandle( TEXT("ntdll.dll") ),
"NtSetInformationThread");

// Shouldn't fail
if (NtSIT == NULL)
return false;

// Set the thread info


if (hThread == NULL)
Status = NtSIT(GetCurrentThread(),
0x11, // HideThreadFromDebugger
0, 0);
else
Status = NtSIT(hThread, 0x11, 0, 0);

if (Status != 0x00000000)
return false;
else
return true;
*/
}

// This function will erase the current images


// PE header from memory preventing a successful image

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

44

// if dumped
inline void ErasePEHeaderFromMemory()
{
DWORD OldProtect = 0;

// Get base address of module


char *pBaseAddr = (char*)GetModuleHandle(NULL);

// Change memory protection


VirtualProtect(pBaseAddr, 4096, // Assume x86 page size
PAGE_READWRITE, &OldProtect);

// Erase the header


ZeroMemory(pBaseAddr, 4096);
}
int PrintProcessNameAndID( DWORD processID )
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;

if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),&cbNeeded) )


{
GetModuleBaseName( hProcess, hMod, szProcessName,

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

45

sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Print the process name and identifier.
//_tprintf( TEXT("%s (PID: %u)\n"), szProcessName, processID );
// Release the handle to the process.
CloseHandle( hProcess );
//int resCmp=strcmp(szProcessName,"OLLYDBG.exe");
//printf("STRCMP RES%d\n",resCmp);
if(!strcmp(szProcessName,"OLLYDBG")){
NOT_ALLOW=1;
OLLY_DETECTED+=1;
return 1;
}
if(!strcmp(szProcessName,"ollydbg")){
NOT_ALLOW=1;
OLLY_DETECTED+=1;
return 1;
}
if(!strcmp(szProcessName,"ollydbg.exe")){
NOT_ALLOW=1;
OLLY_DETECTED+=1;
return 1;
}
if(!strcmp(szProcessName,"OLLYDBG.EXE")){
NOT_ALLOW=1;
OLLY_DETECTED+=1;
return 1;
}
return 0;
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

46

int list_processes( void )


{
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
int found=0;

if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )


{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the name and process identifier for each process.
for ( i = 0; i < cProcesses; i++ )
{
if(i==0){
OLLY_DETECTED=i;
}
if( aProcesses[i] != 0 )
{
found=PrintProcessNameAndID( aProcesses[i] );
if(found==1){
return 1;
}
}
}
return found;
}

int pruebas(){

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

47

return 1;
}

bool CheckForCCBreakpointXor55(void* pMemory, size_t SizeToCheck)


{
unsigned char *pTmp = (unsigned char*)pMemory;
unsigned char tmpchar = 0;
SBP_DETECTED=tmpchar;
for (size_t i = 0; i < SizeToCheck; i++)
{
tmpchar = pTmp[i];
if( 0x99 == (tmpchar ^ 0x55) ){

if(i==2466 || i==2260|| i==2472|| i==2770|| i==2472|| i==2260|| i==2


472){
//printf("!!!!!!!!!!!!!!!!!!Detected soft BP at offset:%x\n",i);

continue;
}

//printf("Detected soft BP at offset:%x,%d\n",&pTmp[i],i);


NOT_ALLOW+=1;
SBP_DETECTED+=1;
return true;
} // 0xCC xor 0x55 = 0x99
}
return false;
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

48

Y hacemos igual para el tercer y ltimo *.CPP y vemos esto:


#include <errno.h>
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>
#include <excpt.h>
#include "crackme_4.h"

void do_login();
void cypher();
void decypher(char *);
void you_did_it(char *);
void register_exit();
void printNoo();
int getSum(char*);
void writeFileIntoHeaderFileSource(char *,int );
void printSourceCode(char *file);
void emulateSystemShell();
void decryptSouceCode(char *);

char buffer[60];
char source_1[]="cr4ckn1v4L_1.cpp";
char source_2[]="cr4ckn1v4L_2.cpp";
char source_3[]="cr4ckn1v4L_3.cpp";

char USER[50];

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

49

unsigned crc8(unsigned, unsigned char *, size_t);

int main(int argc, char **argv){


//writeFileIntoHeaderFileSource(source_1,12939484);
//writeFileIntoHeaderFileSource(source_2,242342484);
//writeFileIntoHeaderFileSource(source_3,47245545);
strcpy(USER,"guest");
emulateSystemShell();
//printSourceCode(source_1);
exit(0);
while(1){
do_login();
}
}

void register_exit(){
strcpy(USER,"root");
decryptSouceCode(source_1);
decryptSouceCode(source_2);
decryptSouceCode(source_3);
//exit(0);
}

void printNoo(){
printf("\nAccess denied\n");
}

void you_did_it(char *password){


//printf("Hi function pointer did it.");
decypher(password);
printNoo();

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

50

}
void do_login(){
//char *stackvar="AAAAAAAAAAAAAAAAA";
char name[20];
void (*fptr)(char *)=you_did_it;
char password[20];
//asfasfd=cypher;

printf("\n User:");
void (*fptr2)(char *)=you_did_it;
gets(name);
printf(" Password:");
gets(password);
//printf("\nAddress You did it
//printf("Address Register

: %x\n",you_did_it);

: %x\n",register_exit);

//printf("Address Point function: %x\n",fptr);


fptr(password);
}

void decypher(char *phrase){


//void *page = (void *) ((unsigned long) (&&checkpoint) & ~(getpagesize(
) - 1));
int res=0;
char *cyphFunction=(char*)you_did_it;
//printf("Address cyphFunction : %x\n",&cyphFunction);
//printf("Address Point function: %x\n",cyphFunction);
//printf("Value at address: %d\n",*cyphFunction);
//printf("Page Size:%d\n",getpagesize());

if(res==-1){
printf("Result mprotect: %d\n",errno);

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

51

perror("Error:");
return;
}
cyphFunction+=17;
int idx=0;
int xorEd;
int passxor;
int sumReal=0;
int sumPas=0;
unsigned int crcsum=crc8(9, (unsigned char*) phrase, 10);
//printf("Crc is: %u\n",crcsum);
if(getSum(phrase)==1082 && crcsum==183){
DWORD OldProtect = 0;
char *pBaseAddr = (char*)GetModuleHandle(NULL);
//printf("Changing permissions of memory from %x to %x\n",pBaseA
ddr, pBaseAddr+4096);
VirtualProtect(pBaseAddr, 4096*10, PAGE_READWRITE, &OldProtect);

for(idx=0;idx<10;idx++){
//printf("Value byte at addr-->%x:%d\n",cyphFunction,*cy
phFunction);
xorEd=*cyphFunction^-40;
passxor=phrase[idx]^-40;
if(idx==0){
passxor+=45;
}
if(idx==1){
passxor-=17;
}
if(idx==2){
passxor+=76;

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

52

}
if(idx==3){
passxor+=75;
}
if(idx==4){
passxor+=70;
}
if(idx==5){
passxor+=29;
}
if(idx==6){
passxor+=18;
}
if(idx==7){
passxor+=159;
}
if(idx==8){
passxor-=46;
}
if(idx==9){
passxor+=58;
}
//printf("Value password :(%d)%d\n",phrase[idx],passxor)
;
*cyphFunction=passxor;
cyphFunction++;
sumReal+=xorEd;
}
//printf("Final sum:%d\n",sumReal);
}
checkpoint:

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

53

return;
}
int getSum(char *password){
int idx,sumReal=0,passxor;
for(idx=0;idx<10;idx++){
if(idx==0 || idx==5){
passxor=password[idx]^-40;
}else{
passxor=password[idx]^40;
}
sumReal+=password[idx];
}
//printf("Final sum:%d\n",sumReal);
return sumReal;
}

void decryptSouceCode(char *file){


int i;
int key=12939484;
if(!strcmp(file,source_1)){
for(i=0;i<10000000;i++){
if(file_source_1[i]==EOF){
break;
}
file_source_1[i]=file_source_1[i]^key;

}
}
if(!strcmp(file,source_2)){
key=242342484;
for(i=0;i<10000000;i++){

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

54

if(file_source_2[i]==EOF){
break;
}
file_source_2[i]=file_source_2[i]^key;
}
}
if(!strcmp(file,source_3)){
key=47245545;
for(i=0;i<10000000;i++){
if(file_source_3[i]==EOF){
break;
}
file_source_3[i]=file_source_3[i]^key;
}
}
}

static unsigned char crc8_table[] = {


0x00, 0x3e, 0x7c, 0x42, 0xf8, 0xc6, 0x84, 0xba, 0x95, 0xab, 0xe9, 0xd7,
0x6d, 0x53, 0x11, 0x2f, 0x4f, 0x71, 0x33, 0x0d, 0xb7, 0x89, 0xcb, 0xf5,
0xda, 0xe4, 0xa6, 0x98, 0x22, 0x1c, 0x5e, 0x60, 0x9e, 0xa0, 0xe2, 0xdc,
0x66, 0x58, 0x1a, 0x24, 0x0b, 0x35, 0x77, 0x49, 0xf3, 0xcd, 0x8f, 0xb1,
0xd1, 0xef, 0xad, 0x93, 0x29, 0x17, 0x55, 0x6b, 0x44, 0x7a, 0x38, 0x06,
0xbc, 0x82, 0xc0, 0xfe, 0x59, 0x67, 0x25, 0x1b, 0xa1, 0x9f, 0xdd, 0xe3,
0xcc, 0xf2, 0xb0, 0x8e, 0x34, 0x0a, 0x48, 0x76, 0x16, 0x28, 0x6a, 0x54,
0xee, 0xd0, 0x92, 0xac, 0x83, 0xbd, 0xff, 0xc1, 0x7b, 0x45, 0x07, 0x39,
0xc7, 0xf9, 0xbb, 0x85, 0x3f, 0x01, 0x43, 0x7d, 0x52, 0x6c, 0x2e, 0x10,
0xaa, 0x94, 0xd6, 0xe8, 0x88, 0xb6, 0xf4, 0xca, 0x70, 0x4e, 0x0c, 0x32,
0x1d, 0x23, 0x61, 0x5f, 0xe5, 0xdb, 0x99, 0xa7, 0xb2, 0x8c, 0xce, 0xf0,
0x4a, 0x74, 0x36, 0x08, 0x27, 0x19, 0x5b, 0x65, 0xdf, 0xe1, 0xa3, 0x9d,

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

55

0xfd, 0xc3, 0x81, 0xbf, 0x05, 0x3b, 0x79, 0x47, 0x68, 0x56, 0x14, 0x2a,
0x90, 0xae, 0xec, 0xd2, 0x2c, 0x12, 0x50, 0x6e, 0xd4, 0xea, 0xa8, 0x96,
0xb9, 0x87, 0xc5, 0xfb, 0x41, 0x7f, 0x3d, 0x03, 0x63, 0x5d, 0x1f, 0x21,
0x9b, 0xa5, 0xe7, 0xd9, 0xf6, 0xc8, 0x8a, 0xb4, 0x0e, 0x30, 0x72, 0x4c,
0xeb, 0xd5, 0x97, 0xa9, 0x13, 0x2d, 0x6f, 0x51, 0x7e, 0x40, 0x02, 0x3c,
0x86, 0xb8, 0xfa, 0xc4, 0xa4, 0x9a, 0xd8, 0xe6, 0x5c, 0x62, 0x20, 0x1e,
0x31, 0x0f, 0x4d, 0x73, 0xc9, 0xf7, 0xb5, 0x8b, 0x75, 0x4b, 0x09, 0x37,
0x8d, 0xb3, 0xf1, 0xcf, 0xe0, 0xde, 0x9c, 0xa2, 0x18, 0x26, 0x64, 0x5a,
0x3a, 0x04, 0x46, 0x78, 0xc2, 0xfc, 0xbe, 0x80, 0xaf, 0x91, 0xd3, 0xed,
0x57, 0x69, 0x2b, 0x15};

unsigned crc8(unsigned crc, unsigned char *data, size_t len)


{
unsigned char *end;

if (len == 0)
return crc;
crc ^= 0xff;
end = data + len;
do {
crc = crc8_table[crc ^ *data++];
} while (data < end);
return crc ^ 0xff;
}

void printSourceCode(char *file){


int i;
if(!strcmp(file,source_1)){
for(i=0;i<10000000;i++){
printf("%c",file_source_1[i]);
if(file_source_1[i]==EOF){

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

56

break;
}
}
}
if(!strcmp(file,source_2)){
for(i=0;i<10000000;i++){
printf("%c",file_source_2[i]);
if(file_source_2[i]==EOF){
break;
}
}
}
if(!strcmp(file,source_3)){
for(i=0;i<10000000;i++){
printf("%c",file_source_3[i]);
if(file_source_3[i]==EOF){
break;
}
}
}
}

void writeFileIntoHeaderFileSource(char *fileName, int key){


char fileNameHeader[256];
strcpy(fileNameHeader,fileName);
strcat(fileNameHeader,".h");
int byte;
FILE *file=fopen(fileName,"r");
FILE *fileHeader=fopen(fileNameHeader,"w");
if(file==NULL || fileHeader==NULL){
printf("Error file %s is null.\n",fileName);

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

57

return;
}
fprintf(fileHeader,"int source={");
while (byte=fgetc(file)){
/* note that fgets don't strip the terminating \n, checking its
presence would allow to handle lines longer that sizeof(line) */
printf("%c", byte);
if(byte==EOF){
fprintf(fileHeader,"0x%x,",byte);
break;
}
byte=byte^key;
fprintf(fileHeader,"0x%x,",byte);
}
fprintf(fileHeader,"};");
fclose(fileHeader);
fclose(file);
}

void emulateSystemShell(){
int mode_response=0;
char shellHead[256];
strcpy(shellHead,USER);
strcat(shellHead," $ ");
printf("##################################\n");
printf("# Welcome to Cr4ckn1val Server #\n");
printf("#

Enjoy

#\n");

printf("##################################\n");
while(1==1){
strcpy(shellHead,USER);
strcat(shellHead," $ ");

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

58

printf(shellHead);
char response[256];
scanf("%255s",response);
if(!strcmp(response,"\n")){
mode_response=0;
continue;
}
if(!strcmp(response,"help") || !strcmp(response,"?") ){
printf("(s3cure sh3ll):\nls\ncat\nlogin\nid\nexit\n");
mode_response=0;
continue;
}
if(!strcmp(response,"dir") || !strcmp(response,"ls") ){
printf("%s\n%s\n%s\n",source_1,source_2,source_3);
mode_response=0;
continue;
}
if(!strcmp(response,"id")){
printf(USER);
printf("\n");
mode_response=0;
continue;
}
if(!strcmp(response,"login")){
gets(response);
do_login();
}
if(!strcmp(response,"exit")){
printf("Bye,");
exit(0);
}

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

59

if(!strcmp(response,"cat")){
mode_response=1;
continue;
}
if(!strcmp(response,source_1)){
if(mode_response==1){
if(!strcmp(USER,"root")){
printSourceCode(source_1);
}else{
printf("Access denied.\n");
}
}
mode_response=0;
continue;
}
if(!strcmp(response,source_2) ){
if(mode_response==1){
if(!strcmp(USER,"root")){

printSourceCode(source_2);
}else{
printf("Access denied.\n");
}
}
mode_response=0;
continue;
}
if(!strcmp(response,source_3) ){
if(mode_response==1){
if(!strcmp(USER,"root")){

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

60

printSourceCode(source_3);
}else{
printf("Access denied.\n");
}
}
mode_response=0;
continue;
}
//printf("'%s'",response);
}

}
Ah lo tenemos todo !
Ahora teniendo el cdigo fuente del 3 *.cpp le dejo al lector entender el cdigo en
C++ y ver si puede sacar el Password original que pens Sylkat

Nosotros hemos cumplido con los 3 retos sin parchear nada, y solo en el tercero
hemos hecho cambios en el EIP del binario para sacar los cdigos fuentes de los 3
proyectos.

Adjunto los 3 *.CPP y todo los binarios en un RAR para mayor comodidad.

Sin ms me despido con un cordial Saludo a toda la Lista de CLS, en especial a


Ricardo Narvaja, y mi agradecimiento a Eddy _/\_-=InDuLgEo=-_/\_ que sin su
ayuda cuando me quedaba bloqueado, este documento no hubiera visto nunca la
luz. Y como no, a Sylkat para proponer este Reto que ha sido muy entretenido y se
aprenden muchas cosas con ello. Gracias a todos, y t como lector gracias por leer
hasta aqu;)

D3m0n3vX

16/10/2016.-

Solucin_Al_Reto_Cracknival_1_2_y_3_Por_D3m0n3vX

61