Let's write a Beacon Object File for Havoc C2 - Part 1
Learn how to use Windows APIs in a Beacon Object File (BOF).
In this series of posts, I will create a Beacon Object File (BOF) that works with Havoc C2. I will start by implementing simple functionality and gradually increase the level of complexity.
If this is the first time you are learning about BOFs, I recommend that you read my posts, Enhancing C2 agent via Beacon Object Files (BOF) and Creating a simple beacon object file for Havoc C2 for a quick introduction to BOF and BOF development.
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.
In this part, I will cover how to use Windows APIs in a BOF. While this might seem trivial to implement in a typical C or C++ program, it comes with a learning curve when implementing in a BOF. The reason for this is because a lot of common functions (e.g., strlen, strcmp, etc.) are not available via a BOF.
I am using Ubuntu 24.04 (with build-essential and mingw-w64 installed), Havoc C2 0.7 and Windows 10 target for this demonstration. I am assuming that there’s already a beacon from a Windows 10 machine calling back to Havoc C2.
I will start with a very simple Windows API, MessageBoxA. The Beacon API exposes equivalent to few Windows APIs but MessageBoxA is not one of them. To use MessageBoxA in a BOF, we need to include its prototype at the beginning of the file.
For MessageBox, this prototype is:
WINUSERAPI int WINAPI USER32$MessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);
The following command can be used to find the prototype of a Windows API:
grep -r " <WINDOWS API NAME>"
cd /usr/share/mingw-w64
grep -r " MessageBoxA"
As can be seen in the above screenshot, the prototype for MessageBoxA is included in the file /usr/share/mingw-w64/include/winuser.h.
While at it, let’s search for the prototype of GetLastError as well.
grep -r " GetLastError"
With prototypes in place, let’s write the code for the BOF:
The code is available here.
Save the code in .c file and use the following command to compile (use the beacon.h file available here):
x86_64-w64-mingw32-gcc -c message-box.c -o message-box.o -w
Next, let’s write the Python script that will register the command to invoke this BOF. Remember, we can also use the command inline-execute
to execute a BOF without registering a command in the Havoc C2 GUI.
The code is available here.
To load this in Havoc C2, go to Scripts → Script Manager → Load Script and select the message-box.py file.
To see the help for the message-box
command, use
help message-box
Now, lets run the command:
message-box
Red Team Notes
- Beacon API exposes equivalent to few Windows APIs and other functions for beacon internal use.
- Other Windows APIs can be accessed from a Beacon Object File (BOF) by specifying their prototype at the beginning of the code file (after include statements).
Follow my journey of 100 Days of Red Team on WhatsApp, Telegram or Discord.