La semana pasada, en la publicación Radare2: abriendo las puertas al reversing, explicamos qué es Radare2 y dimos los primeros pasos con esta poderosa herramienta. En esta ocasión iremos más allá y mostraremos cómo podríamos usarla para el análisis de códigos maliciosos.

Muchas veces los ciberdelincuentes utilizan lenguajes de programación como C, C++ y Delphi para desarrollar amenazas informáticas. Pero una vez compiladas, no hay forma de extraer el código fuente de estas tecnologías, lo cual presenta cierta complejidad para los investigadores de seguridad al momento de comprender qué intenciones tiene una amenaza y a partir de ello desarrollar una solución para eliminarla.

Supongamos que nos encontramos en presencia de una amenaza que contiene técnicas anti debugging en su código para evitar que algún usuario descubra su actividad en un equipo. A continuación, podemos observar que nuestra aplicación “crack_me_353T” evaluará si se encuentra siendo depurada o no y, dependiendo de esa condición, se ejecutará el mensaje correspondiente.

Para iniciar Radare2 en modo debug, debemos ejecutar el siguiente comando en consola: radare2 –Ad, donde con la letra "A" se analizarán diferentes aspectos del ejecutable y con “d” ejecutamos la aplicación en modo debug. Luego de haber ejecutado la aplicación, con “dc” le indicamos a radare2 que continúe corriendo el programa.

Como mencionamos anteriormente, el software identificó que lo estaban depurando y lo evidencia con un mensaje en consola:

radare2

Como primera instancia, analizaremos el programa estáticamente; para ello iniciaremos nuevamente en una consola radare2 más el archivo con el que estemos trabajando. Una vez que la herramienta haya cargado, utilizaremos aaa para que realice un análisis de todo el ejecutable, para luego emplear afl, comando que nos listará todas las funciones encontradas por la herramienta. En dicha lista, podemos destacar “sym.main” que es la función principal del programa:

radare2

Abriendo el modo visual de radare2 sobre la función “sym.main”, tendremos la estructura del código en instrucciones de bajo nivel, pero de una modo más agradable, ayudando al usuario identificar determinadas estructuras, como por ejemplo bucles o condicionales. Si prestamos atención en las dos últimas líneas del primer bloque tenemos:

0x0804847a     85c0           test eax, eax

 0x0804847c     7913           jns 0x8048491

En la primera línea se verifica si el contenido de registro EAX es menor a 0. De ser así, se establecerá el SF (sign flag) en 1. En la segunda línea nos encontramos con la operación JNS (Jump on No Sign), esto quiere decir que si el SF es igual a 0 el programa continuará en la dirección que se indica (0x08048491), de lo contrario, no realiza el salto y continúa con la próxima operación.

En resumen, si el registro SF se encuentra en uno (SF=0x00000001), el programa determinará que se encuentra siendo depurado. Caso contrario, SF contiene el valor cero (SF=0x00000000), lograremos eludir la protección de anti debugging. En la siguiente captura podemos ver con más claridad lo desarrollado:

3

Como ya conocemos qué condiciones y valores se establecen durante la ejecución, tenemos los datos necesarios para modificar el binario y lograr dar el salto a la dirección 0x08048491, para obtener como resultado el mensaje “We Live Security!”.

Como mencionamos, JNS es un salto condicional. Por lo tanto, podríamos reemplazar esa instrucción por otra, JMP (Jump), quedándonos como resultado la línea en hexadecimal ed 13. Para modificar el binario necesitamos utilizar un editor hexadecimal y para nuestra suerte, con Radare2 podemos realizar esta acción.

Utilizando -Aw abrimos el ejecutable en modo de escritura. Luego debemos situarnos sobre la dirección que queremos editar; el comando adecuado para esto es s más la dirección de memoria. Como vemos en la captura que se encuentra más adelante, haciendo uso de pd y la cantidad de bytes que deseemos podemos mostrar en consola el desensamblado del binario que hemos indicado.

Ahora sí, como mencionamos antes, tenemos que modificar el valor “79” por “eb” y por lo tanto, con wx eb13 reemplazamos los hexadecimales que necesitamos. Nuevamente volvemos a imprimir el desensamblado y podemos observar que el binario ya se encuentra modificado:

radare2

Ahora, debemos verificar si los cambios que realizamos fueron los correctos para que el ejecutable no identifique que se encuentra siendo depurado. Una vez más, corremos la aplicación en modo debug y como resultado final, podemos observar que el mensaje ha cambiado. Esto quiere decir que logramos que el flujo de ejecución del programa sea diferente del que teníamos al principio:

radare2

Como puedes ver, esta es una de tantas técnicas o procedimientos que podríamos realizar al momento de aplicar ingeniería inversa sobre un código malicioso, como así también eludir metodologías de anti virtualización y de esta manera profundizar y comprender completamente el objetivo de una amenaza. La ingeniería inversa muchas veces es empleada para desarrollar productos que sean compatibles con otros sin conocer detalles de desarrollo de éstos últimos, y es empleada para comprobar la seguridad de un software para detectar y mitigar efectos no deseados en estos.

Claramente Radare2 no tiene nada que envidiarle a otras aplicaciones open source o de pago, como lo son OllyDbg, GNU Debugger, Immunity Debugger o IDA Pro, entre las más conocidas, ya que nos brinda todo lo que necesitamos para encarar y llevar a cabo una investigación.