Skip to content

SCM Event Log Consumer and BVTConsumer: Benign or Not?

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.

Published on 3 min read

TL;DR. Two WMI event subscriptions are Windows' own. SCM Event Log (SCM Event Log Filter → NTEventLogEventConsumer SCM Event Log Consumer) forwards Service Control Manager events to the event log. BVT (BVTFilter → CommandLineEventConsumer BVTConsumer, cscript KernCap.vbs) is a build-verification leftover on Windows 7-era images. Both are harmless when their content matches. Check the content, not only the name.

Why this matters

Any review of root\subscription finds these two first, and an analyst new to WMI may raise them as persistence. The reverse mistake is worse: an attacker who reuses a trusted name — or edits the default consumer — slips past a name-only allowlist. PyWMIPersistenceFinder already annotated both bindings as "common, possibly legitimate"; WMI Parser goes one step further and compares each property with what Windows installs.

SCM Event Log

ObjectExpected content
__EventFilter SCM Event Log FilterQuery = select * from MSFT_SCMEventLogEvent, QueryLanguage = WQL, EventNamespace = root\cimv2
NTEventLogEventConsumer SCM Event Log ConsumerSourceName = Service Control Manager, NameOfUserSIDProperty = sid
__FilterToConsumerBinding__EventFilter.Name="SCM Event Log Filter" → NTEventLogEventConsumer.Name="SCM Event Log Consumer"

It exists on Windows Vista and later. Its CreatorSID is usually S-1-5-32-544 (the Administrators group), since it is created at setup. The consumer writes an event log entry; it runs no code.

BVTFilter and BVTConsumer

ObjectExpected content
__EventFilter BVTFilterSELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA "Win32_Processor" AND TargetInstance.LoadPercentage > 99
CommandLineEventConsumer BVTConsumerCommandLineTemplate = cscript KernCap.vbs, WorkingDirectory = C:\\tools\\kernrate (the doubled backslashes are stored as such)
__FilterToConsumerBinding__EventFilter.Name="BVTFilter" → CommandLineEventConsumer.Name="BVTConsumer"

"BVT" stands for build verification test. The subscription would run a kernel profiling script when a processor stays above 99% load; C:\tools\kernrate\KernCap.vbs does not exist on a normal system, so nothing happens. It shows up on Windows 7 / Server 2008 R2-era images and on machines upgraded from them, and its CreatorSID is typically a local administrator (RID 500).

What should raise an eyebrow

  • A default name with different content: a BVTConsumer whose command is not cscript KernCap.vbs, a working directory elsewhere, a SCM Event Log Consumer that is a CommandLineEventConsumer, or a filter with another query. WMI Parser flags this as Default name, other content.
  • A KernCap.vbs that exists. If C:\tools\kernrate\KernCap.vbs is on disk, the dormant BVT subscription becomes a live one: read the script.
  • A third binding to a default filter or consumer. Attackers can bind their own consumer to an existing filter. Count the bindings, not only the objects.
  • Defaults in freed space with different content. A recovered older version of a default object means it was modified at some point.

Everything else is not automatically bad

Management agents, endpoint security products and vendor tools (hardware monitoring, configuration management) also register subscriptions. They are "not a Windows default", not "malicious". Identify the product from the names, the command lines and the paths, and compare with a clean machine of the same build.

FAQ

Is SCM Event Log Consumer malicious?

Not when it matches the Windows default: an NTEventLogEventConsumer with SourceName Service Control Manager, bound to the SCM Event Log Filter that queries MSFT_SCMEventLogEvent in root\cimv2.

What is BVTConsumer and kernCap.vbs?

BVTFilter and BVTConsumer are a build-verification leftover found on Windows 7 and Server 2008 R2 era images. The consumer runs cscript KernCap.vbs from C:\tools\kernrate when CPU load stays above 99%; the script does not normally exist, so nothing runs.

Should I delete the default WMI subscriptions?

No need when they match the defaults. What matters is a default name with different content: a changed query, another consumer class or a different command line.

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.
Why deleted WMI filters, consumers and bindings survive in OBJECTS.DATA, how index walking and carving differ, and how python-cim and PyWMIPersistenceFinder compare.
How WMI event subscription persistence works: __EventFilter, event consumers and __FilterToConsumerBinding, where they are stored and how to find them.