WMI was designed to allow local and remote system administration using DCOM or WSMan, it's enabled on all systems by default. Generally it's used to get information about a system, set parameters, execute methods and subscribe to events.
From an offensive PoV, WMI is excellent for recon, remote code execution, persistence and convert storage as WMI-based detection is far behind the rest. WMI persistence can technically be considered RCE as well but it doesn't involve invoking a method.
WMI uses SQL-like syntax, for example
SELECT [Class property name / names | *] FROM [Class name] <WHERE [Condition]>
SELECT * FROM Win32_Service WHERE Name = "PSEXESVC"
PowerShell is considered to be the best tool to interact with WMI and here are some commands to interact with the service
Get-WmiObject-Class Win32_ServiceGet-WmiObject-Class Win32_Service -Filter 'Name = "WinDefend"'Get-WmiObject-Class Win32_Service -Filter 'Name = "WinDefend"'-Property State, PathNameGet-WmiObject-Namespace 'root/cimv2'-Query 'SELECT State, PathName FROM Win32_Service WHERE Name = "WinDefend"'Get-CimInstance-ClassName Win32_ServiceGet-CimInstance-ClassName Win32_Service -Filter 'Name = "WinDefend"'Get-CimInstance-ClassName Win32_Service -Filter 'Name = "WinDefend"'-Property State, PathNameGet-CimInstance-Namespace 'root/cimv2'-Query 'SELECT State, PathName FROM Win32_Service WHERE Name = "WinDefend"'
Most WMI classes are not well documented but we can use WMI to query for them
SELECT [Class property name[s]|*] FROM [INTRINSIC CLASS NAME] WITHIN [POLLING INTERVAL] <WHERE [CONSTRAINT]>
SELECT [Class property name[s]|*] FROM [EXTRINSIC CLASS NAME] <WHERE [CONSTRAINT]>
Register-WmiEvent -Query 'SELECT ProcessName FROM Win32_ProcessStartTrace' -Action { Write-Host "New process: $($EventArgs.NewEvent.ProcessName)" }
Register-CimIndicationEvent -Namespace root/subscription -Query 'SELECT * FROM __InstanceCreationEvent WHERE TargetInstance ISA "__FilterToConsumerBinding"' -Action {Write-Host 'New WMI persistence!'}
Event queries can persist beyond reboots and execute something in response instead of just being executed in the context of the PowerShell process they're executed from; for this to be possible there are 3 requirements
__EventConsumer: the action to execute
__EventFilter: the event to trigger off of
__FilterToConsumerBinding: binds the filter and consumer together