Muy buenas a todos. En los
siguientes cuatro post expondré como resolví y posteriormente
conseguí ejecutar código en un reto de cracking
que me envió
un amigo. Escribí un writeup ya que me parece interesante la protección
“anti-cracking”
que tiene y sobretodo porque la ejecución de código no viene supeditada a un
buffer overflow (de ningún tipo),
format string, use
after-free o demás formas de explotación documentadas.
El writeup es largo
y por eso hemos decidido dividirlo en varias entregas ya que al ser un tema
denso con mucho ensamblado de por medio, es fácil perderse si se publicase del
tirón. La primera parte es la más corta y básica pero a partir de la segunda ya
se “intensifica” la questión.
Para los que no
tengan conocimientos previos de ensamblador recomiendo un paper muy claro y aclarador que escribió mi amigo, a pesar de ser del Barça, Daniel Romero hace cosa de un año. ¡Espero que os
guste!
1 Resolviendo el reto de forma “oficial”
1. Primer vistazo
Hace cosa de un mes
mi amigo y compi de trabajo Martín Vigo (@martin_vigo) me envió un reto de
reversing que había codeado un amigo suyo (http://www.iquilezles.org/).
El binario se puede descargar desde el siguiente link: http://goo.gl/tLKlsu
El reto consistía
en hacer que un binario de Windows compilado para x86 mostrara una ventana. Un
archivo png con dicha ventana venía adjunto al propio archivo del reto:

Lo más relevante de
esto, que podremos usar posteriormente, es el nombre de la ventana que podemos
ver que es “test_app”. Este nombre salvo que esté ofuscado o cifrado en el binario
puede darnos una idea de qué función debemos alcanzar para pintar dicha ventana
y por tanto solucionar el reto.
Lo primero que hice
fue ejecutar el binario para ver que ocurría y esta ventana es la que obtuve.

Por tanto, parece
ser que el binario está esperando, bien en un archivo o como argumento, una
licencia.
2. Strings y desensamblado
El siguiente paso
es cargar el binario en vuestro desensamblador favorito para ver que funciones
y librerías carga. En mi caso he usado IDA PRO:

Tenemos muy pocas
funciones, por lo que no debería ser demasiado difícil encontrar en el
ensamblado lo que el programa espera o
lo que está haciendo. Tras mirar los strings vemos que existe una referencia al
anterior nombre de ventana comentado “test_app”:

De algún modo
debemos conseguir que nuestro flujo de ejecución acceda a cierta parte del
ensamblado que lea esa dirección de memoria ya que será utilizado para crear la
ventana con la que resolveremos.
Rápidamente vemos
que el binario intenta leer un fichero de nombre “key.txt” en el mismo path
donde se encuentra el binario.

Podemos ver en la
documentación de CreateFileA (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx)
que se está usando el argumento 3 como “dwCreationDisposition”
por lo tanto solo se abrirá un descriptor del fichero en caso de que el archivo
exista.
Si el fichero
“key.txt” existe la función CreateFileA devolverá un descriptor del fichero en
el registro EAX. En caso de no existir devolverá FFFFFFFF y por tanto al hacer
INC EAX, OR EAX EAX, activará el flag ZF y saltará a “loc_402360”.
3. Debugueando y entendiendo el código
3.1 Crear la ventana
El primer objetivo
parece que será crear la ventana que presumiblemente tendrá el nombre
“test_app”. Para saber cómo hacerlo lo más cómodo es debuguear el binario.
Crearemos
un fichero “key.txt” cuyo contenido es “AAAAAAA”. Pondremos un breakpoint
tras el CALL a CreateFileA y enseguida llegamos
al segmento de código que realmente nos interesa:
He comentado un par
de detalles que nos interesan:
- El primer CALL es una llamada a la función ReadFile que toma 5 parámetros.
- El tercer parámetro pusheado es el número de bytes del fichero que se van a leer del fichero “key.txt”. En este caso solo 14h (20) bytes.
El resultado de la
lectura se almacena en una zona de memoria apuntada por ESI. Ahora veremos instrucción
a instrucción lo que se está haciendo:
- Se mueve 7A40B660 a EAX.
- Se suma a dicho valor lo existente en los primeros 4 bytes a los que apunta ESI que en este caso son los 4 primeros bytes de nuestro “key.txt” (“41414141” = “AAAA”). La suma se almacena en EAX.
- Se llama a la dirección resultante.
Por tanto los
primeros 4 bytes del fichero “key.txt” serán los que se utilizarán para decidir
a qué dirección haremos el CALL tras sumar “7A40B660”.
5 comments :
ganas del siguiente capitulo!!
porque IV? si es PARTE 1 DE 3.1 ???
Es una división interna del artículo. En el último post se publicará el paper entero en PDF y este se ha dividido para estar todo más ordenado.
Un saludo
¿Está buscando una muy rápida
Préstamo? en una
tasa de interés asequible? Ha
sido rechazadas
Constantemente por sus bancos y otras
financiero
instituciones?
-La buena noticia es aquí! Ofrecemos
préstamos que van
de $ 1,000.00 a $ 5,000,000.00 Min
Max en el 3%
tasa de interés por anule. contáctenos
hoy en (texcoloan24hours@fengv.com)
PRIMERA INFORMACIÓN necesarios son:
Nombre: .........
Otro Nombre (s): ........
Sexo: .........
Estado civil: .........
Dirección de contacto: .........
Ciudad / Código postal: .........
País: .........
Fecha de nacimiento: .........
Cantidad necesaria del préstamo: .........
Duración del préstamo: .........
Ingresos mensuales: .........
Ocupación: .........
Propósito para el préstamo: .........
House Teléfono: .........
Teléfono celular: .........
Saludos,
Sra. Marie
me olvide poner el nuevo CL-SECURITY =)
http://xxxxxxx.onion XD
Publicar un comentario