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:
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