Today we are releasing a new tool to help red teamers avoid detection. Shellcode is a small piece of code that is typically used as the payload in an exploit, and can often be detected by its “signature”, or unique pattern. Shellcode Mutator mutates exploit source code without affecting its functionality, changing its signature and making it harder to reliably detect as malicious.
Download Shellcode Mutator
One of the main benefits of writing your shellcode in assembly is that you have full control over the structure of the shellcode.
For example, the content and order of the functions in the source file can (obviously) be changed and the code compiled to produce a new version of your shellcode. These changes don’t have to be functional however, we can use automated tools to mutate the shellcode source so that each time we compile it the functionality stays the same, but the contents are changed.
This then means that the resultant shellcode will have a different size, file hash, byte order etc, which will make it harder to reliably detect both statically and in memory.
This ability is orthogonal to shellcode encryption etc, as at some point encrypted and encoded shellcode needs to be decrypted and decoded and descrambled so that it can actually be executed, and at this point it may get detected.
Let’s make use of a concrete, if a little contrived, example.
We can take the nasm source code for some MessageBox shellcode from Didier Stevens, compile it as per his instructions and inject it and we successfully get a message box – so far so good.
If we were to extract this shellcode as a blue teamer and want to write detections to catch it, we may note the hash, examine the contents and the disassembly and then write a yara rule to be able to catch it in memory or on disk.
As show below, we can take a quick peek at the binary using binary refinery.
We also note the sha256 hash is
Rizin can be used to examine the shellcode disassembly.
If we were to write a very quick yara rule for this, we may choose to focus on the initial bytes which perform some setup. Replacing the offsets (e.g.
[rbx + 0x113]) with wildcards and taking the bytes up to the second call at
0x0000001b we can write a quick yara rule that matches the shellcode in memory and on disk, but nothing else in e.g.
C:\Windows\System32 (testing for false positives).
The rule matches the shellcode on disk and in memory and triggers no false positives against anything in
So we have a reliable yara rule and add it to our threat hunts, all good right?
This is where the Shellcode Mutator project comes in. This simple python script will parse nasm source code and insert sets of instructions at random intervals that ‘do nothing’, but will then alter and byte order and file hash of the shellcode at the cost of increased size.
The script is easy enough to use, taking a source code ‘template’, an out file, a morph percentage and a flag to set
This script has some basic logic to check source lines but essentially has to sets of instructions that can be expanded upon, one for
x86 and one for
x64. Each entry in these instruction sets should, after all instructions have executed, leave all registers and flags in the same state as before they were executed to ensure that the shellcode can continue without erroring.
Along with some other logic, the script will place these instruction sets at random intervals (dictated by the morph percentage) before the instructions specified in the
If we run the script against our MessageBox shellcode, setting a morph percentage of 15% we get a source code file that is 57 lines instead of 53. Compiling that shellcode and executing the yara search shows that it is not caught and only the original shellcode matches.
Examining the disassembly of the binary file shows that it has inserted a nop (
0x90) instruction into the bytes that we matched upon (in addition to at other places). This of course also changed the file hash.
There is an element of luck of course. We need to make sure that we change enough bytes that any yara rules will no longer match without actually knowing what those yara rules are (or any other detections). Increasing the morph percentage then will increase the number of alterations made and the likelihood of bypassing any rules at the cost of increased shellcode size.
Of course the big question is, does our shellcode still run?