Los códigos maliciosos, claro está, son programas, y como tales se crean utilizando un lenguaje de programación. Si bien es común encontrarnos con malware desarrollado en Delphi, C o C++ entre otros, también existen amenazas que utilizan lenguajes interpretados como el caso de Python, Java o .NET. El análisis de malware para cada uno de estos lenguajes tiene sus diferencias y es por ello que en este post veremos diferentes herramientas que nos permitirán el análisis de malware u otros programas en .NET, ya sea que hayan sido programados en VB.NET o en C#.
El malware desarrollado en .NET, y en particular las diferentes familias detectadas como variantes de MSIL/Injector, crecieron de manera notable durante los últimos años. Entre los tipos de amenazas más comunes que vemos desarrolladas con esta tecnología se encuentran diferentes tipos de BitCoinMiners, packers, o protectores que ocultan en su interior diferentes variantes de códigos maliciosos desarrollados en otras tecnologías. El siguiente gráfico muestra el crecimiento de malware en MSIL durante los últimos años:
Tal como muestra el gráfico, desde la tercera parte de 2014 han aumentado las detecciones de estas familias, ya sea en el rol de ocultar lo que hacen otras amenazas o robar información de los usuarios. En base a ello trabajaremos en cómo analizarlas o qué herramientas utilizar para hacerlo.
Al momento de compilar un programa desarrollado con el framework de .NET en lenguajes como VB.NET o en C#, se genera mediante el Common Language Infrastructure un código intermedio conocido como CIL (por su siglas en inglés de Common Intermediate Language). Este es interpretado por el framework de Microsoft. Salvando las diferencias técnicas, es un proceso similar al que sucede cuando se compila el código en Java para obtener los .jar o el .dex en el caso de que se esté programando para Android.
Debido a que el programa que se compila queda en un lenguaje intermedio, es posible a través de diferentes herramientas obtener un código que se asemeje bastante al original y en determinados casos que sea prácticamente el mismo. Este tipo de situaciones son de gran ayuda para reducir el tiempo de análisis requerido y así comprender el funcionamiento de una amenaza.
.NET en IDA Pro
IDA Pro es una de las herramientas predilectas para el análisis de malware o el estudio de cualquier otro programa que se quiera analizar estáticamente. Esta herramienta la hemos introducido a lo largo de un gran número de posts y casos puntuales para explicar qué es lo que hace una amenaza sin la necesidad de ejecutarla en un sistema.
Ahora, cuando abrimos un archivo en IDA Pro que fue desarrollado por ejemplo en C# y detectado por ESET como MSIL/Injector.LES, el desensamblador ya identifica por defecto que es assembly de .NET:
Si dejamos la recomendación por defecto y procedemos a desensamblar el archivo podremos ver cuáles son las funciones presentes en el programa:
Sin embargo, cuando intentemos observar el código desensamblado de las mismas, lo que veremos serán las instrucciones de CIL, que al igual que aprender assembler, o el bytecode de Java llevan su tiempo de aprendizaje:
Si bien es posible analizar el flow del programa, al analizar este tipo de archivos existen otras herramientas que nos brindan una aproximación más directa, permitiéndonos ver el código en un lenguaje de más alto nivel y hasta incluso ejecutar las amenazas con un debugger, instrucción por instrucción.
.NET Reflector
Esta herramienta desarrollada por Red-Gate nos permite decompilar cualquier programa desarrollado en .NET, modificarlo ya sea para solucionar bugs o estudiar su comportamiento. Desde el sitio se puede descargar una versión de prueba de 14 días o comprar la herramienta. También viene con un plugin para Visual Studio.
Una vez que terminaron de instalar la herramienta, la primera vez que la ejecutan podrán elegir cuál es el tipo de assembly por defecto con el que quieren trabajar:
Ahora, si abrimos el mismo programa que vimos en el caso anterior, además de ver sus métodos y recursos podremos ver el código en el lenguaje que deseemos. Esto de por sí simplifica el entendimiento del código malicioso y en determinados casos nos ahorra una gran cantidad de tiempo en el análisis:
Además de ver el código, en C# en este caso podríamos elegir entre Visual Basic, IL, MC++ o F#. .NET Reflector también nos permite analizar un método y ver desde dónde se lo invoca o cual sería la secuencia de ejecución que tendría.
ILSpy
La tercera herramienta que veremos en esta entrada, es de código abierto y está disponible en el repositorio de GitHub ILSpy. Este analizador de aplicaciones en .NET y desensamblador también permite extender sus funcionalidades a través de la instalación o creación de plugins.
En sus funciones básicas es similar a la herramienta que vimos anteriormente. Es flexible y liviana, sumado a que no es necesario instalarla ya que se puede bajar el standalone, o clonar su repositorio de GitHub e incluso modificarla según nuestras necesidades.
Al abrir la amenaza con la cual venimos trabajando, vemos la información de las librerías correspondientes al framework como así también la estructura interna del programa, similar a lo que vimos con .NET Reflector:
Al pararnos sobre un método o clase podemos analizar su contenido y ver dónde se asigna, se accede o se utiliza, lo que puede simplificar en gran parte un análisis estático. Hasta este punto, a excepción de IDA Pro, que también es un debugger, ninguna herramienta nos dejaría analizar el malware de manera dinámica.
Si quisiéramos ejecutar un análisis dinámico podríamos utilizar herramientas como las que ya hemos visto, sin embargo, la última herramienta que vamos a ver nos permite extender o simplificar aún más nuestras acciones.
dnSpy
La cuarta herramienta que veremos en este post es dnSpy, un fork de la anteriormente presentada ILSpy. En cuanto a la estética, nos permite manejar diferentes combinaciones de colores, pero eso no es todo su potencial.
La principal diferencia o valor agregado es que incluye un debugger para el código que desensamblamos, lo que brinda la oportunidad de hacer el análisis a un nivel un poco más alto que si utilizáramos OllyDbg, Immunity Debugger o IDA Pro con este tipo de tecnologías. No va a ser la solución a todos los casos pero sí de gran ayuda al llegar el momento de analizar protectores, u otras amenazas que están desarrolladas en las tecnologías de .NET.
Cuando seleccionamos el programa en .NET que queremos analizar y lo inicializamos, se detendrá la ejecución y nos devolverá el control al inicio del proceso. En este punto podremos comenzar a debuggear la aplicación y así responder a las preguntas que nos pudiesen haber quedado, definiendo los breakpoints que nos interesen y controlando la ejecución:
El objetivo de presentar estas herramientas es compartir con ustedes algunas maneras de simplificar el análisis de determinados tipos de amenazas. Como comentamos al principio el malware desarrollado en tecnologías basadas en .NET se incrementó de manera considerable en el último tiempo y es por ello que hay que saber qué herramientas utilizar para su análisis. Esto nos ayudará a minimizar los tiempos de respuesta.
De todas formas, aprender a utilizar las herramientas es solo parte del trabajo; aún queda mucho por hacer y cosas por conocer. Para aquellos que quieran saber más sobre análisis de malware en .NET les recomiendo leer la investigación que Marcim Hartung presentó en Virus Bulletin 2015, "Unpack your troubles: .NET Packer tricks and countermeasures".