Beacon Object Files (BOFs)
Beacon Object Files (BOFs) are a post-ex capability that allows for code execution inside the Beacon host process. The main advantage is to avoid the fork & run pattern that commands such as powershell, powerpick and execute-assembly rely on. Since these spawn a sacrificial process and use process injection to run the post-ex action, they are heavily scrutinised by AV and EDR products.
BOFs are essentially tiny COFF objects (written in C or C++) on which Beacon acts as a linker and loader.
To get started with writing a BOF, you'll want the Beacon header file - beacon.h (https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/beacon.h)
- Hello World
To compile on Windows, open the x64 Native Tools Command Prompt for VS 2019, ensure your hello-world.c and beacon.h files are in the same directory, then run: cl.exe /c /GS- hello-world.c /Fohello-world.o
. If on Linux, then: x86_64-w64-mingw32-gcc -c hello-world.c -o hello-world.o
.
To execute the BOF:
beacon>
inline-execute \path\to\hello-world.o
(This built-in inline-execute command expects that the entry point of the BOF is called go. Otherwise, we willsee an error)
- Integrating BOFs in Agressor
BOFs can be integrated with Aggressor by registering custom aliases and commands.
- Handling Arguments
Naturally, there will be times where we want to pass arguments down to a BOF. A typical console application may have an entry point which looks like: main(int argc, char *argv[]). But a BOF uses go(char * args, int len).
Valid data formats and how to unpack them:
Format | Description | Unpack Function |
b | Binary data | BeaconDataExtract |
i | 4-byte integer (int) | BeaconDataInt |
s | 2-byte integer (short) | BeaconDataShort |
z | zero-terminated+encoded string | BeaconDataExtract |
Z | zero-terminated wide string | (wchar_t *)BeaconDataExtract |
For example, if we want to provide a username to our BOF:
- Calling Win32 APIs
APIs such as LoadLibrary and GetProcAddress are available from a BOF, which can be used to resolve and call other APIs at runtime. However, BOFs provide a convention called Dynamic Function Resolution (DFR), which allows Beacon to perform the necessary resolution for you.
Example:
- Interestings BOFs
CS-Situational-Awareness-BOF (https://github.com/trustedsec/CS-Situational-Awareness-BOF)
BOF.NET (https://github.com/CCob/BOF.NET)
NanoDump (https://github.com/fortra/nanodump)
InlineWhispers (https://github.com/outflanknl/InlineWhispers)
Last updated