Diseccionando binarios - 0x03 Crackmes Hardcoded

Publicada en Publicada en Cracking, Reversing

Muy buenas a todos continuamos con esta saga de tutoriales sobre Reversing/Cracking con la principal motivación de compartir con la Comunidad Fwhibbit mi estudio, usando principalmente las tools x64dbg como Debugger y radare2 para realizar el análisis estático del código. Dejaré en la primera entrada de esta saga el índice con todos los links que se vayan publicando, para así tenerlo a mano.

La tool x64dbg que usaremos en este tutorial y los siguientes podéis descargarla de aquí:

https://x64dbg.com/#start

Usaremos diferentes Crackmes y aconsejo la lectura de todo el contenido que tiene en la web Ricardo Narvaja, recomendable: http://ricardonarvaja.info/WEB/ .Usaré dos tools diferentes como comente anteriormente para cubrir más abanico de posibilidades en el Reversing. El amigo SoftDat de CrackSLatinoS, subió hace poco un manual traducido al castellano del oficial de radare2 os lo dejo para poder descargarlo, gracias por tu aporte 😉

Radare2 traducido por SoftDat

El original en inglés lo podréis encontrar en la página oficial de Radare2:

https://radare.gitbooks.io/radare2book/content/

Crackme Hardcoded 1

Comenzamos con un crackme hardcodeado donde el serial no es calculado a través de una cadena de caracteres que nosotros introducimos sino es único. Podéis descargarlo de aquí:

HARCODED1.exe

Lo abrimos con x64dbg:

No os preocupeis si no entendéis la interfaz gráfica del programa, ya que iremos viéndola a base de practicar con Crackmes y dando su uso a la mayor parte de las ventanas. Según lo que ya sabemos si habéis seguido las dos últimas entradas, se intuye que la ventana principal a la izquierda corresponde al Desensamblado, a la derecha los Registros, abajo a la izquierda el Dump o Volcado en Hexadecimal y la derecha el Stack o Pila. Vemos que no se situa en el EntryPoint del programa, sino en la ntdll.dll le damos a Ejecutar y ya nos posicionamos con EIP apuntando a la dirección 401000. Se dice que esta harcodeado, porque en este caso aparece las Strings del serial a introducir además de lo comentado anteriormente. Por lo tanto Botón derecho en el desensamblador Buscar en/Region actual/Referencias a cadenas.

Vemos que hace referencia a las Strings "FIACA" y luego a "Mal Muy MAL", podemos deducir que este último es el cuadro de texto de que hemos introducido mal las cadenas de caracteres. Sino, siempre antes de comenzar a Debuggear podemos ejecutar el programa para ver como interactua.

Además de poder buscar las cadenas de texto o Strings podemos buscar por Llamadas entre Módulos y ver las diferentes apis que usa el programa o Crackme:

Vemos que usa la user32.GetDlgItemTextA que si nos vamos a la página de Microsoft recupera el valor introducido, en este caso el Serial que ingresemos. Y la api user32.MessageBoxA para mostrar un mensaje y siendo dos las llamadas que se hacen a la api indicando que una sera el mensaje correcto y el otro el incorrecto.

Introducimos un Breakpoint (Botón derecho Alternar Breakpoint o F2) en ambas direcciones correspondientes a la instrucción call.
Le damos a Ejecutar y nos aparecera la ventana del programa:

Le damos a Verificar y el EIP apunta a la instrucción call de la api GetDlgItemTextA.

Apretamos F7 para ejecutar una instrucción y entramos en la api.

Si miramos detenidamente en el Stack, el ESP (19F924) contiene la dirección de retorno una vez finalice de ejecutar la api (ret) para así saber en que instrucción del programa hardcoded1.exe tiene que volver, en este caso es la dirección de memoria 401061. Si hacemos botón derecho en la dirección del Stack 19F930 dónde pone hardcoded y mostrar Dword en el Volcado vemos el Buffer preparado para recibir el serial en la dirección de memoria 403010.

Volcado:

Ahora en la pestaña Depurar/Ejecutar hasta retorno lo clickeamos y el EIP apuntará hasta el ret para salir de la api.

Ahora si visualizamos en el Volcado tendremos almacenado el serial introducido. En el Stack, el contenido que tiene una dirección dada en el Volcado se coloca al revés el valor hexadecimal.

Apretamos F7 y volvemos a la ejecución del programa. Si nos vamos al modo gráfico tenemos una visual más intuitiva. En la primera instrucción lo que realiza es mover el contenido ("FIACA") de la dirección de memoria 403008 al registro EDX. Podemos localizar también los otros dos Breakpoints que pusimos a la api MessageBoxA (cuadrado rojo delante de la instrucción).

La siguiente instrucción realiza lo mismo pero moviendo el contenido de la dirección de memoria 403010 que si recordamos era la instrucción donde quedo almacenada (Buffer) nuestro serial, al registro EBX. Luego realizará una comparación con la instrucción cmp entre ambos valores entre "FIACA" y "naivenom", que dependiendo del tipo de salto condicional realizará una acción u otra. Podemos deducir que el Serial bueno es "FIACA" siendo muy fácil identificarla a través de referencias a cadenas o Strings.

Ejecutamos con F7 hasta llegar al salto condicional. Volvemos a la pantalla del CPU y vemos los registros para ir viendo que cada vez que vayamos ejecutando el programa, el contenido de los registros irán modificandose.

