Skip to content

WMI Event Subscription Persistence Explained

How WMI event subscription persistence works: __EventFilter, event consumers and __FilterToConsumerBinding, where they are stored and how to find them.

Published on 4 min read

TL;DR. A WMI event subscription is three objects: an __EventFilter (a WQL query that describes when), an event consumer (what to do) and a __FilterToConsumerBinding that wires them together. Registered permanently, it survives reboots and runs as SYSTEM. MITRE tracks it as T1546.003. The evidence lives in the CIM repository, and you can read it offline — deleted objects included.

The three pieces

WMI is Windows' management layer. Besides answering queries, it can react: when an event matching a query happens, it hands the event to a consumer. A permanent subscription is made of:

ObjectClassHolds
Filter__EventFilterName, Query (WQL), QueryLanguage, EventNamespace, CreatorSID
Consumera class derived from __EventConsumerthe action: command line, script, log file, event, e-mail
Binding__FilterToConsumerBindingFilter and Consumer references, CreatorSID

Windows ships five standard consumer classes:

  • CommandLineEventConsumer: CommandLineTemplate, ExecutablePath, WorkingDirectory. Started by the WMI provider host (WmiPrvSE.exe).
  • ActiveScriptEventConsumer: ScriptingEngine (VBScript or JScript) and either ScriptText or ScriptFilename. Run by scrcons.exe.
  • LogFileEventConsumer: appends Text to Filename.
  • NTEventLogEventConsumer: writes an event log entry.
  • SMTPEventConsumer: sends an e-mail.

Only the first two run arbitrary code, which is why most WMI persistence uses them.

Why attackers use it

A subscription needs administrator rights to create, but once in place it offers a lot:

  • It survives reboots and needs no file in a Run key, a service or a scheduled task.
  • The action runs as SYSTEM, parented to WMI processes that are always running.
  • The trigger can be anything WMI can see: a few minutes after boot, a user logon, a process start, a USB insertion, a time of day or a WMI timer.
  • It hides in plain sight: autoruns-style reviews that skip WMI miss it, and the repository is a binary database that few people open.

A classic example is a filter on Win32_PerfFormattedData_PerfOS_System that fires when SystemUpTime falls between 240 and 325 seconds, so the payload starts about four minutes after every boot:

SELECT * FROM __InstanceModificationEvent WITHIN 60
WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325

Bound to a CommandLineEventConsumer whose template is C:\ProgramData\Intel\m64.exe -svc, that is a complete persistence mechanism — it is exactly what the WMI Parser sample contains, on the fictional host FIN-WKS-07.

Where the evidence lives

Subscriptions are objects in the WMI repository, C:\Windows\System32\wbem\Repository:

They normally sit in the root\subscription namespace, but a subscription registered in root\cimv2 or root\default works too. The format is described in Inside OBJECTS.DATA.

Two properties matter a lot in a case:

  • CreatorSID on each object records the account that created it. A SID ending in -500, S-1-5-32-544 or a specific user's SID each tell a different story.
  • Deleted objects are not wiped. Their pages are released and overwritten only when WMI needs the space, so an attacker's clean-up often leaves the filter, the consumer or the binding behind. See recovering deleted WMI persistence.

What the repository does not give you is a documented creation time. Each instance record carries two undocumented FILETIMEs that often follow when it was written; treat them as leads. For timing, correlate with event ID 5861 in Microsoft-Windows-WMI-Activity/Operational and with Sysmon events 19 to 21, covered in the investigation checklist.

How to find it

  1. Collect the repository from a shadow copy, KAPE (WBEM target) or Velociraptor: how to collect the WMI repository.
  2. Parse it offline. Drop the folder on WMI Parser: it lists every binding with its filter and consumer, recovers deleted ones, and says for each object whether it came from the index or from carving.
  3. Separate the defaults. Windows installs an SCM Event Log subscription, and older images a BVT one. They are harmless when their content matches: see SCM Event Log Consumer and BVTConsumer.
  4. Read what is left: the trigger query, the command or the script, the paths and the creator.

Findings to look for: encoded PowerShell, binaries in user-writable folders (C:\ProgramData, C:\Users\Public, %TEMP%), script consumers, triggers on uptime or logon, and subscriptions outside root\subscription.

FAQ

What is WMI event subscription persistence?

An attacker registers a permanent WMI event subscription: an __EventFilter that describes an event, a consumer that describes an action, and a __FilterToConsumerBinding that links them. Windows then runs the action as SYSTEM every time the event happens, including after reboots.

Where are WMI event subscriptions stored?

In the WMI (CIM) repository, C:\Windows\System32\wbem\Repository, mainly in OBJECTS.DATA with its INDEX.BTR and MAPPING files. They normally live in the root\subscription namespace.

Which consumers matter for persistence?

CommandLineEventConsumer (runs a command line) and ActiveScriptEventConsumer (runs VBScript or JScript) execute code. LogFileEventConsumer, NTEventLogEventConsumer and SMTPEventConsumer write a file, an event or an e-mail.

Related articles

Step-by-step checklist for WMI persistence: live queries, the repository, event IDs 5860 and 5861, Sysmon 19-21, execution evidence and a safe clean-up.
The two WMI subscriptions Windows ships — SCM Event Log and BVTFilter/BVTConsumer — what they contain, why they are harmless, and how attackers can abuse the names.
Why deleted WMI filters, consumers and bindings survive in OBJECTS.DATA, how index walking and carving differ, and how python-cim and PyWMIPersistenceFinder compare.