BOF and Extensions
Beacon Object Files
BOF is just a block of position-independent code that receives pointers to some Beacon internal APIs. BOFs are single-file C programs that call Win32 APIs and limited Beacon APIs.
AdaptixC2 expects that your BOFs are single-threaded programs that run for a short period of time. BOFs will block other agent tasks and functionality from executing. BOFs execute inside of your agent. If a BOF crashes, you will lose access. Write your BOFs carefully.
Description of BOF for agents
Beacon BOFsGopher BOFsExtensions
How to execute AxScript
The extension file is an AxScript that must start with a global definition of the metadata variable that has the following properties: .
name
- extension name,description
- extension descriptionstore
- determines whether the extension should be stored in the database (default:true
).
var metadata = {
name: "Elevation-BOF",
description: "BOFs for context elevation",
store: true
};
// AxScript code
// ...
Typically, extensions register new commands to call already registered commands. An example of defining a shell
command that calls the command ps run -o ...
. See more details here.
let cmd_shell = ax.create_command("shell", "Execute command via cmd.exe", "shell whoami /all");
cmd_shell.addArgString("cmd_params", true);
cmd_shell.setPreHook(function (id, cmdline, parsed_json, ...parsed_lines) {
let new_cmd = "ps run -o C:\\Windows\\System32\\cmd.exe /c " + parsed_json["cmd_params"];
ax.execute_alias(id, cmdline, new_cmd);
});
AxScript and BOFs
You'll likely want to use AxScript to run your finalized BOF implementations within AdaptixC2. A BOF is a good place to implement a lateral movement technique, an escalation of privilege tool, or a new reconnaissance capability.
Each agent has its own command to execute BOF. For example, for a beacon agent it is execute bof
. Here is a script to run a screenshot_bof
BOF:
var cmd_screenshot = ax.create_command("screenshot_bof", "Alternative screenshot capability that does not do fork n run by @codex_tf2", "screenshot -n screen1 -p 812");
cmd_screenshot.addArgFlagString("-n", "note", "Screenshot caption", "ScreenshotBOF");
cmd_screenshot.addArgFlagInt("-p", "pid", "PID of the application whose window screenshot will be taken. If 0, then a full-screen screenshot", 0);
cmd_screenshot.setPreHook(function (id, cmdline, parsed_json, ...parsed_lines) {
let note = parsed_json["note"];
let pid = parsed_json["pid"];
let bof_params = ax.bof_pack("cstr,int", [note, pid]);
let bof_path = ax.script_dir() + "_bin/Screenshot." + ax.arch(id) + ".o";
ax.execute_alias(id, cmdline, `execute bof ${bof_path} ${bof_params}`, "Task: Screenshot BOF");
});
First, the script gets the note
and pid
values. The next step is to pack our arguments. The bof_pack function packs arguments in a way that is compatible with Beacon's internal data parser API. This script uses execute_alias to run BOF with its arguments.
Last updated