Today RSM US has released a new research project dubbed Crimson Forge. The project originated from the desire to add evasion capabilities to existing, native payloads. The intention is to target x86 and AMD64 shellcode and automatically rewrite it to evade signature based detections. The issue with many existing implementations are that they rely on “encoding” the payload and converting it to something which is self-modifying. This has a couple of note worthy disadvantages including:
- The original payload is eventually decoded and will exist unmodified in memory shortly after execution has begun.
- The payload must exist in a memory segment with the necessary permissions to allow it to be both executable and writable. This means the memory will need RWX permissions, and allocation such a region is very often identified as suspicious activity and thus scrutinized.
What Crimson Forge Does
The approach that Crimson Forge takes is to re-write the original payload such that neither of these qualities are present. It does so using a multi step process that ultimately yields code that is functionally equivalent, is not self-modifying and does not call any additional API methods.
- Ingest the original binary shellcode by disassembling it with Capstone and “lifting” it to an intermediary representation (IR) using LibVEX.
- Organize the ingested code instructions into basic execution blocks, similar to the graph view from Binary Ninja or IDA Pro.
- For each basic block, construct a graph of the positional constraints (the positional-constraint-graph or PCG) of each instruction using their respective IR. This maps the relationship between which instructions in a basic block must be run before and after each other instruction within the same basic block.
- Optionally process each instruction in each block and substitute them with functional equivalents, effectively de-optimizing the executable code. This phase for example will replace a push instruction with an explicit write to and subtraction of the stack pointer. Equivalents are replaced into the PCG generated in the previous step.
- For each basic block, reconstruct a linear set of instructions while honoring the positional constraints resulting in them being shuffled. Since step 4 would have injected new instructions into the graph, when this step is executed, there is by design no guarantee that the injected instructions will be sequential in the resulting output, e.g. if
push 0x10
is replaced withsub esp, 4
,mov [esp], 0x10
it is possible that another instruction may be placed in the middle.
The resulting binaries are functionally equivalent, with no additional API calls to trigger behavioral detections. Crimson Forge is in fact agnostic of the underlying platform details such as the Application Binary Interface (ABI). This means that Crimson Forge can process binary payloads so long as they are of a supported architecture (currently only x86 and AMD64) whether or not they target Windows, Linux, etc.
Running Crimson Forge
There are three primary ways of running Crimson Forge. There is the core CLI application crimson-forge
, the interactive crimson-forge-wizard
and the Metasploit module.
The core CLI provides quite a few options to tweak the functionality. This is the primary interface and exposes all available features. The most important options to specify are the input architecture (-a / --arch
), the input file and the output file. The wizard can be used to make the process of selecting the appropriate options easier. By running the interactive wizard, each necessary option can be specified one at a time, while selecting from appropriate values when available. At the end of the wizard, the options generated can optionally be written out to a file. These options can later be used with the core CLI by specifying ./crimson-forge @path/to/options.txt
.
Crimson Forge can integrate directly with Metasploit through the included Metasploit module. The module is an external evasion module. Once installed, simply use evasion/windows/crimson_forge
, set the necessary options and run
it. This module does not expose all of the functionality available, but streamlines the process of generating a payload using Metasploit and then processing it with Crimson Forge.
Supported File Formats
While Crimson Forge can process binary payloads as the input, it can also generate them into executable files. Currently only EXEs and Windows service-compatible EXEs are currently supported. The following table describes the currently supported formats for both architectures. The “Direction” column notes which formats are supported for input files as well as output (generated) files.
Format | Direction | Description |
pe:exe | out | A Windows portable executable file (.exe) |
pe:exe:svc | out | A Windows service-compatible portable executable file (.exe) |
raw | in / out | A raw, binary payload |
source | in / out | An assembly source file to a payload |
Crimson Forge can be downloaded from GitHub at https://github.com/zeroSteiner/crimson-forge.