Analisis de Binarios .NET: dnSpy, ILSpy y Decompilacion
Analisis de malware .NET con dnSpy e ILSpy. Estructura de assemblies .NET, codigo IL, decompilacion a C#, ofuscacion con ConfuserEx y Dotfuscator, deobfuscacion con de4dot y herramientas especializadas.
.NET: el paraiso del analista de malware
Analizar malware .NET es fundamentalmente diferente a analizar malware nativo. Mientras que un binario C++ compilado pierde casi toda la informacion de alto nivel, un assembly .NET conserva metadatos completos: nombres de clases, metodos, campos, tipos de parametros y hasta el flujo de control. Los decompiladores modernos reconstruyen codigo C# que es casi identico al original.
Esto convierte a .NET en un territorio privilegiado para el analista. Las familias mas populares de malware .NET (Agent Tesla, AsyncRAT, QuasarRAT, NanoCore, RedLine Stealer, Formbook variantes .NET) se pueden analizar leyendo codigo C# decompilado, sin necesidad de ensamblador.
El desafio viene cuando el autor usa ofuscadores como ConfuserEx o .NET Reactor. Pero incluso ahi, las herramientas de deobfuscacion automatica como de4dot resuelven la mayoria de los casos.
Estructura de un assembly .NET
Un assembly .NET es un archivo PE con una estructura especifica:
| Componente | Contenido |
|---|---|
| PE Header | Headers estandar con CLR flag |
| CLR Header | Metadatos .NET, entry point de IL |
| Metadata Tables | Clases, metodos, campos, strings |
| IL Code | Instrucciones Intermediate Language |
| Resources | Recursos embebidos (archivos, configuraciones) |
| Strong Name Signature | Firma opcional del assembly |
Identificacion de un assembly .NET
import pefile
pe = pefile.PE("sample.exe")
# Verificar CLR header (Data Directory indice 14)
if len(pe.OPTIONAL_HEADER.DATA_DIRECTORY) > 14:
clr = pe.OPTIONAL_HEADER.DATA_DIRECTORY[14]
if clr.VirtualAddress > 0 and clr.Size > 0:
print("Es un assembly .NET")
print("CLR header en RVA:", hex(clr.VirtualAddress))
else:
print("No es .NET")
Otros indicadores:
- Referencia a mscoree.dll en imports (funcion _CorExeMain).
- Seccion .text con IL code en lugar de instrucciones x86/x64.
- Detect It Easy lo identifica como ".NET assembly".
Codigo IL (Intermediate Language)
IL (tambien llamado CIL o MSIL) es el lenguaje intermedio al que compilan todos los lenguajes .NET (C#, VB.NET, F#). Es un lenguaje de stack (como Java bytecode) que se compila a codigo nativo por el JIT compiler en runtime.
Ejemplo de IL vs C#:
// C# original
public int Add(int a, int b)
{
return a + b;
}
// IL equivalente
.method public hidebysig instance int32 Add(int32 a, int32 b) cil managed
{
.maxstack 2
ldarg.1 // push a
ldarg.2 // push b
add // a + b
ret // return
}
Normalmente no es necesario leer IL directamente. Los decompiladores lo convierten a C# automaticamente.
dnSpy / dnSpyEx: la herramienta de referencia
dnSpy (y su fork activo dnSpyEx) es el decompilador y debugger .NET preferido para analisis de malware. Combina decompilacion, edicion de codigo y debugging en una sola herramienta.
Funcionalidades clave
Decompilacion:
- Decompila assemblies a C# o VB.NET con alta fidelidad.
- Navega clases, metodos y campos con arbol jerarquico.
- Resalta dependencias y referencias cruzadas.
- Busqueda global de strings, tipos y metodos.
Debugging:
- Debug de assemblies .NET sin el codigo fuente original.
- Breakpoints, watches, call stack, variables locales.
- Modificar valores de variables en runtime.
- Step into/over/out como cualquier debugger.
Edicion:
- Editar codigo C# directamente y recompilar el assembly.
- Modificar metadatos, IL code y recursos.
- Util para parchear anti-debug o bypass de checks.
Flujo de analisis con dnSpy
- Abrir el assembly: File, Open. dnSpy parsea toda la metadata.
- Explorar la estructura: Navegar el arbol de namespaces y clases.
- Buscar el entry point: Buscar Main() o el metodo marcado como entry point.
- Identificar funcionalidad: Buscar clases relacionadas con red, archivos, registro, criptografia.
- Buscar strings: Edit, Search Assemblies, buscar URLs, IPs, paths.
- Analizar comunicacion C2: Buscar HttpClient, WebClient, TcpClient, Socket.
- Extraer configuracion: Buscar campos estaticos con URLs, puertos, claves de cifrado.
Busquedas utiles en dnSpy
| Busqueda | Que encuentra |
|---|---|
| "http://" o "https://" | URLs de C2 o descarga |
| Socket, TcpClient | Comunicacion de red raw |
| Registry, RegistryKey | Acceso al registro (persistencia) |
| Process.Start | Ejecucion de procesos |
| File.Write, File.Copy | Operaciones de archivo |
| Clipboard | Acceso al portapapeles (clipboard stealer) |
| Screenshot, CaptureScreen | Captura de pantalla |
| Keylog, GetAsyncKeyState | Keylogger |
| Crypto, AES, DES, Rijndael | Operaciones criptograficas |
| base64, Convert.FromBase64 | Datos codificados |
ILSpy: alternativa open source
ILSpy es la alternativa open source a dnSpy, mantenida activamente. No tiene debugger integrado, pero su decompilador es excelente:
- Decompilacion a C# de alta calidad.
- Soporte para assemblies .NET Core y .NET 5+.
- Plugins para funcionalidad adicional.
- Disponible como extension de Visual Studio Code (ILSpy for VS Code).
# ILSpy desde linea de comandos
ilspycmd sample.exe -o output_directory/
# Genera archivos .cs decompilados
Ofuscacion en malware .NET
ConfuserEx
El ofuscador open source mas popular en malware. Aplica multiples protecciones:
| Proteccion | Efecto |
|---|---|
| Rename | Renombra clases, metodos y campos a caracteres no legibles |
| String encryption | Cifra todos los strings con funciones de descifrado en runtime |
| Control flow | Ofusca el flujo de control con switch dispatchers |
| Ref proxy | Reemplaza llamadas directas con proxies indirectos |
| Anti-tamper | Detecta modificaciones del assembly |
| Anti-debug | Detecta debuggers |
| Constants protection | Protege constantes numericas |
| Resource encryption | Cifra recursos embebidos |
Deteccion:
- Metadata con nombres como caracteres Unicode no imprimibles.
- Metodo de inicializacion con nombre ofuscado que se ejecuta en el static constructor.
- Strings "#ConfuserEx" o "Confuser" a veces presentes en la metadata.
- Detect It Easy lo identifica automaticamente.
.NET Reactor
Protector comercial que va mas alla de la ofuscacion:
- Cifra el IL code completo (no solo ofuscacion superficial).
- Native code generation (convierte parte del IL a codigo nativo).
- Merge de assemblies (combina multiples DLLs en uno).
- Licenciamiento integrado.
Dotfuscator
Incluido en Visual Studio. Menos agresivo que ConfuserEx:
- Renaming de identificadores.
- String encryption basico.
- Control flow ofuscation leve.
- Pruning de codigo no usado.
Otros ofuscadores
| Ofuscador | Tipo | Frecuencia en malware |
|---|---|---|
| SmartAssembly | Comercial | Media |
| Agile.NET (CliSecure) | Comercial | Baja |
| Babel.NET | Comercial | Baja |
| Eazfuscator | Comercial | Baja |
| Crypto Obfuscator | Comercial | Media |
| Custom | Propio | Alta (en malware sofisticado) |
de4dot: deobfuscacion automatica
de4dot es la herramienta de referencia para deobfuscacion automatica de assemblies .NET. Detecta el ofuscador y aplica las transformaciones inversas.
# Deobfuscar automaticamente (detecta el ofuscador)
de4dot sample_obfuscated.exe
# Resultado: sample_obfuscated-cleaned.exe
# Especificar ofuscador manualmente
de4dot sample.exe -p cr # ConfuserEx (Confuser (r)ex)
de4dot sample.exe -p dr # .NET Reactor
de4dot sample.exe -p sa # SmartAssembly
# Solo renombrar (sin descifrar strings)
de4dot sample.exe --dont-restore-strings
# Preservar tokens de metadata
de4dot sample.exe --preserve-tokens
Que hace de4dot:
- Detecta el ofuscador usado.
- Descifra strings protegidas.
- Renombra clases y metodos a nombres legibles (Class0, Method1, etc.).
- Elimina proxy calls.
- Simplifica el control flow.
- Elimina anti-tamper y anti-debug.
- Genera un assembly limpio.
Limitaciones:
- No soporta todos los ofuscadores (especialmente custom).
- Algunos protectores modernos no se desofuscan completamente.
- El renaming automatico (Class0, Method1) es mejor que caracteres ilegibles pero no recupera los nombres originales.
Analisis de recursos en assemblies .NET
Los assemblies .NET pueden embeber recursos como streams accesibles programaticamente. El malware los usa para ocultar payloads:
// Patron comun en malware .NET: cargar payload desde recursos
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStream("Payload.bin");
var data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
// Descifrar
for (int i = 0; i < data.Length; i++)
{
data[i] ^= 0x55; // XOR con clave
}
// Cargar assembly desde memoria
var payload = Assembly.Load(data);
payload.EntryPoint.Invoke(null, null);
En dnSpy: Resources, examinar cada recurso embebido. Extraer y analizar por separado si tienen entropia alta.
Tecnicas especificas de malware .NET
Reflection para evasion
El malware usa System.Reflection para invocar metodos sin referenciarlos directamente:
// En lugar de llamar directamente a Process.Start:
Type t = Type.GetType("System.Diagnostics.Process");
MethodInfo m = t.GetMethod("Start", new Type[] { typeof(string) });
m.Invoke(null, new object[] { "cmd.exe" });
Esto oculta la dependencia de Process.Start del analisis estatico.
Assembly.Load desde memoria
Cargar un assembly completo desde un array de bytes en memoria, sin tocar el disco:
byte[] payload = DecryptResource("EmbeddedPayload");
Assembly asm = Assembly.Load(payload);
asm.EntryPoint.Invoke(null, new object[] { new string[0] });
El assembly cargado no existe como archivo, dificultando el analisis forense.
AppDomain para aislamiento
Crear un AppDomain separado para ejecutar el payload, con la capacidad de descargarlo despues:
AppDomain domain = AppDomain.CreateDomain("PayloadDomain");
domain.ExecuteAssembly(payloadPath);
AppDomain.Unload(domain); // Descargar despues de ejecutar
Costura.Fody: merge de assemblies
Herramienta legitima que embebe todas las dependencias dentro del ejecutable principal. El malware la usa para crear un solo archivo sin DLLs externas. Los assemblies embebidos se comprimen y se cargan en runtime.
Flujo de trabajo completo
- Identificar .NET:
fileo pefile verifica CLR header. - Verificar ofuscacion: Abrir en dnSpy, examinar nombres de clases.
- Deobfuscar si necesario:
de4dot sample.exe. - Abrir en dnSpy: Navegar el arbol de clases.
- Buscar entry point: Main() o punto de entrada del CLR.
- Identificar funcionalidad clave:
- C2: buscar HttpClient, Socket, WebClient.
- Persistencia: Registry, ScheduledTask.
- Robo: Clipboard, Keylogger, Screenshot.
- Cifrado: AES, RSA, XOR.
- Extraer configuracion: Campos estaticos con URLs, puertos, claves.
- Extraer recursos: Verificar si hay payloads embebidos.
- Debugging si necesario: Breakpoints en funciones de descifrado o C2.
Familias .NET comunes
| Familia | Tipo | Ofuscador comun |
|---|---|---|
| Agent Tesla | Infostealer | ConfuserEx, .NET Reactor |
| AsyncRAT | RAT | ConfuserEx, custom |
| QuasarRAT | RAT | ConfuserEx |
| NanoCore | RAT | ConfuserEx, Eazfuscator |
| RedLine Stealer | Infostealer | Custom, ConfuserEx |
| njRAT | RAT | Ninguno o ConfuserEx basico |
| LimeRAT | RAT | ConfuserEx |
| Formbook/.NET variant | Infostealer | Custom |
| Snake Keylogger | Keylogger | ConfuserEx |
| Remcos | RAT | .NET Reactor, custom |
Conclusion
El malware .NET es mas accesible para el analisis que cualquier otro tipo gracias a la riqueza de los metadatos IL y las herramientas de decompilacion. El flujo estandar (de4dot para deobfuscar, dnSpy para decompiliar y debuggear) resuelve la mayoria de las muestras en minutos. Las familias mas populares de RATs y infostealers usan .NET precisamente por la facilidad de desarrollo, pero esa misma facilidad beneficia al analista.
El desafio real aparece con ofuscadores avanzados o protectores que cifran el IL code completo. En esos casos, el analisis dinamico con dnSpy como debugger y breakpoints en funciones de descifrado es el camino mas eficiente.
Preguntas frecuentes
Libros recomendados
Artículos relacionados
Formato PE de Windows: Estructura Completa del Ejecutable
Ofuscacion de Codigo: Tecnicas y Estrategias de Deobfuscacion
Analisis Estatico Basico: Strings, Hashes y Metadatos
Packing y Unpacking: UPX, Themida, VMProtect y Tecnicas
Este contenido tiene fines exclusivamente educativos y de investigación en ciberseguridad defensiva. No se proporcionan binarios maliciosos ni payloads ejecutables. El uso indebido de esta información es responsabilidad exclusiva del usuario. Leer disclaimer completo.