Vemos en las eflags como la ZF esta seteada a 0, eso quiere decir que no va a realizar el salto ya que con JE salta si es igual o es cero y como las dos cadenas no son iguales no salta y nos saldrá la ventana de "Mal Muy Mal". Por tanto si tiene que ser igual, y viendo "FIACA" deducimos que este es el serial bueno.

Si seteamos la ZF a 1 y le damos a F7, nos saldrá la ventana de Muy Bien ya que realizaría el salto.

Crackme Hardcoded 2

Descarga del fichero:

crackme.exe

Continuamos con el siguiente Crackme situándonos en el EntryPoint del programa. Miramos como siempre las apis y las Strings. En los módulos o apis localizamos user32.GetWindowTextA que recogerá el Serial que introduzcamos por teclado, kernel32.lstrcmpA que comparará las cadenas de texto que hayamos introducido, y por último user32.MessageBoxA mostrando el mensaje en una ventana de si es correcto el serial o no (ya que hay dos llamadas a ese módulo o api).

Una vez colocados los Breakpoints le damos a Ejecutar e introducimos el Serial o Password:

Vemos como el programa, el EIP apunta a la instrucción correspondiente a la llamada de la api GetWindowTextA. Entramos en el módulo con F7, y visualizamos el Buffer en el Volcado, y observamos como esta preparado para recibir el Serial que introduzcamos por teclado.:

Ejecutamos hasta el ret, y vemos nuestros Strings almacenados en el Buffer:

Ejecutamos para salir de la api con F7, y visualizamos el Desensamblado en modo Gráfico. Vemos que Pushea al Stack dos direcciones de memoria cuyo contenido corresponde a las cadenas de caracteres "naivenom" y "cannabis" (este último tiene pinta de ser el Serial bueno). Al pushearlo, como vimos en entradas anteriores y luego llamando a la api o módulo kernel32.lstrcmpA corresponderá a los argumentos que recibe dicha api.

Vemos en el Stack al ejecutar con F7 las dos instrucciones push, como queda almacenado las dos direcciones de memoria siendo "19FAB0" el ESP:

Ejecutamos la api que va a comparar la Strings y le damos a ejecutar hasta el ret:

El resultado de la api nos devuelve en EAX cuyo valor es 00000001, mirando en los Registros:

Antes de realizar el salto condicional, realiza una operación lógica con el registro EAX cuyo resultado es 00000001. Como el salto jne salta si no es igual o no es cero (ZF=0) y como no es igual se produce el salto, flecha verde en el modo gráfico o en el de CPU lo muestra y especifica como "Salto tomado":

Podríamos haber evitado que el salto se tome modificando la ZF seteandola a 1, como vimos en el anterior Crackme, y también sabemos que la api lstrcmpA compará dos Strings el serial bueno que es "cannabis" con lo introducido por nosotros que corresponde a "naivenom". Así que ya sabemos cual es el Serial, cerramos y ejecutamos la aplicación.

Ahora ya por último vamos a usar radare2 para este Crackme usando comandos básicos para realizar un análisis estático del mismo. En la primera y segunda entrada de los tutoriales uso este software, por si tenéis que realizar una consulta y más adelante profundizaré más en su uso, además de que disponéis de las Docs que ofrece radare2. Analizamos con la opción aaaa (strings,funciones,flags...).

Con la opción afl, buscamos todas las funciones disponibles o apis y con s buscamos la dirección virtual de la función en el binario. Vemos que estamos situados en el prompt del CLI de r2 en en EntryPoint correspondiente a la dirección de memoria 401000.

Podemos hacer uso de !!rabin2 -z en busca de los Strings en el binario desde el prompt de r2 o fuera. Si ejecutamos iz hace lo mismo, y con izz busca Strings en todo el binario no solo en .data.

Observamos dónde estan localizadas con su correspondiente dirección de memoria, por ejemplo la de "You entered the right password!" con 40305E. Tenemos el mismo resultado que con x64dbg:

Con la opción pdf, realizamos el desensamblado del EntryPoint ya que estamos situados desde el prompt allí.

Si queremos verlo en modo visual gráfico introducimos v!. Localizamos como pushea la String "cannabis" y la otra dirección de memoria que nosotros ya sabemos cuando hicimos el Debugging que corresponde con el Serial que introdujimos por teclado, y también cómo hace las llamadas a las diferentes apis y después de ejecutar el módulo lstrcmpA, realiza la operación or y el salto condicional. Este Crackme al estar hardcodedeado es sencillo ver de forma estática cual "podría" ser el Serial además de conocer el funcionamiento de las apis que usa el programa.

Para recorrer el código podemos ir con la tecla n y vamos buscando por la función siguiente y con la tecla m abrimos el menu de arriba y para movernos entre un menu hacia la derecha e izquierda respectivamente l y h. Si apretamos ? nos saldrá una pequeña ayuda.

También si hacemos v y seguidamente accionamos p, vamos cambiando el modo de visualización.

Con vv podemos visualizar el Desensamblado en función de los módulos/funciones/apis que vayamos recorriendo:

En la próxima entrada realizaremos primero el análisis estático del binario con r2 para entender algunas instrucciones assembly y buscar referencias a cadenas e ir aprendiendo poco a poco el manejo de esta CLI, y luego debuggearemos con x64dbg.

Un saludo, Naivenom.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *