MegaArtículo de analisis de Malware

Antes de empezar con el artículo, quiero mencionar que lo que se escribe a continuación es una recopilación de varios artículos que leí en los blogs que leo siempre. Los mismos están extraídos textualmente.

Se extrae de los siguientes post:
http://www.areino.com/malware-analysis-1/
http://www.areino.com/malware-analysis-2/
http://www.areino.com/malware-analysis-3/
http://www.areino.com/malware-analysis-4/
http://hacking-avanzado.blogspot.com/2010/04/algunos-links-utiles.html
http://hacking-avanzado.blogspot.com/2010/05/introduccion-al-portable-executable.html

1.0 - Bichología – Introducción

El malware actual es variado y utiliza técnicas bastante avanzadas para conseguir algo: dinero. Ya pasaron los tiempos del "I love you" o de virus cuya motivación era ser "visibles" y si es posible salir en la tele. Y si has conseguido infectar varios millones de PCs en el primer día de propagación, más gloria te llevas. No, el malware de ahora busca pasar desapercibido, propagarse sin hacer saltar alarmas, intentar que el usuario no se de cuenta, y dedicarse a enviar spam, robar contraseñas, etc.

Todo "bicho" que se precie tiene, simplificando, varios elementos:

  • Mecanismo de infección. Puede ser una combinación de métodos que el malware realiza por si mismo (infección a otras máquinas desde una máquina infectada via red, por ejemplo) o con ayuda (desde una página web que te lo "enchufa" cuando la visitas, o oculto en documentos PDF, o "a caballo" de otros troyanos, downloaders, etc.)
  • Mecanismo de "Command & Control". Para tener una botnet efectiva, una vez que tienes varias decenas de miles de PCs infectados, necesitas poder "decirles" que quieres que hagan. Ya sea enviar SPAM, lanzar ataques de Denegación de Servicio (DoS), robar contraseñas de Facebook, etc. Para ello el malware debe tener algun mecanismo que permita recibir comandos de la gente que controla la red. Esto puede ser conectándose a un canal de IRC, a una página web, etc. Los sistemas de "command & control" pueden ser muy sencillos o extremadamente complicados, implementando funcionalidad de redes peer-to-peer (P2P).
  • Carga útil o payload. Es decir, el código que implementa lo que quieres que haga el "bicho": robar datos, etc.
  • Mecanismo de persistencia y ocultación. Cualquier cosa que haga para mantener la máquina infectada, y ocultar su presencia. Puede ir desde aparentar ser un fichero de sistema normal y corriente, a alterar el funcionamiento de software antivirus, etc.

¿Por qué molestarse en analizarlo nosotros mismos? Podemos enviar la muestra a nuestro fabricante favorito de antivirus y que hagan el trabajo ellos, que tienen expertos que se dedican a ello. Varias razones:

  • Podemos tener un incidente más o menos grave en curso. El fabricante de antivirus puede tardar horas o días en darnos una solución. Mientras tanto es importante conocer un poco a qué nos enfrentamos y poder desarrollar un procedimiento de detección, de contención de la propagación, y si es posible de eliminación.
  • Porque mola y es divertido.

Digamos que en el transcurso de una investigación encontramos algo sospechoso. O bien nos lo remite un usuario que lo ha detectado. O nuestro flamante antivirus dice que encuentra "algo" que podría ser un virus, ya sea mediante heurística o mediante monitorización de su actividad. ¿Cómo procedemos?

Esto es una sugerencia de pasos a seguir:

  • Establece un entorno ("laboratorio") de análisis. Aislado.
  • Intenta ejecutar el "bicho" y monitoriza su comportamiento (acceso a ficheros y registro, conexiones de red, etc.)
  • Realiza análisis estáticos y dinámicos del código para determinar su funcionamiento interno. Esto suele ser lo más complicado y lo que requiere más expertise por parte del analista.
  • Documenta los resultados.

Ten preparado (de antemano) el entorno aislado donde puedas copiar el malware para su análisis. Puedes seguir los consejos de Lenny Zeltser, pero en general suele ser suficiente un entorno virtual (tipo VMWare), en una red aislada (y monitorizada), y con herramientas de análisis de comportamiento (Process Explorer, Wireshark, Process Monitor, etc.). Esto suele ser suficiente para empezar.


2.0 - Laboratorio y herramientas

¿Qué necesitamos para analizar "bichos"? Tampoco mucho, y la mayoría es gratis.

