In days of yore, there existed a humble batch, whence emerged the WMI, and it didst hold dominion o’er the realm of Windows contraptions for a considerable span until it was entwined with the might of PowerShell.
An event filter is a condition that should be met for something to happen. What’s the something? This something is an Event Consumer (script or executable). Binding is used to tie these two guys up. To set up, up this thing we can use PowerShell or mofcomp.exe
(compiles MOF
files into OBJECTS.DATA
). It is similar to scheduled tasks but much more flexible, robust and capable. Malware has been using WMI for a while, the pioneer being the notorious 🦠 Stuxnet.
⚠️ WMI consumers run with SYSTEM privileges.
There are two ways to interact with WMI: wmic
utility (running as a process wmprsve.exe
) and PowerShell (many cmdlets are wrappers around WMI). When you create a filter-consumer-binder thingy, it’s added to a MOF file which is some WMI repo. It is used to register new classes into the WMI repo. Set-WmiInstance
or CreateInstance
can also be used. To note, Metasploit can do that as well (PowerShell commands under the hood?).
wmic /?
wmic /node:<IP> startup list full
wmic /node:<IP> nicconfig get
wmic /node:<IP> process get
Types
The first two types are beloved attackers because they give the best capabilities. The LogFileEventConsumer
and NTEventLogEventConsumer
could be used to cover the tracks, while SMTPEventConsumer
could be utilised for C2C, but I have not researched that.
- ActiveScriptEventConsumer 🔥 - execute a
vbs
orjs
script. - CommandLineEventConsumer 🔥 - start a process.
- LogFileEventConsumer - write to logs.
- NTEventLogEventConsumer - log message to event logs.
- SMTPEventConsumer - email via SMTP.
- Custom - one needs a COM object to use that.
Whitelist
There are not too many default WMI consumers, so it’s pretty trivial to whitelist those.
SCM Event Log Consumer
. This WMI consumer monitors events related to the Service Control Manager (SCM) on a Windows machine. It captures service start, stop, and failure events, allowing administrators to track and troubleshoot service-related issues.TSLogonFilter
- filters and captures events related to Terminal Services logon on a Windows machine. It enables administrators to monitor and log user logon activities, session creation, and other related events in a Terminal Services environment.KernCap.vbs
- acts as a WMI consumer and is used to capture kernel events on a Windows machine. It allows administrators to monitor and log events related to the Windows kernel, such as driver loading, system crashes, and other low-level system activities.BVTFilter
- filters and captures events related to Boot Verification Test (BVT) on a Windows machine. BVT is a testing mechanism Microsoft uses to verify the integrity and functionality of the Windows boot process. The BVTFilter consumer helps monitor and log events associated with this testing process.RAevent.vbs
- used for capturing events related to Remote Assistance (RA) sessions on a Windows machine. It allows administrators or remote support personnel to monitor and log events related to RA sessions, including session initiation, user interaction, and session termination.NTEventLogConsumer
- captures events from the Windows Event Log. It can monitor and log various events recorded in the Event Log, including application, system, and security events. Its purpose is to provide a general mechanism for capturing events from the Windows Event Log.TSLogonEvents.vbs
- designed to capture events related to Terminal Services logon on a Windows machine. It enables administrators to monitor and log user logon activities, session creation, and other related events, specifically in a Terminal Services environment.RmAssistEventFilter
filters and captures events related to a Windows machine’s Resource Manager Assistance (RmAssist) feature. RmAssist is a Windows Server feature that assists in managing resources for virtual machines. The RmAssistEventFilter consumer allows administrators to monitor and log events related to resource management activities.WSCEAA.exe
(Dell) - ???
📚 References: pentest lab article, SANS article, https://www.sans.org/blog/finding-evil-wmi-event-consumers-with-disk-forensics/?utm_medium=Social&utm_source=Twitter&utm_content=WMI%20Forensics_Blog_VMR&utm_campaign=DFIR%20Blog, https://www.sans.org/blog/wmic-for-incident-response/, https://isc.sans.edu/diary/Tip+of+the+Day+-+Like+a+Kid+in+a+WMIC+Candy+Store/1622
📘 BTFM
# See the consumers
Get-WmiObject -Namespace root\Subscription -Class ___EventFilter
Get-WmiObject -Namespace root\Subscription -Class ___EventConsumer
Get-WmiObject -Namespace root\Subscription -Class ___FilterToConsumerBinding
Get-WmiObject -Namespace root\Default -Class ___EventFilter
Get-WmiObject -Namespace root\Default -Class ___EventConsumer
Get-WmiObject -Namespace root\Default -Class ___FilterToConsumerBinding
# Create consumers
Set-WmiInstance
CreateInstance
# Spot processes NOT running from Windows folder. You see a system process here - red flag 🚩
wmic PROCESS WHERE "NOT ExecutablePath LIKE '%Windows%'" GET ExecutablePath
# remote management
# list autoruns
wmic /node:IP startup list all
wmic /node:IP process get # get process list
wmic /node:IP nicconfig get # net config on a remote system
.\Modules\Process\Get-ProcsWMI.ps1 | Out-GridView # Kansa's Module to pull info about ProcsWMI from the live system and display in a user-friendly mode.
🛠️ autorunsc
and 🛠️ Kansa
both can get the artefacts associated with this mechanism. Also, 🛠️ PoSh-R2
(here) and Velociraptor
are both tools to use for the collection.
Terms
cmdlet - put certain enhanced operating system functions into effect when usung powershell, example: Get-Help
.
WMI (Windows Management Instrumentation). Some of the functions are available through powershell cmdlets. Use Get-Command -Noun WMI*
to get all WMI cmdlets. On my Windows VM (Parallels, Windows insider) I got this result:
PS C:\Users\user> Get-Command -Noun WMI*
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Get-WmiObject 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Invoke-WmiMethod 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Register-WmiEvent 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Remove-WmiObject 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Set-WmiInstance 3.1.0.0 Microsoft.PowerShell.Management
WMI cmdlets were deprecated accourding to the doc, so the recommendation is to start using CIM (Common Information Model). However, CIM is using WIM under the hood anyway. This is what I’ve got on the WinVM:
PS C:\Users\user> Get-Command -Module CimCmdlets
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Export-BinaryMiLog 1.0.0.0 CimCmdlets
Cmdlet Get-CimAssociatedInstance 1.0.0.0 CimCmdlets
Cmdlet Get-CimClass 1.0.0.0 CimCmdlets
Cmdlet Get-CimInstance 1.0.0.0 CimCmdlets
Cmdlet Get-CimSession 1.0.0.0 CimCmdlets
Cmdlet Import-BinaryMiLog 1.0.0.0 CimCmdlets
Cmdlet Invoke-CimMethod 1.0.0.0 CimCmdlets
Cmdlet New-CimInstance 1.0.0.0 CimCmdlets
Cmdlet New-CimSession 1.0.0.0 CimCmdlets
Cmdlet New-CimSessionOption 1.0.0.0 CimCmdlets
Cmdlet Register-CimIndicationEvent 1.0.0.0 CimCmdlets
Cmdlet Remove-CimInstance 1.0.0.0 CimCmdlets
Cmdlet Remove-CimSession 1.0.0.0 CimCmdlets
Cmdlet Set-CimInstance 1.0.0.0 CimCmdlets
Analysis with WMI
# Get autostarts
wmic /node:<IP> startup list full
# get processes
wmic /node:<IP> process get
# network config
wmic /node:<IP> nicconfig get
# Prebuilt wmic scripts by Justin Hall on USB
wmic_lr.local.cmd & wmic_lr.remote.cmd
Analysis of CIM
Looks like the structure is as follows: all the commands start with GetCimInstance
. Get the stack version to determine wether to use WSMan protocol or DCOM:
For a remote machine you may use Test-WSMan -ComputerName dc01
. Running hostname
to get the local PC name and using this value in the previous command resulted in error. $PSVersionTable
worked fine for me. On newer versions DCOM is usually blocked by firewall 🔥.
$DCOM = New-CimSessionOption -Protocol Dcom
$Cred = Get-Credential
$CimSession = New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred
Privileges
Powershell has the exact same privileges as when you are using GUI. For example, when runnning Powershell as local admin, you might get an “access denied 🙅♀️” error trying to connect to a remote machine. In this case you have two options:
- restart Powershell with domain admin privileges (less secure since you’d end up using this privileged window to do other non-privileged stuff);
- use per-command privilege escalation using
Credentials
parameter:$CimSession = New-CimSession -ComputerName dc01 -Credential (Get-Credential)
. Then query the remote machine using this session:Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
.
Examples
# get the serial
Get-CimInstance -ClassName Win32_BIOS | Select-Object -Property SerialNumber
# these two options return the same result:
# 1
(Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber).SerialNumber
# 2
Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -ExpandProperty SerialNumber
# query a remote PC
Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
# might get an "access denied" error
Resources
[1] Official Docs