25 marzo 2014

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:

image

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.

image

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:

image

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”:

image

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.

image

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:

image

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”.


Artículo cortesía de: Alberto García Illera

5 comments :

Code dijo...

ganas del siguiente capitulo!!

Bruno Cardenas Cyberoff dijo...

porque IV? si es PARTE 1 DE 3.1 ???

Alberto dijo...

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

Cheryl Ron dijo...

¿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

Migul dijo...

me olvide poner el nuevo CL-SECURITY =)


http://xxxxxxx.onion XD