¿Qué es una suscripción de eventos WMI?
WMI (Windows Management Instrumentation) puede ejecutar una acción cuando ocurre algo. Una suscripción de eventos permanente tiene tres partes: un __EventFilter (una consulta WQL que describe el evento), un consumidor de eventos (qué hacer: ejecutar una línea de comandos, un VBScript/JScript, escribir una línea de log, una entrada del registro de eventos o un correo electrónico) y un __FilterToConsumerBinding que une ambos.
Las suscripciones se almacenan en el repositorio WMI (CIM) y sobreviven a los reinicios. Sus acciones se ejecutan como SYSTEM —una línea de comandos iniciada por el host de proveedores WMI (WmiPrvSE.exe) o un script ejecutado por scrcons.exe— sin nada en una clave Run ni en una tarea programada. Por eso los atacantes las usan para persistencia (MITRE ATT&CK T1546.003) y por eso es fácil pasarlas por alto.
Dónde se almacena
- C:\Windows\System32\wbem\Repository\OBJECTS.DATA: todas las definiciones de clase e instancias, en páginas de 8 KiB. Las páginas liberadas conservan su contenido anterior hasta que se reutilizan.
- INDEX.BTR: un árbol B de claves como NS_<hash>\CI_<hash>\IL_<hash>.<page>.<record>.<length>, donde cada hash es el SHA-256 (MD5 en XP) de un nombre en mayúsculas.
- MAPPING1.MAP, MAPPING2.MAP, MAPPING3.MAP: mapas de páginas lógicas a físicas para OBJECTS.DATA e INDEX.BTR; Windows conserva tres generaciones y usa la más reciente.
- Las suscripciones suelen residir en el espacio de nombres root\subscription, pero funcionan en cualquier espacio de nombres.
Qué muestra esta herramienta
- Cada enlace unido a su filtro (la consulta disparadora) y a su consumidor (la línea de comandos, el script, el archivo de log o el registro de eventos de destino).
- Dos formas de encontrar cada objeto, siempre indicadas: estructurada (a través de INDEX.BTR y el archivo MAPPING actual, como python-cim) y carving (un barrido de todo OBJECTS.DATA en busca de cabeceras de registro y texto de enlaces, como PyWMIPersistenceFinder).
- Versiones eliminadas y anteriores de objetos recuperadas de páginas liberadas y del slack de página, distinguidas de las activas cuando están presentes los archivos MAPPING.
- Hallazgos con sus motivos: PowerShell codificado, rutas escribibles por usuarios, consumidores de script, disparadores de persistencia (tiempo de actividad, inicio de sesión, temporizadores), enlaces fuera de root\subscription, piezas sin enlazar o rotas, y las suscripciones predeterminadas de Windows (SCM Event Log y BVT) reconocidas por nombre y contenido.
- En equipos con el cliente de Configuration Manager: CCM_RecentlyUsedApps como evidencia de ejecución (ruta, usuario, LastUsedTime, recuento de inicios e información de versión), incluidas las copias antiguas recuperadas del espacio liberado, con rango de tiempo y hallazgos.
Limitaciones
- Los objetos de suscripción WMI no tienen marcas de tiempo documentadas. Cada cabecera de instancia contiene dos FILETIME no documentados, mostrados como pistas; las vistas de suscripciones no tienen filtro de tiempo (la vista SCCM sí: LastUsedTime es una hora real).
- Los registros recuperados por carving no tienen espacio de nombres, y un registro repartido entre páginas liberadas no contiguas puede ser solo parcialmente legible.
- Sin INDEX.BTR ni un archivo MAPPING, las estructuras de clase proceden de una copia integrada de las clases estándar de Windows (validada en cada registro), y no se pueden distinguir los registros activos de los eliminados.
- Los archivos MOF, la lista AutoRecover y otros puntos de persistencia quedan fuera del alcance; la estructura de Windows XP está soportada con menos pruebas.
Cómo obtener los archivos
- Recopile la carpeta Repository completa con KAPE (target WBEM), Velociraptor (Windows.Triage.Targets, WBEM) o desde una imagen de disco.
- En un sistema en funcionamiento, lea los archivos desde una instantánea de volumen para que todos procedan del mismo instante. Nunca detenga el servicio WMI para copiarlos.
- Conserve también las copias antiguas (instantáneas de volumen, Windows.old): una suscripción eliminada puede seguir allí.
Créditos y método
- flare-wmi / python-cim — Willi Ballenthin, FireEye (now Mandiant). Las estructuras del repositorio —archivos MAPPING, páginas de INDEX.BTR, tabla de contenidos de OBJECTS.DATA, definición de clase y cabeceras de instancia— se han portado de python-cim, y el modo estructurado sigue su resolutor de objetos. Apache-2.0.
- PyWMIPersistenceFinder — David Pany, Mandiant. La pasada de carving de texto sigue su idea: buscar el texto __FilterToConsumerBinding y sus referencias EventConsumer.Name / __EventFilter.Name en cualquier parte de OBJECTS.DATA, y tratar los enlaces BVT y SCM Event Log como predeterminados habituales. MIT.
- WMI Attacks, Defense and Forensics (DEF CON 23) — William Ballenthin, Matt Graeber, Claudiu Teodorescu (FireEye, 2015). La charla (y el white paper que la acompaña) que documentó el formato del repositorio y la persistencia WMI; las diapositivas y demos se conservan en el repositorio flare-wmi.
- [MS-WMIO]: WMI Encoding Version 1.0 Protocol — Microsoft. La especificación pública de la codificación de objetos dentro de cada registro: partes de clase, NdTable, tabla de valores, heap y cadenas codificadas.
Preguntas frecuentes
¿Se sube mi repositorio a algún sitio?
No. El analizador está escrito en Rust compilado a WebAssembly y se ejecuta en un Web Worker de su navegador. No existe ningún punto de subida.
¿Basta con OBJECTS.DATA?
Sí, para encontrar suscripciones: el modo de carving recorre cada byte en busca de registros de filtros, consumidores y enlaces, incluidos los eliminados. Con INDEX.BTR y los archivos MAPPING obtiene además los espacios de nombres y un veredicto fiable de activo/eliminado.
¿Qué significan «Índice», «Registro recuperado» y «Coincidencia de texto»?
Indican cómo se encontró un objeto. Índice: a través de INDEX.BTR y el archivo MAPPING actual, por lo que está activo. Registro recuperado: su cabecera de registro se encontró recorriendo OBJECTS.DATA; si además no está indexado, se encuentra en espacio liberado. Coincidencia de texto: solo sobrevivió el texto del enlace, del modo en que PyWMIPersistenceFinder encuentra los enlaces.
¿Son maliciosos SCM Event Log Consumer y BVTConsumer?
No, cuando coinciden con lo que instala Windows: el enlace SCM Event Log viene con Windows Vista y posteriores, y el enlace BVT (cscript KernCap.vbs) es un resto inofensivo en imágenes de la época de Windows 7. La herramienta comprueba también el contenido y señala un nombre predeterminado con contenido distinto.
¿Puede saber cuándo se creó una suscripción?
No de forma fiable. El repositorio no almacena ninguna marca de tiempo documentada por objeto. Cada cabecera de instancia tiene dos FILETIME que a menudo siguen el momento en que se escribió la instancia; se muestran como pistas. Correlacione con el ID de evento 5861 en Microsoft-Windows-WMI-Activity/Operational, que registra los nuevos consumidores permanentes.
¿Qué es la vista Evidencia de ejecución (SCCM)?
En equipos con el cliente de Configuration Manager (SCCM / ConfigMgr), el repositorio también contiene CCM_RecentlyUsedApps en root\ccm\SoftwareMeteringAgent: un registro por ejecutable y usuario con LastUsedTime (el último inicio de ese usuario, un CIM DATETIME que lleva su desfase respecto a UTC), un recuento de inicios y la información de versión del archivo. La herramienta lo lee del mismo OBJECTS.DATA, recupera copias antiguas del espacio liberado y añade un rango de tiempo. Sin el cliente de ConfigMgr no existen estos datos.