Another simple tutorial tonight. CobaltStrike is very flexible C2 framework that allow the adversaries to be so creative in order to develop their arsenal. In this article, I would like to share simple tutorial in order to develop Beacon Object Files (BOF)
What is Beacon Object Files (BOF)
A Beacon Object File (BOF) is a compiled C program, written to a convention that allows it to execute within a Beacon process and use internal Beacon APIs. BOFs are a way to rapidly extend the Beacon agent with new post-exploitation features.
Why consider implementing a Beacon Object File (BOF) when CobaltStrike already incorporates features for loading .NET applications? The key distinction lies in the BOF’s minimal footprint and the fact that its payload runs directly within the beacon, as opposed to loading a .NET application, which spawns a sacrificial process, potentially generating more noise and a larger footprint. Another aspect to ponder is the potential downside of running the BOF within the agent: a crash in the BOF could lead to the agent itself crashing, resulting in a loss of connection
Below are the general advantages
- OPSEC Considerations: The operation is specifically designed to execute within the Beacon process, eliminating the need to create new processes, thereby enhancing operational security.
- Efficient Memory Usage: The utilization of Malleable C2 profiles within the process-inject block enhances memory management, resulting in efficient resource usage.
- Compact Size: BOFs are notably smaller compared to equivalent Reflective DLLs, which is crucial for operations with limited bandwidth, such as DNS communication, minimizing data transfer overhead.
- Simplified Development: The implementation involves straightforward C code compiled with a Win32 C compiler such as MinGW or Microsoft’s compiler, eliminating the need for complex project configurations.
Hello World
The very basic BOF code structure is below.
#include <windows.h>
#include "beacon.h"
void go(char * args, int alen) {
BeaconPrintf(CALLBACK_OUTPUT, "Hello World: %s", args);
}
To compile the code above with Visual Studion is just with the very simple line below
cl.exe /c /myBOF.c /myBOF.o
To enhance your BOF development process, consider utilizing the Visual Studio template accessible on GitHub at https://github.com/Cobalt-Strike/bof-vs. This template is recommended for its well maintained github repository, which enables smoother testing and simplification of code during the development phase.
Listing Process
Below is the a bit complex code that I created in order to list out the running process in the victim machine.
bof.cpp
I have an example demonstrating the importance of utilizing the Windows API. It is crucial to declare the desired Windows API in order to customize it as necessary. This declaration can be achieved using DFR_LOCAL, which is a C macro found in helpers.h. For a more detailed explanation of the differences between DFR_LOCAL and DFR, please consult the GitHub link provided earlier.
#include <Windows.h>
#include "base\helpers.h"
#include <tlhelp32.h>
extern "C" {
#include "beacon.h"
bool IsProcessRunning() {
DFR_LOCAL(KERNEL32, Process32First);
DFR_LOCAL(KERNEL32, Process32Next);
DFR_LOCAL(KERNEL32, CloseHandle);
DFR_LOCAL(KERNEL32, CreateToolhelp32Snapshot);
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
const auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
do {
BeaconPrintf(CALLBACK_OUTPUT, "Process Name: %s\n", entry.szExeFile);
} while (Process32Next(snapshot, &entry));
CloseHandle(snapshot);
return false;
}
void go(char* args, int len) {
IsProcessRunning();
}
}
Running the BOF

Output

More BOF Samples
You can visit this github repository https://github.com/N7WEra/BofAllTheThings in order to enhance your BOF development skill.