Back to Posts

WMI Persistence

Posted in Pentesting

Networks Engineered to Exploit.
- Windows/UNIX - Domains/Subnets - Initial/Post/Lateral - Low Cost VPN Ranges -

WMI Basics

WMI is a core functionality of the Windows OS that has been part of Windows for a long time (see also: DCOM and CIM). From Microsoft: “Windows Management Instrumentation (WMI) is the infrastructure for management data and operations on Windows-based operating systems.” Read up on official MS documentation to learn more about the WMI architecture

From a security perspective WMI can be used for Intrusion Detection, Recon, Remote Access, Persistence and much more. This post will focus on Persistence via permanent WMI Event Subscriptions. This topic isn’t necessarily new and has been documented by researchers in the past - be sure to follow-up with the sources at the bottom.

WMI Subscriptions

Simply put, a WMI Event Subscription triggers an action when an event occurs. Actions and Events can be defined by the user creating a WMI Event Subscription. In WMI event subscription lingo, actions are called Consumers and events are called Filters. There is also a third component that links the two together called Binding. In most cases you may want one event (Filter) to trigger one action(Consumer) but sometimes you may want one event to trigger multiple actions - this is where Binding is useful.

Here are 3 PowerShell commands to display the 3 subscription classes:

Get-WMIObject -Namespace root\Subscription -Class __EventFilter
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer

  • The EventFilter has multiple properties, but the primary property/function of the Filter is the WMI query. The query is written in WMI Query Language (WQL) which is similar to SQL syntax. We’ll run through multiple subscription examples so this will make sense in a bit.
  • The Binding is self-explanatory - just like the WMI class says: FilterToConsumerBinding. These properties link the Filter and Consumer, plastering them together.
  • Since the EventConsumer is basically the action, this will include the payload or what will happen when something matches the Filter aka WMI query. There are 5 Consumers to choose from when creating a subscription.

      LogFileEventConsumer - Writes custom strings to a log file.
      CommandLineEventConsumer - Runs an arbitrary process.
      SMTPEventConsumer - Send an email via SMTP.
      ActiveScriptEventConsumer - Run a script in an arbitrary language.
      NTEventLogEventConsumer - Logs a message to the Windows Event Log.

We’ll need all three of these classes for a subscription to function properly.

WMI Event Subscriptions can be created with PowerShell or WMIC, however this post will focus on creating WMI events via Metasploit and Empire modules. Now that the WMI basics are covered, we’ll move onto the practical examples.

Practical Examples

Scenario: You have a Meterpreter session on a Windows 10 target as Admin and would like to maintain “file-less” persistence via a WMI Event Subscription.

First let’s check the current (in this case default) wmi subscriptions by dropping into a shell running the 3 WMI Event Subscription PowerShel commands from above.

alt text

It seems there is only one default filter, consumer and binding as seen by the 3 wim queries. Now we have a basic idea of what each command will pull back to us. Time to create persistence.

Background the meterpreter session, and use the windows/local/wmi_persistence module. I’d recommend reading the info about this module before executing it. Here’s the official documentaiton - otherwise show info via msf.

alt text

The module provides the attacker 5 possible methods to use. Each method is a Filter (event) which will trigger what ever is set in the Metasploit payload option as a poweshell command. A few of these methods will be covered, but lets start with the default EVENT method (as seen above).

According to the module info, the property PERSISTENCE_METHOD of EVENT will trigger the Consumer when the Windows event log ID is matched. Running this default setup will trigger the payload when a failed login attempt is made by user BOB. This module is set to our background session and ran.

alt text

Now let’s interact with our current backgrounded session, drop into a shell and verify the wmi subscription was pushed successfully.

alt text

Checking the EventFilter and EventConsumer it seems they were indeed pushed. A defender should see these as obvious red flags, specifically the powershell command in the Consumer…as long as they’re checking subscriptions.

Now let’s say our meterpreter session dies of dysentary and we want to re-establish a new session. As the module says, we can use smbclient to connect to the targets C$ with user BOB and a random password. We just need to trigger a failed login attempt (Event ID 4635) with username BOB.

alt text

Great (or scary) it looks like the module worked and we have clean stable file-less persistence on the target.

More Module Methods

A few other methods within this module are the PROCESS method and the LOGON method. After cleaning up the previous subscriptions and running the wmi module again using the PROCESS method we see a similar EventFilter with the query being fairly straightforward - execute consumer when process “thunderbird.exe” starts. The consumer will be the same powershell payload in each method.

alt text

Now, testing the LOGON method will trigger the consumer to execute after 4 minutes of system uptime. This method however can be seen in sysinternals Autoruns under the WMI tab. Be advised, after trying multiple methods and payloads, the metapsloit module method of EVENT and PROCESS also showed up in Autoruns…and sometimes did not (within my lab).

alt text

Let’s try out powershell Empire.


Empire has a similar wmi persistence module that will create a subscription just like the LOGON method via metasploit..or the metasploit LOGON method is just like this Empire module (..or PowerSploit module). The WQL is identical but there’s no reason to reinvent the wheel. Here’s the description.

(Empire: powershell/persistence/elevated/wmi) > info

  Persist a stager (or script) using a permanent WMI
  subscription. This has a difficult detection/removal rating.

After acquiring an agent and setting the properties, the task is run. If you’re unfamiliar with Empire check out my Empire Basics post

alt text

On the target machine, checking Autoruns and the EventFilter shows the same results as the previous Metasploit example. Ultimately it seems the Metasploit LOGON method and this Empire module are the same.

To remove subscriptions manually, use the wmic commands below replacing the name property with your own.

wmic/namespace:\\root\subscription PATH CommandLineEventConsumer WHERE Name="empire" DELETE
wmic/namespace:\\root\subscription PATH __EventFilter WHERE Name="empire" DELETE
wmic/namespace:\\root\subscription PATH __FilterToConsumerBinding WHERE Filter='__EventFilter.Name="empire"' DELETE


Malicious WMI Event Subscriptions can be fought with Defensive WMI Event Subscriptions. A defender could create a subscription that would alert whenever a new subscription is created or when an existing (defensive) subscription is deleted.

If you are running Sysmon keep an eye out for WMI subscription event ID’s 19-21.

Event ID 19: WmiEventFilter activity detected
Event ID 20: WmiEventConsumer activity detected
Event ID 21: WmiEventConsumerToFilter

Otherwise you can utilize powershell and WinRM to check subscriptions via PowerShell Remoting.

Invoke-Command -ComputerName TARGET -ScriptBlock { Get-WMIObject -Namespace root\Subscription -Class __EventFilter } -credential USERNAME

alt text

As mentioned previously this method is fairly well documented and not necessarily new. Be sure to checkout the sources below for further information.

DHS Writeup on WMI and persistence

Attack method on MITRE

Thorough write-up covering multiple facets of WMI

Manual subscription creation using wmic

WMI Event Subscription Basics

More on WMI Persistence Detection

Custom Cyber Ranges >>

Read Next

SELinux Intro