Вы находитесь на странице: 1из 6

Pwnium @8.jul .

2014

Programming::Crackme fast += 300


by skuater, Longinos & Nox

[ Crackme fast ]

. Descripcin .

. Introduccin .
En la descripcin del reto nos muestra lo siguiente: Crackme Fast The
binary http://41.231.53.44:9393/ Send the password in less than 2 seconds
http://41.231.53.44:9393/check.php?p={p@55} .

Voy a enfatizar lo siguiente de la descripcin: Enviar la contrasea en


menos de dos segundos.

. Manos a la obra .

. Anlisis esttico .
Al conectarse a la direccin http://41.231.53.44:9393/ se descarga un
binario. Cada vez que nos conectados a esa direccin, tenemos un binario
diferente. Al abrirlo con un editor hexadecimal se muestra lo siguiente.

#1/6
by skuater, Longinos & Nox @ Programming::Crackme fast

Tenemos unos caracteres LPCK y luego le sigue un hash md5 que


finaliza con la extensin .exe. Probablemente es usado para identificacin de cada
binario servido. Ms abajo se observa los caracteres MZ, muy conocido
indicador de que se trata del formato PE, si se revisa la estructura con un vistazo,
se puede asegurar de que es un ejecutable para Windows. Entonces solo se
necesita eliminar los bytes hasta los caracteres MZ y tendremos un ejecutable
funcional.

Ahora, interactuamos con el binario, para ver si tenemos un chico malo.

C:\Documents and Settings\Administrador>"C:\Documents and


Settings\Administrador\Escritorio\file.exe"
Password :
989898
Sorry ! Incorrect pass

. Tiempo de IDA .
Abrimos el binario con IDA y buscamos la referencia de la cadena
Password :.

Al llegar a la referencia de la cadena aPassword como lo denomina IDA, se


puede observar que en la direccin 0x402000, hay un array de DWORDS de 8
tems de nombre array_dword_402000 , que es copiado a la variable local que
he nombrado key_hardcoded.

.data:00402000 ;org 402000h


.data:00402000 array_dword_402000 dd 'j', 'x', 'k', '4', 'A', 'J', 'x', '9'
.data:00402000 ; DATA XREF: sub_401334+15o

El array array_dword_402000 tiene los siguientes caracteres: jxk4AJx9.

.text:00401345 lea edx, [esp+5Ch+key_hardcoded]


.text:00401349 mov ebx, offset array_dword_402000
.text:0040134E mov eax, 8
.text:00401353 mov edi, edx
.text:00401355 mov esi, ebx
.text:00401357 mov ecx, eax

#2/6
Sigue la impresin en consola de la cadena Password :, y la peticin de
una contrasea a ingresar que es guardada en la variable local pass_in.
Finalmente se inicia un contador a 0 para comenzar con el bucle.

.text:00401359 rep movsd


.text:0040135B mov [esp+5Ch+var_10], 0
.text:00401363 mov [esp+5Ch+var_5C], offset aPassword ; "Password :"
.text:0040136A call puts
.text:0040136F lea eax, [esp+5Ch+pass_in]
.text:00401373 mov [esp+5Ch+var_58], eax
.text:00401377 mov [esp+5Ch+var_5C], offset aS ; "%s"
.text:0040137E call scanf
.text:00401383 mov [esp+5Ch+count], 0
.text:0040138B jmp short loc_4013B1

Luego, obtiene la longitud de la cadena en la direccin 0x4013BC. Si el


contador es mayor que la longitud, sale del bucle y nos manda al chico malo. Si
sigue en el bucle, obtiene cada tem del array array_dword_402000 (direccin
0x401391), operando cada byte con un XOR 1 (direccin 0x401397), guardando el
resultado en ECX. Y comparando byte a byte con la contrasea ingresada que la
contiene EAX para ver que coinciden (direccin 0x4013A9).

Finalmente si todos los caracteres de la contrasea que hemos ingresado


ha coincidido con todo los tems del array array_dword_402000, nos imprime al
chico bueno. Eso quiere decir que si hacemos un XOR 1, al array, obtendremos la
contrasea.