2.1 - Entorno de Trabajo

Lo primero que necesitamos es algún sitio donde tener nuestras herramientas de análisis y poder ejecutar las muestras de malware sin peligro de infectar nuestro PC de trabajo habitual o los equipos que estén conectados en la misma red. No, no queremos eso.

Lo mejor es tener un laboratorio con varios equipos, físicos y virtuales, conectados en red. Esto nos permite crear un entorno "realista" para la muestra, y poder monitorizar intentos de infección entre un equipo y otro.

Si no podemos permitirnos algo así, un conjunto de máquinas virtuales suele ser suficiente. Yo uso VMWare Workstation instalado sobre Linux con varias máquinas virtuales (Windows Server 2003, Windows XP, Windows 7) para hacer pruebas. Este producto tiene dos cosas que lo hacen interesante: permite tomar snapshots (guardar el estado de la máquina virtual en un momento dado, y poder volver atrás en cualquier momento), y la creación de redes virtuales para interconectar equipos virtuales.

También se puede usar Virtual PC o VirtualBox o similares, pero no tengo el gusto.

Si la red es física (sobre todo si estamos mezclando máquinas virtuales con físicas), viene bien tener un hub ethernet. Y cuando digo un hub no me refiero a un switch. Son cosas diferentes. Un hub nos simplifica la tarea de conectar un equipo con un sniffer que capture el tráfico de red para luego analizarlo. El problema es que es casi imposible encontrar hubs verdaderos ya. Casi todo lo que se vende son switches. Si os haceis con un hub viejo, no lo tireis.

Con las máquinas físicas (cualquier PC antiguo que pueda correr XP sirve) conviene tener imágenes de la máquina recién instalada y limpia, hechas con Ghost o similar. Esto es para poder recuperar el estado original de los equipos una vez hemos terminado el análisis.

2.2 - Herramientas Online

Existen muchos servicios online que nos ayudan a analizar malware. Cogemos nuestra muestra (un .EXE o .DLL o similar) y la subimos a la página web. Al rato nos dará un informe que nos puede ser de mucha utilidad.

  • Anubis nos da un informe sobre los ficheros y entradas de registro accedidas, así como las DLLs cargadas en el proceso. Un poco lo que nos daría Process Monitor de hacerlo nosotros mismos. Además pasa el fichero por el scanner de Ikarus y nos dice si lo identifica o no.
  • JoeBox es como Anubis, pero nos da bastante más información y más detallada. Además analiza las conexiones de red del fichero y nos las muestra en el informe. Al igual que Anubis, tambien lo pasa por un scanner, esta vez de Avira.
  • VirusTotal nos permite analizar la muestra contra 39 scanners antivirus, además de proporcionarnos otra información útil. Un ejemplo de informe.

Hay más, pero estas son las tres que suelo utilizar.

2.3 - Herramientas de Análisis de Comportamiento

Cualquier programa ejecutado en Windows hace básicamente cuatro cosas de forma silenciosa: acceso a ficheros, acceso a registro, gestión de procesos y threads, y conexiones de red.

La suerte es que para las tres primeras tenemos una excelente herramienta cortesía de Microsoft (SysInternals) llamada Process Monitor. Nos permite monitorizar en tiempo real todo lo que pasa en el sistema (fichero, registros, procesos, etc.) Además permite hacer análisis desde la propia herramienta, generando árboles de procesos, secuencias temporales de actividad, etc.

Esta herramienta se complementa con Process Explorer, de los mismos señores. Esta última está orientada a examinar procesos mientras se están ejecutando (digamos que es un Task Manager avanzado), y ver sus conexiones de red, librerías DLL cargadas, etc.

La tercera herramienta fundamental es un buen sniffer, como Wireshark. Podemos tenerla instalada en la máquina donde ejecutamos el especimen, o podemos tenera en otro sistema de forma que pueda capturar todo el tráfico de red (recuerda el hub). Un buen sniffer nos va a dar información sobre intentos de conexión que realiza el "bicho", ya sea para infectar otras máquinas, como para enviar SPAM, como para conectarse "a casa" a recibir comandos.

2.4 - Herramientas de Análisis de Código

El análisis de código es complejo y requiere experiencia  importante en desarrollo. El malware puede estar desarrollado en código compilado (más habitual) o interpretado (python, etc.). Además puede estar cifrado y/o empaquetado. Muchas veces es necesario ejecutar la muestra de malware de forma controlada, siguiendo su secuencia de ejecución, para poder entender qué hace y cómo lo hace.

