Ingeniería inversa de malware protegido

Me parece que se me había pasado comentaros pero…

A lo largo del tiempo vuelan muchas muestras de malware por nuestras manos, que analizamos para lograr comprender su funcionamiento (ingeniería inversa). Este proceso es un arduo trabajo que puede llevar bastante tiempo dependiendo de la complejidad del propio malware y del packer o packers utilizados para protegerlo. Existen varios tipos, pero como ejemplo explicaremos como desempaquetar un packer sencillo que únicamente tenga una fase, como puede ser UPX (algunos implementan varias rutinas de empaquetado y desempaquetado).

El primer paso es saber si el binario esta empaquetado o no, para ello existen un gran número de herramientas que pueden ayudarnos, algunas de las más conocidas son RDG Packer Detector y PEiD (basadas en detección de firmas y calculo de entropía principalmente). Las imágenes que se muestran en la galería inferior son de un malware, pero para hacer las pruebas os proporcionamos un binario inofensivo de ejemplo («Hola Mundo» empaquetado con NsPack). El siguiente paso es abrir la muestra con un debugger, en este caso utilizaremos el clásico Immunity Debugger.

Una vez abierto, nos indicara que el entry point esta fuera del código (como se especifica en la cabecera PE). A continuación buscaremos el comando “PUSHAD” ya que realiza el push del contenido de los registros de propósito general en la pila. Bastará con hacer click derecho y acceder a “Search for” y dentro a “Command”.

Una vez se ha localizado dicha instrucción, pulsamos F2 para poner un breakpoint. Seguido, pulsamos F9 para que se ejecute el programa hasta la instrucción marcada. Tras pulsar F8 para llegar al “PUSHAD”, vamos a la sección de registros, marcamos ESP (Extended Stack Pointer) y haciendo click derecho en él, elegimos “Follow in Dump” para poder ver lo que se encuentra allí en el HEX Dump.

Ahora se visualizará, en el DUMP, el contenido en hexadecimal de la dirección correspondiente. Para controlar cuándo se vuelve a tener acceso a estos datos (presumiblemente accederá a ellos justo antes de ejecutar el código original o lo que es lo mismo, al final del desempaquetado de los datos) se debe poner un breakpoint hardware de acceso de tipo «Dword» en los primeros bits. Para ello, marcamos los primero 32 bits, hacemos click derecho y elegimos la opción que se ha comentado previamente. Luego, pulsamos F9 para llegar al momento en el que se vuelve a acceder a esos datos. Nos encontremos en un JMP”, pulsaremos F7 para entrar (nos llevará al código original de la muestra). Automáticamente Immunity no interpreta los datos como código, por lo que será necesario indicárselo. Click derecho, elegimos «Analysis» y finalmente «Analyse code».

Con estos pasos hemos logrado conseguir el código real del malware, el cual podremos analizar más en profundidad para entender su funcionalidad. En caso de querer crear el binario sin empaquetar, podremos utilizar el plugin OllyDumpEx para hacer el dump a través de la opción “Dump proccess”. Finalmente solo haría faltaría reconstruir las imports del ejecutable con ImpREC para que funcione correctamente.

Se utilizan varias técnicas anti-debugging para impedir este tipo de análisis, como puede ser utilizar la función KERNEL32.IsDebuggerPresent de winAPI. También suelen comprobar si la ejecución se está realizando en una máquina virtual utilizando el TSC (Time Stamp Counter) entre otros. En caso de que alguno de esos “triggers” salte, la ejecución cambiará y ocultará su funcionalidad real realizando algo inocuo. En otra ocasión explicaremos como intentar evadir esas técnicas de protección contra ingeniería inversa.

Recordad que estos análisis se tienen que realizar en entornos controlados para impedir cualquier infección en caso de que algo no salga como debería.

El que avisa no es traidor.

Iskander Sanchez-Rola
Acerca de
Founder/Content Director
Expertise: Web Security and Privacy
iskander-sanchez-rola.com