CobaltStrike Bof开发(1)

admin 2024年12月25日23:12:07评论29 views字数 3528阅读11分45秒阅读模式

欢迎加入我的知识星球,目前正在更新免杀相关的东西,129/永久,每100人加29,每周更新2-3篇上千字PDF文档。文档中会详细描述。目前已更新82+ PDF文档

加好友备注(星球)!!!

CobaltStrike Bof开发(1)

一些资源的截图:

CobaltStrike Bof开发(1)
CobaltStrike Bof开发(1)
CobaltStrike Bof开发(1)

简介

CobaltStrike Bof的全称是Beacon Object Files,Bof是一种在目标系统上执行自定义代码的机制,Bof是用C编写的小型程序。

Bof是一种通过将自定义的C代码编译成对象文件并通过CobaltStrike的Beacon在目标系统内存中加载和执行的机制。

什么是Bof

Bof在CobaltStrike中是一种插件的基址,它允许用户在Beacon上指定自定义的C代码,Bof文件是通过将C代码编译为对象文件,也就是.o文件。

这些对象文件可以通过CobaltStrike的Beacon模块去加载和执行。

构建环境

构建环境非常简单,如下Bof模版。

https://github.com/securifybv/Visual-Studio-BOF-template/releases
我们下载解压之后只需要将文件夹放置到VS的ProjectTemplates目录即可。
CobaltStrike Bof开发(1)
然后在你去创建项目的时候,这里就有Beacon Object File了。
CobaltStrike Bof开发(1)

点击创建。

创建之后可能会报错找不到Source.cpp文件,这可能是因为下载的这个模版中没有这个文件。

CobaltStrike Bof开发(1)

我们点击确认。

然后将其Source.cpp文件移除掉。

CobaltStrike Bof开发(1)
再去重新创建一个Source.c文件。
CobaltStrike Bof开发(1)
创建之后将其下面的模版代码复制进去。
#include <windows.h>#include <stdio.h>#include "bofdefs.h"void go(char* buff, int len) {BeaconPrintf(CALLBACK_OUTPUT, "Hello world");}void main(int argc, char* argv[]) {}
紧接着点击生成->批生成。
CobaltStrike Bof开发(1)
在批生成中勾选Bof。
CobaltStrike Bof开发(1)
然后在编译这里切换到Bof即可。
CobaltStrike Bof开发(1)
最后点击生成,会生成一个.obj文件。
CobaltStrike Bof开发(1)
紧接着我们就可以使用CobaltStrike中的inline-execute命令来进行加载了。
inline-execute source.obj
可以看到成功执行。
CobaltStrike Bof开发(1)

理解代码

那么我们接下来就来尝试去理解Bof代码。

首先我们要解释的是bofdefs.h头文件,这个头文件中包含了CobaltStrike Bof特定的函数和宏定义。

而go函数是Bof的入口函数,CobaltStrike在加载和执行Bof的时候会去调用这个函数。

正如上图所见,我们打印出了Hello World。

void go(char* buff, int len) {BeaconPrintf(CALLBACK_OUTPUT, "Hello world");}

调用BeaconPrintf函数会在Beacon控制台中输出Hello World字符串,至于CALLBACK_OUTPUT标记表示这是一个普通的输出类型。

那么我们来详细看一下这个函数的原型,这个函数是CobaltStrike中提供的一个API函数,用于在控制台中输出信息。

如下原型:

voidBeaconPrintf(int type, constchar *fmt, ...);

type参数表示的是输出信息的类型,一般的值为CALLBACK_OUTPUT表示普通的输出信息,而CALLBACK_ERROR表示错误信息。

fmt是格式化字符串,类似于printf函数,后面的三个点是一个可变参数,表示输出的实际数据。

 那么如果我们想格式化输出值的话,我们只需要给定一个变量以及%d占位符即可。

如下代码:

#include <windows.h>#include <stdio.h>#include "bofdefs.h"void go(char* buff, int len) {    int number = 42;    BeaconPrintf(CALLBACK_OUTPUT, "The number is %d", number);}void main(int argc, char* argv[]) {}
CobaltStrike Bof开发(1)

那么我们来学习一下其他的函数。

常见函数学习

BeaconDataParse

BeaconDataParse函数是用于初始化数据解析器的一个函数,它会将传递给Bof的原始数据和解析器关联起来,以便后续的函数来提取各种类型的数据。

函数原型如下:
voidBeaconDataParse(datap *parser, char *data, int length);

parser参数指向了一个datap的指针,用于保存解析器的状态。

data参数是传递给Bof的原始数据。

length参数是数据的长度。

我们来看一下datap结构,这个结构是用于管理和解析数据的内部结构,BeaconDataParse函数将数据和长度与datap结构关联了起来。

这个函数一般会和BeaconDataInt,BeaconDataShort,等函数来配合使用。

这里我们演示的话就使用BeaconDataint吧。

如下代码:

#include <windows.h>#include "beacon.h"void go(char* args, int length) {    // 初始化解析器    datap parser;    BeaconDataParse(&parser, args, length);    // 提取整数值    int value1 = BeaconDataInt(&parser);    int value2 = BeaconDataInt(&parser);    // 输出提取的值    BeaconPrintf(CALLBACK_OUTPUT, "this is number: %d, %d", value1, value2);}void main(int argc, char* argv[]) {}

其实就是在CobaltStrike去运行Bof的时候传递的值会在这里进行接收。

那么接下来这这几种方式其实也是一样的。

都是用来接收参数的。

CobaltStrike Bof开发(1)
BeaconFormatAlloc

BeaconFormatAlloc函数用于初始化和分配一个formatp结构的,formatp结构用户构建动态缓冲区,可以在Bof中格式化和存储数据。

函数原型如下:

DECLSPEC_IMPORT void __cdecl BeaconFormatAlloc(formatp *format, int maxlen);

format参数指向formatp结构的指针,这个结构指针将被初始化和分配。

Maxlen参数指向动态缓冲区的初始最大长度。

如下使用方式:

#include <windows.h>#include <stdio.h>#include "beacon.h"void go(char *args, int length) {    formatp buffer;    BeaconFormatAlloc(&buffer, 128); // 初始化并分配一个最大长度为128的formatp结构    BeaconFormatPrintf(&buffer, "Hello: %d", 123);    char *output = (char *)buffer.buffer;    BeaconPrintf(CALLBACK_OUTPUT, "%s", output);    BeaconFormatFree(&buffer);}void main(int argc, char *argv[]) {}
BeaconIsAdmin

BeaconIsAdmin函数是用于检查当前线程是否是以管理员的权限去运行的,比如说如果我们想去添加用户,那么我们首先肯定是需要去判断当前的线程是否是以管理员去运行的。

函数原型如下:

DECLSPEC_IMPORT BOOL __cdecl BeaconIsAdmin();

如果当前线程以管理员权限运行的,那么返回TRUE。

如果当前线程不是以管理员权限运行的,那么返回FALSE。

如下代码:

#include <windows.h>#include <stdio.h>#include "beacon.h"void go(char *args, int length) {    if (BeaconIsAdmin()) {        BeaconPrintf(CALLBACK_OUTPUT, "管理员运行的线程");    } else {        BeaconPrintf(CALLBACK_OUTPUT, "不是管理员运行的线程");    }}void main(int argc, char *argv[]) {}
CobaltStrike Bof开发(1)

原文始发于微信公众号(Relay学安全):CobaltStrike Bof开发(1)

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月25日23:12:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CobaltStrike Bof开发(1)https://cn-sec.com/archives/3554083.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息