Las herramientas principales aquí son los debuggers (como OllyDbg), desensambladores (IDA Pro), y cualquier herramienta que nos permita hacer volcados de la memoria reservada por un proceso (como Process Dumper o PMDump)  y un análisis de estos (Memory Parser).

También hay que tener a mano herramientas para "desempaquetar" código "empaquetado".

Y no olvidemos la utilidad strings (también de Microsoft / SysInternals) que a veces es capaz de sacar información útil de ficheros binarios (una vez desempaquetados) y de ficheros de volcado de memoria de procesos.


3.0 - Un ejemplo práctico

Tengo una muestra de lo que parece ser un virus o similar. El fichero se llama ergdz.exe. Es muy común que el malware utilice nombres aleatorios para los ficheros, por lo que el nombre en general no nos dice nada. Lo primero que he hecho es subirlo a Anubis (ver informe), a Joebox (ver informe), y a VirusTotal (ver informe).

En este último informe se puede ver que algunos (no todos, a día de hoy) de los antivirus lo detectan, con nombres variados. Estos nombres que aparecen (skintrim, wintrim, hrup, etc.) corresponden a una "familia" de troyanos de "adware", es decir, su motivación principal (aunque pueden tener otras) es mostrar publicidad al usuario.

En el informe de JoeBox (ver informe) -JoeBox es un analizador de malware online- podemos ver como el bicho ha leído una serie de claves de registro, ha hecho un par de conexiones a un feed RSS de Microsoft, y ha terminado.

Es curioso esto de las conexiones. En mi opinión, puede servir para comprobar si el equipo infectado tiene acceso a Internet.

Otra cosa útil que nos dice VirusTotal, es el tipo de fichero, y en este caso tiene toda la pinta de ser un ejecutable Win32 compilado con Visual Studio C++. Si además examinamos el fichero con una herramienta como PEiD podemos ver que es Visual Studio C++ 6.0 (y que no parece empaquetado).

Investigando un poco más, todavía sin ejecutar la muestra, con Resource Hacker (clic aca para descargar la versión 3.4.0) podemos examinar los "recursos" enlazados con el binario compilado (iconos, imágenes, textos, etc.)

Curiosas cadenas de texto. El comando "strings" tampoco saca nada mucho más interesante.


4.0 - Links útiles sobre ingeniería inversa, assembly y demás temas relacionados.

4.1 - Compiladores, ensambladores, ...., IDEs, con sus respectivos foros y tutoriales para principiantes:

4.2 - Foros de ingeniería inversa:
  • Woodmann: es algo un poco "duro" y tiene más información de ingeniería inversa en ring-0. Tuts4you .
  • reverse-engineering community: Es muy útil para principiantes. Asociado a éste, tenemos crackmes.de, donde encontraremos numerosos programas para probar nuestros skills en ingeniería inversa.
  • Tuts4you: Tiene de todo

4.3 - Códigos de virus y troyanos, muchos de ellos en assembly:

  • VX-heavens: Dentro de el, en library, hay bastante información de polimorfismo y otras técnicas. Los tutoriales son algo viejos (años 80/90), pero no por ello han dejado de ser actuales. Dentro de VX-heavens, seguramente lo mejor en assembly es lo escrito por 29A y por Zombie (por ejemplo los mutation engine de Zombie, simplemente impresionantes). Bastantes de los miembros de 29A eran españoles.
  • Opensc está especializado en troyanos. Tiene poquito en assembly, pero mucho en C, que al fin y al cabo puede re-escribirse en asm en poco tiempo.
4.4 - Bibliografía (buscarlos en thepiratebay.org)
  • Secrets Of Reverse Engineering: no tiene mucho de "secrets", pero es una muy buena introducción al tema.
  • Windows System Programming: tened cuidado de coger la última edición del libro, que es la cuarta. Este libro es una excelente referencia sobre los internals de windows (interprocess comunication, memoria, etc).
  • Rootkits, subverting de windows kernel: durísimo libro con muy valiosa información del kernel de windows. No abarca los últimos windows 7 y demás familia, pero las técnicas, muchas de ellas (hooks en la IDT, por poner un ejemplo) están y estarán vigentes por mucho tiempo.
