Bluffy the AV Slayer
As an experiment, we converted default Cobalt Strike shellcode into various forms to see how it would do against static detection. Turns out, quite well...
Last updated
As an experiment, we converted default Cobalt Strike shellcode into various forms to see how it would do against static detection. Turns out, quite well...
Last updated
proposed an idea:
How will static detection fare against shellcode hidden within realistic datatypes?
Avoiding all kinds of encryption and compression, two came to mind: and .
This function has already seen weaponisation, namely from which does just that. So, we spent some time thinking of methods we could use to do this, and we came up with a tool:
Bluffy takes in a bin file, and has the ability to wrap that bin file up into, currently, four different masks:
SVG
CSS
UUID
CSV
These are not uniform, they will require different setup. Lets get into a rundown of the examples and their ability to handle Windows Defender.
The one missing from this list that we wanted to include is CLSID. That is because we thought we would leave that one as a task for the reader if they felted so compelled. We also had plans for Json, but never got around to it. And then the final type which we couldn't think of a solution for, but there must be!, was JavaScript.
These are not uniform, they will require different setup, but we have tried to standardise it as much as we can. So, as of now, UUID is the only one which will call VirtualAlloc
and VirtualProtect
(so read, conversion writes, and then update the page); the rest will simply return a unsigned char
. Otherwise, it's pretty straight forward to add. In future, including some more randomisation to add in some more noise would be good, but as a minimal proof of concept, it works for now.
Before going into some examples of three of these masks vs. Defender, two disclaimers:
This was only looked at from a static perspective. If Defender catches this on execution, we don't care...
In a typical Defender-fashion, every other execution passed the dynamic detection.
Lets get into a rundown of the examples and their ability to handle Windows Defender.
First up, UUID
. This is by far the easiest one to use. Here is the API declaration:
This function takes in a string and returns a pointer to the now converted UUID. What makes this so useful is the second parameter: UUID *Uuid
. This parameter will automatically write the data to memory, so all that it needs are allocation and execution. Here is the function to allocate and write:
And then to execute it:
How does it fair against Defender:
It exceeded its requirement, it bypassed both static detection and execution.
If this was to render, it would be:
Testing via Windows Defender:
Another one down.
The next one we thought obvious was CSS, it allows for a whole bunch of different places to store CSS. The following example shows the shellcode embedded into the RGB values of a border:
Using similar methods to SVG, it can be regexed out.
Running this against Defender:
Another one worked.
Out of these 3 techniques, they all bypassed Defender (statically) consitently. We had mixed responses against runtime detection, but that was not the focus of what we were looking for. We found that this method, naturally, has a much lower entropy value too. In hindsight, its kind of obvious that this type of masking would cause static detection to break because its literally just integer values in various datatype formats. This idea started as a meme and ended as a bypass (kinda) without going F U L L S T E G A N O G R A P H Y.
Again, because only execution is needed at this point, anything can be used to trigger it. Take a look at for a comprehensive list.
For the reader who hasn't used SVG to pop XSS, SVG is the . It's got some fanciness for appsec nerds, but what we liked was the XML structure and the plethora of places to drop integers.
Here is an example SVG from :
Our solution here was to take all the available integers from and split shellcode into them. Here is a snippet:
To achieve this, regex was required. regex was what we went for, with a substitution on double quotes and "cm". In order to even do regex, we had to go down a bit of a rabbit hole. After a lot of Googling, we eventually landed on . This was new to us and eventually hacked something together based on .
The code is available on .