WMI Event Consumers


Created: 28.07.2022

A little theory… . 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 setup, this thing - use Powershell or mofcomp.exe (compiles MOF files into OBJECTS.DATA).

⚠ïļ WMI consumers run with SYSTEM privileges.

Init of event filter, consumer and binder are usually contained within a MOF file 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?). Example ðŸĶ : Stuxnet.

wmic /?
wmic /node:<IP> startup list full
wmic /node:<IP> nicconfig get
wmic /node:<IP> process get

Tools 🛠: Cmdlet Get-WmiOject can identify and delete entries, Kansa Framework, autoruns (Sysinternals).

📚 References: pentest lab article, SANS article.

📘 BTFM

 .\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.

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:

stack-version

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:

  1. restart Powershell with domain admin privileges (less secure since you’d end up using this privileged window to do other non-privileged stuff);
  2. 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.

cim-session-create

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

References

Expand… Something here