Finding Evil WMI Event Consumers with Disk Forensics
WMI abuse remains an easy and stealthy component of many modern attacks targeting Microsoft Windows. WMI can facilitate every aspect of the post-exploit kill chain using built-in tools with the added bonus (from the attacker’s perspective) of minimal available logging. WMI event consumers are a specialized form of persistence and code execution that can be traced back to the venerable Stuxnet and continue to be used by a wide variety of threat actors, including top-tier groups with ties to Russia and China like Cozy Bear, Mustang Panda, and Turla. WMI event filters can monitor for specific events and when triggered, enact event consumers that can then do things like run scripts and execute code. Event triggers can be based on time (e.g., every twenty seconds), the start of a specific service, at boot, whenever a user logs in, or thousands of other options. Administrative privileges are necessary, but once achieved, attackers can use WMI to create a backdoor that can be difficult to detect without proper monitoring. If you would like a deeper dive into WMI attacks, the research paper Windows Management Instrumentation Offense, Defense, and Forensics by Ballenthin, Graeber, and Teodorescu is still the definitive reference.
Auditing the Local WMI Repository
PowerShell-based collections, Event Logs, and Sysmon are all viable (and easy) options for discovering malicious WMI Event Consumers, but what about if you are looking at evidence from a system that is no longer running? While not ideal, there are situations where WMI analysis is necessary using only a copy of a hard drive (or equivalent).Luckily there are some capabilities available to assist. WMI event consumers are stored in a local database located in the \Windows\System32\wbem\Repositoryfolder.The WMI database consists of several files with the bulk of the information present in a file named OBJECTS.DATA. The WMI database is in a compressed binary format, making it challenging to interact with. Microsoft provides only sparse documentation on the database format and contents and a typical interaction with these files would normally consist of PowerShell or WMIC queries accomplished while the system is running. Another option is WMI Explorer, an open-source tool facilitating GUI introspection of the database. It can be an excellent tool when searching for something deep within the WMI database or for better understanding how it is composed.
Figure 1: WMI Explorer Showing a Malicious CommandLineEvent Consumer
A big limitation of WMI Explorer is it presumes you have access to the live system you are auditing. However, if you only have a disk image or a triage collection of the WMI folder, you can still perform similar analysis of the database. flare-wmi, from The Mandiant FLARE Team, is a set of Python-based code projects for parsing and interacting with the WMI database including a proof-of-concept GUI database parser. The figure below shows data within the GUI browser, but there are several even more useful command line scripts present in this repository such as show_filtertoconsumerbindings.py.
Figure 2: flare-wmi Offline WMI Parser
If you are looking only to audit WMI Event Consumers (a good idea to start with), David Pany wrote a simple script to search the OBJECTS.DATA file for instances of WMI event consumers and display the results.PyWMIPersistenceFinder.py provides output similar to what you might get from using the PowerShell cmdlet Get-WmiObject on a live system. For offline purposes, this script makes it dead simple to pull out WMI consumers—just export/collect the WMI repository folder and point the script at OBJECTS.DATA file. You will encounter false positives, but they are largely predictable, and the “evil” consumers will almost always stick out. As an example, the consumer on this slide is yet another encoded PowerShell script. By decoding the include base64 data, the script could be analyzed for malicious intent.
Figure 3: PyWMIPersistenceFinder Script Results
Tracking the Creation of Event Consumers
While auditing the local WMI repository is a good first step, it is also possible to identify the initial creation of a WMI event consumer. Evil WMI event consumers are created on a system via two primary methods: MOF compilation and PowerShell. Each has the potential to leave behind valuable clues.
MOF Residue
What exactly is a Managed Object Format (MOF) file? Think of it as a text file representing WMI class definitions and instances. MOF files are used by Windows to build the WMI repo. Many WMI repository definitions are initially defined via the MOF format. They can also be used to extend WMI and hence they are a common way to introduce malicious classes into the WMI repository. References to MOF files can be found in the WMI binary tree index, C:\Windows\System32\wbem\Repository\index.btr.
Standard system MOF files and most subsystem MOF files are all stored in the WBEM folder. While this is standard practice, MOFs can actually be stored anywhere and only the compiled MOF file is required to be present in the repository. Sadly, a MOF file can be named anything, be located anywhere, and even be deleted after it is introduced into the WMI repository. This makes finding malicious MOF files very difficult (though you might get lucky!)Mofcomp.exe is used to compile .MOF files and add them to the WMI repository. While the execution of mofcomp.exe could be an indicator, in practice it is used by the system frequently. The WMI database files are also updated frequently, meaning the NTFS modification times for Prefetch and the files in the \Windows\System32\wbem\Repository cannot be reliably used to identify when something malicious was added. Thus, there are few timeline artifacts available for this activity. To make matters worse, the MOF compiler allows remote namespaces, so supplying the “-N” switch with a remote machine name and MOF file will compile and insert the new classes into a remote system’s WMI database:
mofcomp -N \\[machinename]\root\subscription test.mof
In this scenario, the MOF file is not written to disk on the remote system, leaving even less artifacts. This is why collecting command lines from systems is so important (“mofcomp -N” would make an excellent threat hunting search).Luckily, there is still a chance MOF file residue may be left behind even if the originals are long gone. Our best chance is when the MOF file includes something named “#PRAGMA AUTORECOVER”. This is an optional field included near the top of a MOF file. “PRAGMA AUTORECOVER” ensures a copy of the MOF file is stored in case the WMI repository needs to rebuild itself. Think of this as a precaution to make sure your malicious entries do not eventually age out of the database. Figure 4 shows the compilation of a malicious MOF file using mofcomp.exe and the subsequent error provided when autorecover is not present.
Figure 4: MOF File Lacking Pragma Autorecover Directive
If an attacker chooses to include this statement, there should be some excellent forensic artifacts left behind to find the original MOF files. If this is the case, why do we see a lot of malicious MOF files in the wild that include this? The answer is probably a mix of ignorance of the detection risk along with the desire to keep the malicious classes in the WMI repository indefinitely. Remember that the use case for MOF files is largely persistence, which means they may be the only way the attacker has of getting back into the compromised network.When #PRAGMA AUTORECOVER is included within a MOF file, a copy of the file is stored within the C:\Windows\System32\wbem\AutoRecover folder. This provides an excellent opportunity to identify malicious introductions in the WMI database. The autorecover feature can also be accomplished via the mofcomp.exe tool by using the “-autorecover” parameter. When a backup copy is stored in this folder, it is renamed, so do not expect to see “evil.mof” within this folder. You may only see a handful of files in this folder and they will all be text-based, making analysis straightforward. Additionally, the file timestamps (creation and modification) can help identify outliers and help focus analysis on items modified or created during the expected time range of an attack.
Figure 5: MOF Files Present in AutoRecover Folder
When #PRAGMA AUTORECOVER is included within a MOF file, a Windows Registry entry is also created for that file. This will be located in the HKLM\SOFTWARE\Microsoft\Wbem\CIMOM key, under a value named “Autorecover MOFs.” The name recorded in this value will not be the original name, but it will include the folder path where it existed during compilation. The provided name may also indicate the type of consumer—in the following example, an evil “ActiveScript” consumer was present. The path is particularly important because almost all legitimate MOF files will be in the WBEM folder. Thus, anything present outside of the \Windows folder should be a prompt to perform a thorough review of the C:\Windows\System32\wbem\AutoRecover folder files on disk.
Figure 6: HKLM\SOFTWARE\Microsoft\Wbem\CIMOM Registry Key
PowerShell Creation Artifacts
You do not need a MOF file to set up an evil WMI event consumer. WMI object definitions can be created without a MOF file via direct insertion into the CIM repository using .NET code (PowerShell is often the common choice). It is a trade-off: PowerShell commands to import items are relatively straightforward (see Figure 7), but a MOF file can be a bit cleaner or easier when doing more complicated events like ActiveScript. More advanced adversaries may prefer PowerShell because it has the potential to be stealthier, effectively taking away even the nominal artifacts discussed above with respect to MOF files. However, if the system has at least PowerShell version 5, there are opportunities to collect artifacts via command-line auditing, local PowerShell ScriptBlock Logging and the PSReadline ConsoleHost_history.txt file. The PowerShell commands used are not particularly common and can make good search terms during threat hunting. As an example, the following PowerShell sets up c:\alg.exe as the evil payload with an event trigger of within 10 seconds of any service modification. Clearly some good search terms can be derived from these commands.
Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name=“wmi”;EventNameSpace="root\cimv2"; QueryLanguage="WQL";Query="SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Service'"}
Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=“wmi”;ExecutablePath=‘C:\alg.exe’;CommandLineTemplate =‘C:\alg.exe’}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=“wmi”;Consumer=“wmi”}
Figure 7: Sample PowerShell Commands for WMI Event Consumer Creation
Conclusion
WMI event consumers will continue to be abused in the wild as long as organizations fail to discover and remediate them. While live collection and analysis is preferable to scale efforts across a network, this post covered disk-based artifacts and tools available for use during deeper forensic investigations. A KAPE target exists to collect the required files for offline analysis, making it an easy check to perform during incident response forensic investigations.
Chad Tilbury has spent over twenty years conducting computer crime investigations ranging from hacking to espionage to multimillion-dollar fraud cases. He is a SANS Institute Fellow and co-author of FOR500 Windows Forensic Analysis and FOR508 Advanced Incident Response, Threat Hunting, and Digital Forensics. Find him on Twitter @chadtilbury