#3/6
by skuater, Longinos & Nox @ Programming::Crackme fast

>>> ''.join(chr(ord(c)^1) for c in 'jxk4AJx9')


'kyj5@Ky8'

Ingresamos la contrasea kyj5@Ky8, sin comillas, y

C:\Documents and Settings\Administrador>"C:\Documents and Settings\Administrador


\Escritorio\file.exe"
Password :
kyj5@Ky8
Good Boy ! Send That pass to server to get the Flag

Ya sabemos que el binario tiene una key hardcodeada1, y que opera con
una operacin lgica XOR. Si revisamos la cabecera de la seccin de datos,
RawAddress, es decir, el offset, dnde empieza la seccin en disco es 0x1200.

Sin embargo, debemos tener en cuenta, que al descargar el binario, este


tiene una informacin extra al inicio del archivo. Si abrimos el editor hexadecimal
del binario inicial, y observamos unos bytes, debajo de la direccin 0x1200,
encontraremos el offset dnde est nuestra key hardcodeada.

Envamos la contraseas como nos indica la descripcin,


http://41.231.53.44:9393/check.php?p=kyj5@Ky8, y extraamente no
obtenamos el Flag. Entonces supusimos que deberamos hacerlo en menos de
dos segundos como menciona la descripcin.

. Python .
Una vez establecido la lgica, debemos automatizar dichas acciones para
enviar la respuesta al servidor en menos de dos segundos, ya que ese es el
objetivo, y este nos devuelva el Flag.

Pero porque siempre hay uno , en primera instancia no recibamos


respuesta. Esto les pasaba a otros equipos, y entonces en el IRC del CTF,
mencionaron que necesitbamos crear una cookie. Tena sentido, era la manera
en que el servidor saba de qu binario vena la contrasea para devolver el Flag
correspondiente, ya que en cada conexin devolva uno diferente.

1
El termino key hardcodeada o key hardcoded, significa que la llave usada para la operacin
lgica XOR, fue fijada desde la programacin del reto tambin llamado constante .

#4/6
Sabiendo eso, se program el siguiente cdigo.

import cookielib
import urllib2
import urllib
import os
import sys

cookies = cookielib.LWPCookieJar()
handlers = [
urllib2.HTTPHandler(),
urllib2.HTTPSHandler(),
urllib2.HTTPCookieProcessor(cookies)
]
opener = urllib2.build_opener(*handlers)

def fetch(uri,parametros):
if len(parametros)>0:
req = urllib2.Request(uri,data=parametros)
else:
req = urllib2.Request(uri)
return opener.open(req)

def send_result(v):
params = {}
# params = urllib.urlencode(params)
uri = 'http://41.231.53.44:9393/check.php?p='+v
res = fetch(uri,params)
dump()
contenido=res.read()
return contenido

def Get_valor():
params = {}
uri = 'http://41.231.53.44:9393'
res = fetch(uri,params)
contenido=res.read()
myhash = contenido[0x1310:0x1330]
myhash2 = ""
for i in range(0, len(myhash), 4):
myhash2 += myhash[i:i+1]

myCadena = ''.join(chr(ord(c)^1) for c in myhash2)


return myCadena

valor=Get_valor()
print El Flag es: , send_result(valor)

Y finalmente, el servidor devuelv el Flag al enviar la contrasea del crackme


en menos de dos segundos.

#5/6
by skuater, Longinos & Nox @ Programming::Crackme fast

. Conclusin .

El reto estuvo bastante entretenido, y lo hicimos por partes, mientras yo


programaba todo el cdigo que obtena la contrasea del crackme, mi team mate,
programaba la creacin de la cookie. Eso es trabajo en equipo ;).

Se us IDA porque el anlisis en cdigo muerto es suficiente. Adems, IDA


da mucha informacin para hacer el anlisis amigable.

. La contrasea .

No guardamos el Flag .

A por el mundo!
Nox.

#6/6

Вам также может понравиться