sábado, 14 de abril de 2012

[Crackme 1] - Alteración de cadenas (con Immunity Debugger)

Existen infinitas pruebas o crackmes por internet que siempre nos ayudan a entender los sistemas de protección que son utilizados por lo programas de hoy en día, y no menos importante a aprender cada día más y más sobre la ingeniería inversa.

NOTA: Si es la primera vez que te enfrentas a un reto o crackme y no dispones de conocimientos básicos en ingeniería inversa, recomiendo la lectura de la serie “Introducción a la Ingeniería Inversa en x86” que podéis encontrar en el apartado de Artículos.

Para el primer crackme he decidido comenzar por uno sencillo y sin mucha complicación, así es posible realizar la explicación mucho más detallada.

Descarga del fichero: [Crackme 1]
Escaneo del fichero (exe) en VirustTotal
MD5 (exe): 8703fe327565e59e2de6ec683eb5bc23
SHA1 (exe): c6f44af8fb6b1704065c8f70fb7f0e610781a7f3

IMPORTANTE: Siempre es bueno que probéis a resolver vosotros el crackme antes de leer la resolución.

Antes de nada, ejecutamos el binario para ver qué es y qué nos pide.

image

El funcionamiento es muy simple, nos están pidiendo que introduzcamos una cadena, la cual siempre nos da un resultado incorrecto. Únicamente debemos buscar cual es la cadena correcta y habremos resuelto el reto.

Como paso principal buscaremos los “strings” almacenados en el binario en busca de la cadena correcta, o de alguna que nos pueda ayudar. Si os fijáis en los strings, pueden llamar más la atención los siguientes: [ “Right !“, “Wrong !”, “Ndg6kP” y “BabyGeek” ], identificando los dos primeros como los resultados de la comprobación y los dos últimos como posibles cadenas que tengan algo que ver con la solución. Si probamos las dos últimas cadenas como posibles soluciones nos encontramos con que ninguna de ellas es la correcta.

Lo que en estos momentos nos interesa es visualizar la parte de código donde se está realizando la comprobación de la cadena e intentar entender cual es la cadena correcta. Para esto, abrimos el binario con Immunity Debugger y buscamos donde se esta realizando la comprobación. Teniendo en cuenta la gran cantidad de código que nos podremos encontrar, se me ocurren dos formas de encontrar el código de la comprobación:

- Buscando las cadenas de resultado “Wrong y Right” en el código: Al utilizar como mensajes de la comprobación, el código que nos interesa se encontrará cerca de cuando estas cadenas son utilizadas.
- Llamadas intermodulares: Son las llamadas que hace el binario a la API.

Para hacerlo más entretenido, utilizaremos las llamadas a las APIs. Al introducir una cadena incorrecta, la aplicación nos devuelve un “messagebox” indicando que el mensaje es incorrecto. Esto es debido a que el propio binario llama a la función “MessageBoxA” de la librería USER32.DLL.

Para visualizar este tipo de llamadas en Immunity Debbuger, pulsamos botón derecho el código > Search for > All intermodular calls.

image

Dando como resultado la siguiente información:

image

Como se puede observar en la captura anterior, existen dos llamadas a esta función en el código, las direcciones “004010BE” y “004010D3”. Saltamos a una de las dos direcciones y nos encontramos lo siguiente.

image

Bloque 1: Rellena la pila para posteriormente devolver un mensaje que nos indique que la cadena introducida es la correcta.

Bloque 2: Rellena la pila para posteriormente devolver un mensaje que nos indique que la cadena introducida es incorrecta.

Bloque 3: En este punto (el primero en ejecutarse de los cuatro bloques) se está llamando a la función “GetDlgItemTextA”, la cual nos devuelve (y almacena en EAX) el número de caracteres del buffer indicado en su tercer parámetro, el cual coincide con el texto introducido en el crackme.

En la dirección “0x00401095” se está realizando una comparación de EAX (número de carácter del valor introducido) con 6, por lo que ya sabemos que el número de caracteres que debe tener la cadena correcta es igual a 6.

Bloque 4: Es el encargado de realizar la comparación, para posteriormente saltar a Bloque 1 o 2 dependiendo del resultado de la función “CMP EAX, 1”. Importante la instrucción CALL realizada antes del CMP, ya que, seguramente será allí donde se esté realizando la comprobación y se modifique el valor de EAX.

NOTA: Una solución para que nos devuelva el mensaje de correcto, sería cambiar el valor de EAX a 1 cuando estemos debugeando la aplicación. Pero a nosotros nos interesa buscar la cadena correcta.

Si saltamos a la dirección del registro CALL (0x004010FE), nos encontramos con el siguiente código.

image

De esta función podemos destacar lo siguiente:

- 0x00401102: Guardamos en el registro ESI el puntero que apunta a la cadena introducida en el crackme.
- 0x00401105: Llamamos a una nueva función en la dirección “0x0040110F”.

Procedemos con el código del salto a la dirección “0x0040110F”.

image

Este código ya tiene otra pinta, voy a proceder a explicar paso a paso lo que se hace en cada una de las líneas de esta función, para poder entenderla mejor.

- De 0x0040110F a 0x00401115: Almacena datos en la PILA y pone a 0 los registros ECX, EAX y EBX.
- 0x00401117: Almacena en el registro EDI el valor “Ndg6kP”.

Hasta aquí y es importante recordarlo, disponemos de, en el registro ESI el valor introducido en el crackme y en el registro EDI el valor “Ndg6kP”.

- De 0x0040111C a 0x0040112E: Se esta realizando un bucle donde intervienen los valor ESI y EDI.

Para reproducir tal cual el proceso del bucle vamos a asignar el valor de ESI (el valor introducido en la aplicación) a “123456”.

image

- 0x00401130: Guardamos el valor 1 en ECX (este hará que la comparación del Bloque 4 sea correcta y por lo tanto, nos lleve al mensaje “Right !”)

Con esto ya tenemos suficiente para decir que la comprobación se realiza a partir de la comparación de cada uno de los valores de caracteres del valor introducido con el correspondiente valor de la cadena “Ndg6kP” + 1.

Si lo asemejamos a una formula, nos podría quedar algo similar a esto:

(Hex) CADENA_1[i] + 1 == (Hex) CADENA_2[i] “Donde i es un valor de 0 a 5”

Procedemos a incrementar el valor en hexadecimal de cada uno de los caracteres de la cadena “Ndg6kP” para encontrar la cadena correcta.

image

Por lo que la cadena resultante sería: “Oeh7lQ

Si introducimos dicha cadena en el crackme conseguiremos que el resultado del mensaje sea correcto!!

image

Esto es todo ;)

Un Saludo!!

1 comentario: