COFF Mixing
Mix a capability with benign code and output a ready-to-link COFF
Project Files
Background
This project is a thought exercise to use Crystal Palace features to output a link-ready COFF that's a potential alternative to a shellcode runner. The benefit of this approach is that making our capability part of a valid PE, we're free of the memory-injected context that often differentiates good from bad in detections. For blue teamers, this modality is an opportunity to develop and evaluate defenses without the presumption of memory injection context.
Here are the features that come into play:
- Linking a capability object to a PE means we live in image memory without hacks
- Dynamic Function Resolution hides the capability's imports
- COFF merging and function order randomization (+disco) mix capability functions with benign code
-
make coff +unwindgenerates x64 stack unwinding data in the output--giving the OS what it needs to unwind our call stacks. - The
stripcommand removes target symbols from our capability - ised, register randomization, block order shuffling, and constant blinding give us tools to shape our capability content
How to use
(1) Write or adapt a base program to link your capability to:
(2) Run the capability through COFF mixing to create something ready-to-link
./link mixer.spec /path/to/file.o out.x64.o
(3) Use another build chain to compile the base program and link the post-mix capability to it
x86_64-w64-mingw32-gcc -mwindows base.c out.x64.o -o go.exe
Notes
The mixer.spec script operates in two phases. The first phase processes and outputs the capability as a ready-to-mix COFF. The first phrase is in the capability label. This is where our capability, written to PICO conventions, is paired with PIC services (e.g., dynamic function resolution) and optimized/modified to our satisfaction.
The second phase is the mixing phase. Here, we use make coff +unwind to generate .xdata and .pdata for our output COFF. This restores table-based stack unwinding for x64 programs. Here, we also use +disco to direct Crystal Palace to randomize the order of functions in the output COFF. This is the mixing part of our COFF mixing. As it means our capability no longer exists as one contiguous thing, but is instead interspersed with other (presumably well known) stuff.
We have to merge in a mixing target too. This example just uses a program I wrote with several functions that do very little. But, I encourage you to try compiling things from various libraries and mixing in some cocktail of them. You could also split this process into two .spec files too, to allow different mixing personalities.
The mixed-in program has to pass muster with what Crystal Palace can process. I recommend using compiler flags to disable jump tables and avoid other things that annoy this linker. This is necessary because Crystal Palace has to lift, transform, and lower the mixed content the same as your capability content. If you intend to execute parts of the mixed-in code, your mixed-in code must follow Crystal Palace's rules too (e.g., no exceptions).
The built-in coffparse and disassemble tools are great for observing the effect of your transformations after each run.
Can't I just compile my own EXE or DLL from my capability source code?
Yes, absolutely. You can. But, I want to zoom out to what's going on here. The goal of Tradecraft Garden is to separate the development of capability and tradecraft. To do this, Crystal Palace has to solve the time-of-use composition problem. That is, dynamically assembling a capability to decorate it with tradecraft--based on a user's preferences. Part of this process includes letting the user select an output modality (e.g., PIC, loader-paired PICO, etc.). COFF is another output modality. COFF mixing is another example of tradecraft that's possible with these time-of-use composition primitives.
License
This project is licensed under the BSD License.