CS 4.1 BOF开发
BOF介绍
信标对象文件 (BOF) 是一个已编译的 C 程序,按照约定编写,允许它在信标进程中执行并使用内部信标 API。BOF 是一种使用新的后开发功能快速扩展 Beacon 代理的方法。
BOF是如何执行的
对于 Beacon 来说,BOF 只是一个位置无关的代码块,它接收指向某些 Beacon 内部 API 的指针。
对于 Cobalt Strike 而言,BOF 是由 C 编译器生成的目标文件。Cobalt Strike 解析此文件并充当其内容的链接器和加载器。这种方法允许您编写与位置无关的代码,用于 Beacon,而无需繁琐的体操来管理字符串和动态调用 Win32 API。
BOF缺陷
- BOF 是调用 Win32 API 和有限 Beacon API 的单文件 C 程序。不要期望使用此机制链接其他功能或构建大型项目。
- Cobalt Strike 不会将您的 BOF 链接到 libc。这意味着您仅限于编译器内部函数(例如,Visual Studio 上的 __stosb for memset)、公开的 Beacon 内部 API、Win32 API 以及您编写的函数。您可能无法通过 BOF 使用许多常用函数(例如 strlen、stcmp 等)。
- BOF 在您的 Beacon 代理内部执行。如果 BOF 崩溃,有可能导致Beacon崩溃
- Cobalt Strike 期望您的 BOF 是短时间运行的单线程程序。BOF 将阻止其他 Beacon 任务和功能的执行。异步或长时间运行的任务没有 BOF
模式。如果要构建长时间运行的功能,请考虑在牺牲进程内运行的反射 DLL。
编译的方式
要使用 Visual Studio 编译它:
cl.exe /c /GS- hello.c /Fohello.o
要使用 x86 MinGW 编译它:
i686-w64-mingw32-gcc -c hello.c -o hello.o
要使用 x64 MinGW 编译它:
x86_64-w64-mingw32-gcc -c hello.c -o hello.o
x64 beacon对应加载x64 gcc编译的bof文件,x86 beacon对应加载x86 gcc编译的bof文件
准备环境
* cs 4.1或者以上的版本
* 从官方下载beacon.h -> https://www.cobaltstrike.com/downloads/beacon.h
前置知识
cna主要使用的几个函数和过程:
先了解几个函数:
* bof_pack - 打包参数传入到BOF里的函数
* beacon_inline_execute - 调用BOF里面的函数
bof_pack
$1 - Beacon ID
$2 - 打包数据的格式化字符串 -> (例如Socket里的Packet操作)
此函数将其参数打包成一个二进制结构,以便与&beacon_inline_execute一起使用。此处的格式字符串选项对应于 BOF 文件可用的 BeaconData* C API。该 API 根据它可以打包的每种类型的要求处理数据和提示的转换。
文档链接:https://www.cobaltstrike.com/aggressor-script/functions.html#bof_pack
beacon_inline_execute
$1 - Beacon ID
$2 - 读取了BOF文件的数据
$3 - 要调用的函数名称
$4 - 要传递给BOF文件的打包参数
执行信标对象文件
文档链接:https://www.cobaltstrike.com/aggressor-script/functions.html#beacon_inline_execute
BOF文件示例(有参数调用,无Windows API调用):
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include "beacon.h"
void demo(char * args, int length) {
datap parser; #参数结构定义
char * str_arg;
int num_arg;
BeaconDataParse(&parser, args, length); #准备数据解析器以从指定缓冲区中提取参数
str_arg = BeaconDataExtract(&parser, NULL); #参数解析赋值于str_arg对应bof_pack函数参数2里的格式化字符串z
num_arg = BeaconDataInt(&parser); #参数解析赋值于num_arg对应bof_pack函数参数2里的格式化字符串i
BeaconPrintf(CALLBACK_OUTPUT, "Message is %s with %d arg", str_arg, num_arg);
}
cna文件示例:
cna调用BOF文件函数过程:
* 先读取bof文件内容
* 调用的函数是否需要参数
* 调用函数入口点
alias hello {
btask($1, script_resource("demo.o"));
$handle = openf(script_resource("demo.o")); #读取BOF文件
$data = readb($handle, -1); #读取BOF文件内容
closef($handle);
$args = bof_pack($1, "zi", "Raiden Mei Birthday", 413); #参数打包
btask($1, "Running Hello BOF");
beacon_inline_execute($1, $data, "demo", $args); #调用BOF文件入口点
}
效果如下:
调用Windows API
下载https://github.com/dtmsecurity/bof_helper,执行输入API转换获取BOF里的格式
(自己测试的时候获取失败了,不过看了一下人手转BOF格式也可以)
python3 bof_helper.py DsGetDcNameA
██████╗ ██████╗ ███████╗
██╔══██╗██╔═══██╗██╔════╝
██████╔╝██║ ██║█████╗
██╔══██╗██║ ██║██╔══╝
██████╔╝╚██████╔╝██║
╚═════╝ ╚═════╝ ╚═╝
BOF Helper by @dtmsecurity
[Library] DsGetDcNameA is probably in NetApi32
[Declaration] DWORD WINAPI DsGetDcNameA(LPCSTR, LPCSTR, GUID*, LPCSTR, ULONG, PDOMAIN_CONTROLLER_INFOA*);
[BOF Helper]
DECLSPEC_IMPORT DWORD WINAPI NETAPI32$DsGetDcNameA(LPCSTR, LPCSTR, GUID*, LPCSTR, ULONG, PDOMAIN_CONTROLLER_INFOA*);
例如CreateProcessA
BOOL CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
到了BOF就变成这样
DECLSPEC_IMPORT WINBASEAPI <类型> <API类型> DLL名$<从DLL里面导出的API名称>
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
更多示例
DECLSPEC_IMPORT WINBASEAPI void * __cdecl MSVCRT$memset(void *_Dst,int _Val,size_t _Size);
DECLSPEC_IMPORT WINBASEAPI WINBOOL WINAPI KERNEL32$CreateProcessA (LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation);
DECLSPEC_IMPORT WINBASEAPI LPVOID WINAPI KERNEL32$VirtualAllocEx (HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
DECLSPEC_IMPORT WINBASEAPI WINBOOL WINAPI KERNEL32$WriteProcessMemory (HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$QueueUserAPC (PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
DECLSPEC_IMPORT WINBASEAPI DWORD WINAPI KERNEL32$ResumeThread (HANDLE hThread);
demo2.c (无参数,windows API调用)
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include "beacon.h"
DECLSPEC_IMPORT WINBASEAPI BOOL WINAPI KERNEL32$CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
void demo(char * args, int length) {
STARTUPINFOA si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };
BOOL Test = KERNEL32$CreateProcessA(NULL, "C:\\Windows\\System32\\notepad.exe", NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
}
demo.cna
alias hello {
btask($1, script_resource("demo2.o"));
$handle = openf(script_resource("demo2.o"));
$data = readb($handle, -1);
closef($handle);
$args = bof_pack($1, "zi", "", 0);
btask($1, "Running Hello BOF");
beacon_inline_execute($1, $data, "demo", $args);
}
参考链接
https://www.cobaltstrike.com/help-beacon-object-files
https://www.cobaltstrike.com/aggressor-script/functions.html
http://evilash.me/2020/08/18/BOF.html
https://github.com/boku7/HOLLOW/blob/main/hollow.x64.c - 这个例子不错
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。
文章标题:CS 4.1 BOF开发
本文作者:九世
发布时间:2021-07-28, 21:54:39
最后更新:2021-07-28, 22:08:51
原始链接:http://jiushill.github.io/posts/e42bb01c.html版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。