4.5 - Herramientas
  • OllyDbg: Maravilloso debugger para user-level. Ya hemos hablado de él.
  • Ida: El mejor desensamblador con diferencia (como debugger es un poco incómodo). Desensambla todo tipo de librerías y ejecutables de plataformas distintas, tiene su propio lenguaje para hacer scripts ... De todo.
  • Softice: El mejor debugger de windows para ring-0. Hay otros (WinDbg y Syser), pero no le llegan a la suela de los zapatos. Tiene dos inconvenientes: sólo funciona hasta winXP con SP3 y es un poco "desagradable" de usar.

4.6 - Otras herramientas para manipular o examinar ejecutables:
  • LordPe: examinar ejecutables, hacer un dump ...
  • PeId: suele usarse para ver con qué packer está protegido un programa
  • FileMon, RegMon: sirven para visualizar los cambios hechos (respectivamente) en archivos y en el registro.
  • ResHacker: sirve para editar los recursos de un ejecutable (imágenes, strings, ...). Suele usarse para "traducir" programas o para meterle los logos después de crackearlos.
  • Imprec: reconstrucción de la IAT

5.0 -Introducción al Portable Executable File Format (PE)

Para poder crackear programas o escribir virus o desensamblarlos, uno necesita unos conocimientos mínimos del sistema operativo y, en particular, del formato PE (Portable Executable File format), que es el que corresponde a los archivos ejecutables de windows (.exe, .dll, .ocx, ...).

Necesitamos entender cómo está estructurado ya que muchos packers, antivirus, protecciones de todo tipo, etc hacen uso de distintos trucos de manipulación del formato PE para acceder a la información que necesitan o bien para impedir que nosotros accedamos a ella.

Para empezar, vamos a abrir con Olly un programa cualquiera, Notepad.exe.

Lo primero que vemos es una llamada a GetModuleHandleA:


getmodulehandlea.jpg


Lo que hace al llamar la función es leer un dato almacenado en 0x10010CC en edi y luego hacer un call edi. Si te fijas, verás que en edi hay una tabla con direcciones de memoria. Se trata de la Import Address Table, que contiene las direcciones de todas las funciones de todas las DLL que el programa ha declarado que va a necesitar.

Si le damos a "follow in dump" para la dirección 0x10010CC y luego desensamblamos, nos encontramos lo siguiente:


iat.jpg


Que es lo que comentábamos ... Si mirásemos notepad.exe con un editor hexadecimal, veríamos que lo que hay ahí son un montón de punteros a los strings "GetModuleHandleA", "GetStartupInfoA", ... Cuando el loader de windows prepara el programa para su ejecución, lo que hace es leer cada uno de estos strings, obtener la dirección en memoria en la que va a estar cargado y substituir el puntero por la dirección. De esta forma, los programas saben donde empiezan cada una de las funciones que tienen que llamar.

Veamos ahora la lista de DLLs cargadas por el programa (dándole a view => modules)

notepad2.jpg


Ahí tenemos todas las DLL que han sido cargadas por el programa. Entre ellas, destacaremos las siguientes:
  • kernel32.dll: funciones para manipular archivos, crear threads y procesos. Son las principales funciones que todo programa necesitará. De hecho, cualquier archivo ejecutable necesita cargar kernel32 para interactuar con el sistema operativo.
  • user32.dll: funciones para interactuar con el usuario, como por ejemplo MessageBox.
  • advapi32.dll: acceso al registro, entre otras cosas.
  • gdi32.dll: interfaz gráfica.
  • ntdll.dll: en realidad, todas las funciones de kernel32, advapi32, etc acaban llamando a una de ntdll. Aunque los programas siempre interactuan con las de kernel32, por motivos de compatibilidad.

También es interesante observar que las propias DLL tienen un array con las direcciones de todas las funciones que exportan. Esto es de kernel32.dll:

exports.jpg


Es un poco más de lo mismo. Las DLL exportan funciones y necesitan declarar cuáles son. Esto lo hacen dando una lista de nombres de las funciones por un lado y una lista de direcciones de memoria por otro. De hecho, dentro de kernel32 tenemos la función GetProcAddress, que nos devuelve la dirección de una función dado su nombre y la dirección de memoria en la que se ha cargado la DLL:

The GetProcAddress function returns the address of the specified exported dynamic-link library (DLL) function.

FARPROC GetProcAddress(
HMODULE hModule, // handle to DLL module
LPCSTR lpProcName // name of function
);
Parameters

hModule: Identifies the DLL module that contains the function. The LoadLibrary or GetModuleHandle function returns this handle.
lpProcName: Points to a null-terminated string containing the function name, or specifies the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.


