Análisis de Malware .NET con dnSpy y de4dot: Guía Práctica
Guía práctica de análisis de malware .NET. Uso de dnSpy para decompilación y debugging, de4dot para deobfuscación, análisis de RATs como Agent Tesla y AsyncRAT, y técnicas de identificación de obfuscadores .NET (ConfuserEx, SmartAssembly, Babel).
.NET malware: el código fuente está a la vista
El análisis de malware .NET es fundamentalmente diferente al análisis de malware nativo. Cuando un desarrollador compila un programa en C#, el resultado no es código máquina x86/x64: es MSIL (Microsoft Intermediate Language), un bytecode de nivel intermedio que se compila a código nativo en runtime por el JIT (Just-In-Time compiler).
La consecuencia para el analista: MSIL se puede decompilar a C# casi perfecto. Nombres de clases, métodos, variables, strings, lógica de control. Es como tener acceso al código fuente original, salvo que el desarrollador haya aplicado ofuscación.
Esta ventaja hace que el análisis de malware .NET sea más accesible para analistas que no son expertos en assembly, y más rápido incluso para los que sí lo son.
Identificación de assemblies .NET
Indicadores en el PE
| Indicador | Cómo verificar |
|---|---|
| Data Directory 14 (CLR Runtime Header) | pestudio, CFF Explorer: COM Descriptor directory no es 0 |
Import de mscoree.dll _CorExeMain | pestudio, pefile: úsolo tiene este import |
| Strings "mscorlib", "System." | strings o FLOSS |
| Detect It Easy | DIE identifica ".NET" con versión de framework |
| CAPA | Reporta capability "compiled as .NET" |
Versiones de .NET
| Framework | Identificación | Impacto en análisis |
|---|---|---|
| .NET Framework 2.0-4.8 | PE clásico con CLR header | dnSpy, ILSpy funcionan perfectamente |
| .NET Core / .NET 5-8 | Single-file publish, ReadyToRun | Puede requerir extracción del assembly del bundle |
| Native AOT (.NET 8+) | Compilado a nativo, sin IL | Se pierde la ventaja de decompilación. Analizar como nativo |
Herramientas esenciales
dnSpy / dnSpyEx
| Aspecto | Detalle |
|---|---|
| Tipo | Decompilador + Debugger .NET |
| Lenguajes decompilados | C#, VB.NET, IL |
| Debugging | Puede debuggear assemblies .NET paso a paso |
| Edición | Permite editar IL y recompilar (útil para patchear checks anti-analysis) |
| Estado | Original archivado, fork activo: dnSpyEx |
Workflow básico con dnSpy:
- Abrir el assembly en dnSpy
- Navegar al EntryPoint (Main o constructor del Form principal)
- Leer el código decompilado como C#
- Identificar: URLs de C2, claves de cifrado, técnicas de persistencia
- Si está ofuscado: usar de4dot primero, luego reabrir en dnSpy
- Para análisis dinámico: poner breakpoints y debuggear
de4dot
| Aspecto | Detalle |
|---|---|
| Tipo | Deobfuscador .NET automático |
| Input | Assembly .NET ofuscado |
| Output | Assembly .NET deobfuscado |
| Soporta | ConfuserEx, SmartAssembly, Dotfuscator, Babel, Eazfuscator, Agile.NET, y más |
Uso básico:
# Deobfuscar automaticamente (detecta el obfuscador)
de4dot.exe malware.exe -o malware_clean.exe
# Forzar un obfuscador especifico
de4dot.exe malware.exe --strtyp delegate --strtok 0x06000042 -o clean.exe
# Solo renombrar simbolos (sin string decryption)
de4dot.exe malware.exe --dont-rename -o renamed.exe
Otras herramientas
| Herramienta | Uso |
|---|---|
| ILSpy | Decompilador .NET (alternativa a dnSpy, sin debugger) |
| dotPeek (JetBrains) | Decompilador gratuito, integración con ReSharper |
| CAPA | Detección automática de capacidades |
| pestudio | Identificación rápida de .NET y sus características |
| monodis | Decompilador de Mono (para assemblies Linux) |
| AsmResolver | Librería para manipulación programática de assemblies |
| dnlib | Librería .NET para leer/escribir assemblies (usada por de4dot) |
Obfuscadores .NET y cómo identificarlos
Obfuscadores comunes en malware
| Obfuscador | Identificación | de4dot soporte | Prevalencia |
|---|---|---|---|
| ConfuserEx | Strings con caracteres Unicode, control flow flattening agresivo | Parcial (strings sí, CF parcial) | Muy alta |
| SmartAssembly | Recursos embebidos comprimidos, strings cifradas | Sí | Alta |
| .NET Reactor | Código nativo embebido, anti-decompilation | Parcial | Alta |
| Dotfuscator | Renaming (Dotfuscator Community en VS) | Sí (renaming) | Media |
| Babel Obfuscator | MSIL cifrado, virtualization | Sí | Media |
| Eazfuscator.NET | Strings cifradas, control flow | Sí | Media |
| Agile.NET | String encryption, code virtualization | Sí | Baja |
| Crypto Obfuscator | Strings + resources cifrados | Sí | Baja |
| Custom | Ofuscación propia sin herramienta comercial | No (manual) | Variable |
ConfuserEx: el más común en malware
ConfuserEx es open source y gratuito, lo que lo hace popular entre desarrolladores de malware. Sus protecciones:
- Renaming: clases y métodos renombrados a caracteres Unicode ilegibles
- String encryption: strings cifradas y descifradas en runtime
- Control flow flattening: lógica de if/else/loops convertida en switch con dispatcher
- Anti-debug: checks de debugger integrados
- Anti-dump: impedir dump de memoria
- Resource encryption: recursos embebidos cifrados
Deobfuscación: de4dot maneja strings y renaming. Control flow flattening requiere herramientas adicionales o análisis manual.
Familias de malware .NET más comunes
Agent Tesla (Infostealer)
| Aspecto | Detalle |
|---|---|
| Tipo | Infostealer / Keylogger |
| Lenguaje | C# (.NET) |
| Ofuscador | ConfuserEx, SmartAssembly, .NET Reactor (varía) |
| Capacidades | Keylogger, screenshot, credential theft (navegadores, email, FTP), clipboard |
| Exfiltración | SMTP (email), FTP, HTTP POST, Telegram Bot API |
| Persistencia | Registry Run keys, Scheduled Tasks |
| Distribución | Phishing (adjuntos Office, ISO, RAR) |
Análisis típico:
- Deobfuscar con de4dot
- Abrir en dnSpy, buscar clase "Main" o "Form1"
- Buscar strings: SMTP server, email, password, FTP URL, Telegram bot token
- Identificar módulos: KeyLogger, ScreenCapture, BrowserCredentials, EmailCredentials
- Extraer IOCs: C2 URLs, credenciales del operador, Telegram chat ID
AsyncRAT
| Aspecto | Detalle |
|---|---|
| Tipo | Remote Access Trojan (open source) |
| Código fuente | Disponible en GitHub (NYAN-x-CAT/AsyncRAT-C-Sharp) |
| Ofuscador | Variable (el builder permite elegir) |
| Capacidades | Remote desktop, keylogger, file manager, process manager, shell, webcam |
| C2 | TCP con certificado SSL auto-firmado |
| Configuración | Embebida en Settings class, a veces cifrada con AES |
Extraer configuración:
// Buscar en dnSpy la clase "Settings" o "Config"
public static class Settings
{
public static string Host = "decrypt(encoded_host)";
public static int Port = 8808;
public static string Key = "decrypt(encoded_key)";
public static string Mutex = "AsyncMutex_xxxxx";
public static string Certificate = "decrypt(cert_data)";
}
Quasar RAT
Similar a AsyncRAT (open source, C#), pero con arquitectura cliente-servidor más robusta. El análisis sigue el mismo workflow: deobfuscar, buscar Settings/Config, extraer C2 y credenciales.
Workflow completo de análisis
Paso 1: triage
1. Calcular hash (SHA256)
2. Buscar en VirusTotal
3. Identificar como .NET (DIE, pestudio)
4. Identificar obfuscador (DIE, dnSpy)
5. Ejecutar CAPA para capacidades automáticas
Paso 2: deobfuscación
de4dot.exe sample.exe -o sample_clean.exe
# Si de4dot no identifica el obfuscador:
de4dot.exe sample.exe --un-name "!^[a-zA-Z]" -o sample_clean.exe
Paso 3: análisis estático en dnSpy
1. Abrir sample_clean.exe en dnSpy
2. Ir al EntryPoint (Boton derecho en assembly → Go to Entry Point)
3. Leer Main(): identificar flujo principal
4. Buscar clases de configuracion (Settings, Config, Connection)
5. Buscar strings de interes: URLs, IPs, paths, claves
6. Identificar mecanismos de persistencia
7. Identificar tecnicas de evasion (IsDebuggerPresent, Sleep, sandbox checks)
8. Documentar IOCs
Paso 4: análisis dinámico (si necesario)
1. En dnSpy: Debug → Start Debugging (F5)
2. Poner breakpoint en funciones de interes:
- Funcion de descifrado de configuracion
- Funcion de conexion C2
- Funcion de persistencia
3. Ejecutar hasta el breakpoint
4. Inspeccionar variables locales (valores descifrados)
5. Extraer configuracion descifrada
Paso 5: extracción de IOCs
| Tipo de IOC | Dónde buscar en el código |
|---|---|
| C2 IP/Domain | Clase Settings/Config, métodos de conexión |
| C2 Port | Clase Settings/Config |
| Encryption key | Clase de cifrado, Settings |
| Mutex | CreateMutex calls, Settings |
| Persistence path | Registry key values, file paths |
| User-agent | HTTP client configuration |
| Telegram Bot Token | Strings que empiezan con números y contienen ":" |
| SMTP credentials | Host, port, username, password del email de exfiltración |
Técnicas de anti-analysis en .NET
Anti-debugging
// Check comun en malware .NET
if (Debugger.IsAttached)
Environment.Exit(0);
// Timing check
Stopwatch sw = Stopwatch.StartNew();
Thread.Sleep(1000);
if (sw.ElapsedMilliseconds > 1500) // Demasiado lento = debugger
Environment.Exit(0);
Bypass en dnSpy: editar el IL para invertir la condición o NOP el check. Boton derecho en la instrucción → Edit IL Instructions.
Anti-sandbox
// Check de VM
if (Environment.MachineName.Contains("SANDBOX"))
Environment.Exit(0);
// Check de procesos de analisis
string[] badProcesses = { "wireshark", "procmon", "x64dbg", "dnspy" };
foreach (var p in Process.GetProcesses())
if (badProcesses.Any(b => p.ProcessName.ToLower().Contains(b)))
Environment.Exit(0);
Resource encryption
Muchos malware .NET almacenan su payload real como recurso cifrado:
// Patron comun: cargar recurso, descifrar, ejecutar
byte[] resource = Properties.Resources.payload;
byte[] decrypted = AES_Decrypt(resource, key);
Assembly.Load(decrypted).EntryPoint.Invoke(null, null);
El payload real solo existe descifrado en memoria. Para extraerlo: breakpoint después del descifrado y dumpar el array de bytes.
Mapeo MITRE ATT&CK
| Técnica | ID | Contexto .NET |
|---|---|---|
| Obfuscated Files | T1027 | ConfuserEx, SmartAssembly |
| Deobfuscate/Decode | T1140 | Runtime string decryption |
| Input Capture: Keylogging | T1056.001 | SetWindowsHookEx desde .NET |
| Screen Capture | T1113 | Graphics.CopyFromScreen() |
| Credentials from Browsers | T1555.003 | SQLite read de Chrome/Firefox DBs |
| Application Layer Protocol | T1071 | HTTP/SMTP/Telegram C2 |
Fuentes y referencias
- 0xd4d. "dnSpy: .NET debugger and assembly editor." (archived) https://github.com/dnSpy/dnSpy
- dnSpyEx. "dnSpy Fork." https://github.com/dnSpyEx/dnSpy
- de4dot. ".NET deobfuscator." https://github.com/de4dot/de4dot
- ILSpy. "ILSpy .NET Decompiler." https://github.com/icsharpcode/ILSpy
- NYAN-x-CAT. "AsyncRAT-C-Sharp." GitHub.
- Mandiant. "CAPA: .NET Capability Detection." https://github.com/mandiant/capa
- Any.Run. "Agent Tesla Malware Analysis." ANY.RUN Blog.
- MITRE ATT&CK. "Agent Tesla (S0331)." https://attack.mitre.org/software/S0331/
- OALabs. ".NET Malware Analysis Series." YouTube.
Preguntas frecuentes
Libros recomendados
Artículos relacionados
Anatomía de un PE: Entendiendo los Ejecutables de Windows para Análisis de Malware
Evasión de Antivirus: Ofuscación, Packers y Crypters
Fileless Malware en Windows: PowerShell, .NET y WMI como Armas
CAPE Sandbox: Extracción de Config de AgentTesla
Analisis de DLLs y Handles en Memoria: dlllist, handles y Deteccion de Inyeccion
Analisis de Procesos en Memoria Windows: pslist, pstree y Deteccion de Anomalias
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.