Una forma más "disimulada" de llamar a una función es precismente averiguar su dirección de memoria con GetProcAddress y hacer entonces la llamada, en lugar de tenerla declarada como una función a importar, lo cual hace obvio su existencia sin más que mirar la Import Address Table del ejecutable.

De hecho, es posible ni siquiera usar GetProcAddress simplemente usando nuestra propia función que parsee la DLL y nos devuelva la dirección. Este es un truco muy usado tanto en packers como en virus. Volveremos a esto más adelante.

Sigamos ...

Con Alt+M podemos ver todos los módulos cargados en memoria (archivos PE, que comprenden al propio notepad y a todas las DLL).

notepad.jpg


Como ves, tanto el propio notepad como todas las dll (todos son PE) están compuestos por cabeceras y secciones. Vemos algo que se llama "PE header" y luego unas cuantas secciones, que suelen ser .code (código), .data (datos), .rsrc (recursos), ...

La PE-header contiene toda la información que el sistema operativo necesita para cargar el programa y prepararlo para su ejecución. Entre otras cosas: dirección de memoria en la que debe cargarse, secciones que vienen luego (cuántas son, si son ejecutables o no, si son datos o no...), ...

Para entender mejor este galimatías, lo que vamos a hacer es echarle un ojo a notepad con una utilidad que se llama LordPe, que podés bajar de aquí. Esta utilidad lo que hace es un dump de la información del ejecutable (secciones, funciones importadas, recursos, ...).

Si abrimos notepad ...

lordpe1.jpg

Veamos las cosas más importantes, todas ellas, tal y como indica LorPE, se encuentran en la PE-header de notepad:
  • EntryPoint: punto de entrada del programa. El main() de toda la vida.
  • checksum: crc del ejecutable para garantizar su integridad. LorPE lo recalcula si queremos.
  • NumberOfSections: número de secciones del programa, que son estas:

secciones.jpg

  • SizeOfHeaders: cada sección tiene una cabecera que la describe. Este es el tamaño total de todas ellas.
  • ImageBase: dirección de memoria en la que debería de cargarse notepad.

Por último, dentro de donde pone "directories" podremos encontrar toda la información sobre las funciones importadas y exportadas, etc ...

imports.jpg


Y con esto acabamos esta intro al formato PE. Como vés, no es tan complicado: una cabecera para el ejecutable con la información general, una serie de cabeceras para cada sección y luego las secciones. Además, tenemos ciertas estructuras especiales, entre ellas la lista de funciones importadas y exportadas.


6.0 - Seguimos analizando la muestra

La muestra que estuvimos mirando anteriormente, no parece que haga nada.

Ejecutándola en una máquina virtual de VMware Workstation 7.0.1, corriendo Windows XP SP3, y monitorizando su actividad con Process Explorer, Process Monitor y Wireshark, la muestra no parece hacer nada de nada.

Ni lanzamiento de otros procesos, ni accesos extraños a ficheros, ni creación de claves de registro…

… ni conexiones sospechosas de red a ningún sitio…

El proceso sale inmediatamente y termina, y no hace nada que no haga cualquier otro programa en su secuencia de arranque. Se pueden formular varias hipótesis:

  • No es malware.
    • En contra: el fichero en sí es sospechoso. Las cadenas de texto son muy sospechosas (y me recuerdan a los textos pseudo-aleatorios del SPAM en comentarios de blogs).
    • A favor: los fabricantes de antivirus no parecen ponerse de acuerdo, y no todos lo detectan aun pasado mucho tiempo desde su primera detección (informe Virustotal).
  • Es malware pero está dañado o incompleto.
    • A favor: no parece hacer nada por si mismo.
  • Es malware pero de alguna forma detecta que corre en "entorno hostil" y no hace nada.
    • En contra: cualquier intento de detección (que está en una máquina virtual, que hay herramientas de monitorización, etc.) dejaría al menos alguna traza.
    • A favor: existen técnicas para detección de entornos virtuales que no implican acceso de ficheros y/o registro, como la desarrollada por Joanna Rutkowska, o la que se puede encontrar en Trapkit.de.

Habrá que investigar un poco más, haciendo análisis del código (desensamblado y debuggeado).


Entradas populares de este blog

Trinity Rescue Kit: Tutorial para eliminar la contraseña de administrador en Windows

Cómo extraer el handshake WPA/WPA2 de archivos de captura grandes

HTTP Fingerprinting