内网渗透神器CobaltStrike之BOF编写(十一)

news2024/11/14 4:09:58

前言

Beacon Object File(BOF) 从Cobalt Strike4.1开始所添加的新功能,它允许你使用C语言编写扩展来扩展Beacon的功能。这些扩展可以在运行时直接加载到Beacon的内存中并执行,无需在目标机器的磁盘上创建任何文件

BOF的一个关键特性是它的运行时环境非常有限。它不能直接调用Windows API,而只能通过Cobalt Strike提供的一组函数来与操作系统进行交互。这样做的原因是为了防止BOF在运行时出错导致Beacon崩溃。然而,尽管这种限制使得编写BOF相对复杂一些,但BOF仍然是一个非常强大的工具,可以用来添加各种自定义功能到Beacon中

一旦BOF编译完成,你可以通过Beacon的"inline-execute"命令来加载并执行BOF。这个命令会将BOF上传到Beacon的内存中并立即执行它,无需将BOF写入到磁盘

环境准备

Github上有很多开发BOF的项目,这里我推荐以下两个项目,前者是开发bof的VisualStuido项目模板,此模板对BOF函数进行了宏定义,这样我们可以像使用C语言一样来开发BOF项目;后者是开发BOF项目所需的头文件,如果此项目更新了,我们可以将此项目的头文件替换掉模板项目的头文件

  • bof的visual studio模板:https://github.com/securifybv/Visual-Studio-BOF-template

  • bof所需的头文件:https://github.com/trustedsec/CS-Situational-Awareness-BOF

不过我更加推荐使用evilashz师傅整理好的模板:https://github.com/evilashz/Visual-Studio-BOF-template

此模板通过DLL名称将WindowsApi函数进行了归类,例如kernel32.dll的导出函数定义就写在kernel32.h里

image-20230818102012570

在函数定义里可以发现有加上KERNEL32$这种前缀,为何CobaltStrike的Bof要使用这种前缀呢,个人推测原因有以下两点:

  • 直接调用: 通过这种方式,BOF可以直接调用DLL中的原生函数,而不需要在BOF的导入表中声明它们。这有助于BOF保持小型和轻量级。
  • 隐蔽性: 使用这种前缀来直接调用API函数可以增加对某些安全解决方案的隐蔽性,因为它们可能不会检测到这些不常见的调用模式

beacon.h定义了与Cobalt Strike Beacon交互所需要的各种数据类型和函数

image-20230818102755777

具体来说,这个文件包含了以下部分:

  • 数据API:这部分定义了一个数据结构(datap),以及一些函数,这些函数用于解析和操作这种数据结构。datap 结构包含原始缓冲区的指针,当前缓冲区的指针,剩余的数据长度,以及缓冲区的总大小。
  • 格式API:这部分定义了一个格式化数据的结构(formatp),以及一些函数,这些函数用于分配、重置、释放和操作这种数据结构。formatp 结构与 datap 结构非常相似,但它是用于格式化数据,而不是解析数据。
  • 输出函数:这部分定义了一些宏和函数,用于向 Beacon 的输出流中输出数据。函数 BeaconPrintfBeaconOutput 可以分别用于格式化输出和二进制输出。
  • 令牌函数:这部分定义了一些函数,用于在 Beacon 中使用和操作 Windows 访问令牌。这些函数包括 BeaconUseToken(使用指定的令牌)、BeaconRevertToken(恢复到之前的令牌)、BeaconIsAdmin(检查当前令牌是否具有管理员权限)。
  • 注入函数:这部分定义了一些函数,用于在新的或已经存在的进程中注入 payload。这些函数包括 BeaconGetSpawnTo(获取 Beacon 的 SpawnTo 设置)、BeaconInjectProcess(在指定进程中注入 payload)、BeaconInjectTemporaryProcess(在临时进程中注入 payload)、BeaconCleanupProcess(清理进程信息)。
  • 实用函数:这部分定义了一些实用函数,例如 toWideChar(将一个字符串转换为宽字符字符串)。

bofdefs.h文件定义了许多函数,这些函数实际上是 Windows API 的宏定义,它们使得开发者能够在 Beacon Object File(BOF)中方便地调用 Windows API,就像使用C语言一样

image-20230818103047212

使用步骤

将下载的模板文件解压至visualstudio的模板目录(%UserProfile%\Documents\Visual Studio 2022\Templates\ProjectTemplates),随后重启VisualStuido

image-20230726225541691

在创建项目时选择类型为Beacon Object File的项目

image-20230726233950177

在头文件列表可以看到beacon.hbofdefs.h

image-20230726234108233

打开项目的Batch生成,勾选上BOF配置。配置管理器的编译环境也需设置为BOF

image-20230726235028577

以下是一个简单的bof项目,用于实现向控制台输出字符串

  • BOF入口:代码定义了BOF的入口函数go,当你在Cobalt Strike中使用inline-execute命令加载并执行你的BOF时,这个函数将被调用。你可以在这个函数中添加你的BOF代码
  • 非BOF入口:这部分代码定义了非BOF的入口函数main。当你在非Cobalt Strike环境中运行你的代码时,这个函数将被调用。你可以在这个函数中添加你的非BOF代码
include <windows.h>
include <stdio.h>
include "bofdefs.h"

pragma region error_handling
define print_error(msg, hr) _print_error(__FUNCTION__, __LINE__, msg, hr)
BOOL _print_error(char* func, int line,  char* msg, HRESULT hr) {
ifdef BOF
	BeaconPrintf(CALLBACK_ERROR, "(%s at %d): %s 0x%08lx", func, line,  msg, hr);
else
	printf("[-] (%s at %d): %s 0x%08lx", func, line, msg, hr);
endif // BOF

	return FALSE;
}
pragma endregion


ifdef BOF
void go(char* buff, int len) {
	BeaconPrintf(CALLBACK_OUTPUT, "Hello, World!");
}


else

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

endif

项目生成后会生成一个.obj文件,也就是编译未链接的目标文件,在CobaltStrike中你可以使用inline-execute命令来加载并执行你的.obj文件,此命令将你的 .obj 文件加载到 Beacon 的内存中,然后调用你的 go 函数,命令格式如下所示

beacon> inline-execute your_bof.obj
image-20230727091013243

踩坑记录

1.bof应尽量使用C语言

编写bof时应该尽量使用C语言来编写,如果你使用C++来编写很可能会出现如下图所示的错误:Could not resolve API

这是因为C++为了支持函数重载,会对函数名进行修饰,从而导致函数的实际名称与你在代码中看到的名称不同,因此当你尝试在BOF解析某个函数时,可能会找不到它

image-20230818094623207

2.inline-execute无法接收参数?

如下是一个简单的bof项目源码,用于在beacon命令行输出bof接收的参数

void go(char* buff, int len) {

	// datap是BOF框架中定义的结构体,用于解析从Beacon接收到的数据
	// 当你在Beacon执行BOF时,可以向BOF传递一些参数,这些参数会被打包成一个字节流
	// BOF会使用datap结构体来解析这个字节流,从而获取到传递的参数
	datap parser;

	wchar_t* username;
	wchar_t* password;

	// 初始化datap结构体变量(parser),用于解析从Beacon接收到的字节流(buff)
	BeaconDataParse(&parser, buff, len);
	username = (wchar_t*)BeaconDataExtract(&parser, NULL);
	password = (wchar_t*)BeaconDataExtract(&parser, NULL);

	BeaconPrintf(CALLBACK_OUTPUT, "Extracted username: %S", username);
	BeaconPrintf(CALLBACK_OUTPUT, "Extracted password: %S", password);
}

但是从输出结果来看,bof并没有接收到参数,而是显示(null)。所以说,如果要给BOF传递参数,还是得使用CNA脚本的bof_pack函数来打包参数,然后使用beacon_inline_execute函数来执行BOF

image-20230818100321336

3.报错:Unknown symbol ‘__chkstk’

当你执行bof项目时可能会遇到如下图所示的错误,其根本原因出在你bof的源码上,当你的源代码使用大量的局部变量或数组时,编译器会插入一个__chkstk调用来确保有足够的堆栈空间。而在BOF中,由于我们没有完整的C运行时环境,所以这个函数是不存在的

image-20230819221112051

当时我的bof源码定义了个特别大的局部数组,如下代码所示

WCHAR output[4096] = {0};

为了解决这个问题,应该减少局部变量的大小,使用动态内存分配来创建所需的数组,比如HeapAllocHeapFree,更正后的代码如下:

WCHAR *output = (WCHAR *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 4096 * sizeof(WCHAR));

参考链接

  • http://mp.weixin.qq.com/s?__biz=MzI5NzU0MTc5Mg==&mid=2247484673&idx=1&sn=d1628ed1f77c638ba414185bfeabf8ee&chksm=ecb2cccedbc545d89bd098632be7fb23c273e585a4f2167089b39d483c42deac13b6078ba3b5&scene=126&sessionid=1658057738&key=ffca75888bc216b14d1a0902587e61caf0fefe2cfd31cfccaef08baab2efb4a9952f320749796d966ba2829cd33e4a301cc25916b74879ea9c6bd6de9d2f06ca9beb159028a59e4ce006bc8276b59ee20d18fba2db40dbeccec3351295fad8192f098aee34bfed114a7c0c700ba46bc16f0a9a660f7801c96a668a64fd5a1a7c&ascene=15&uin=MTA3Mzc3OTIzNQ%3D%3D&devicetype=Windows+Server+2016+x64&version=6307001e&lang=zh_CN&session_us=gh_5b8184332bc1&exportkey=AaYcTeWdxPQAKdPy7RMIrxs%3D&acctmode=0&pass_ticket=H5DatfK1H7UD%2FQIL%2B8Md2%2BlWZOBY12u%2F%2FD4TQgyDk5zYF8C5%2BgX4U3zhXOnsq%2BtU&wx_header=0&fontgear=2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/908431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

生物识别技术与身份认证:探讨生物识别技术在强化身份认证和访问控制方面的应用

第一章&#xff1a;引言 在数字化时代&#xff0c;随着信息技术的飞速发展&#xff0c;身份认证和访问控制变得越来越重要。传统的用户名和密码方式逐渐暴露出安全性不足的问题&#xff0c;为此&#xff0c;生物识别技术应运而生。生物识别技术利用人体生物特征来识别个体身份…

HoudiniVex笔记_P25_ForceExtended力进阶

原视频&#xff1a;https://www.youtube.com/playlist?listPLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI Bili&#xff1a;Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili Houdini版本&#xff1a;19.5 如有错误&#xff0c;可在评论区指正。 1、本章主要…

sql数据导出到excel

一、打开Navicat Premium 12 二、导出

管理类联考——逻辑——真题篇——按知识分类——汇总篇——三、综合推理——是否确定信息

真题&#xff08;2018-40&#xff09;——综合推理——是否确定信息——确定信息——以确定信息作为解题起点 某海军部队有甲、乙、丙、丁、戊、己、庚7艘舰艇&#xff0c;拟组成两个编队出航&#xff0c;第一编队编列3艘舰艇&#xff0c;第二编队编列4艘舰艇&#xff0c;编列…

linux的http服务

Web通信基本概念 基于B/S&#xff08;Browser/Server&#xff09;架构的网页服务 服务端提供网页 浏览器下载并显示网页 Hyper Text Markup Lanuage,超文本标记语言 Hyper Text Transfer Protocol&#xff0c;超文本传输协议 虚拟机A&#xff1a;构建基本的Web服务 [root…

python Requests

Requests概述 官方文档&#xff1a;http://cn.python-requests.org/zh_CN/latest/,Requests是python的HTTP的库&#xff0c;我们可以安全的使用 Requests安装 pip install Requests -i https://pypi.tuna.tsinghua.edu.cn/simple Requests的使用 Respose的属性 属性说明url响…

Jeep车型数据源:提供Jeep品牌车系、车型、价格、配置等信息

​​​​​ Jeep是一个极具特色的汽车品牌&#xff0c;它的所有车型都注重实用性&#xff0c;具有越野性能和高性能。Jeep品牌在汽车行业中的口碑一直是非常不错的。如果你想要了解Jeep品牌车系、车型、价格、配置等信息&#xff0c;就可以通过挖数据平台Jeep车型数据源API接口…

IO day 5

1、使用两个线程完成两个文件的拷贝&#xff0c;主线程拷贝前一半内容&#xff0c;子线程拷贝后一半内容&#xff0c;并且主线程要阻塞回收子线程资源 #include <myhead.h>//定义求文件长度函数 int fd1,fd2; //以只读的形式打开源文件 if((fd1open(stcfile,O_RDONLY)) …

aosp-刷入Magisk面具获取root权限

作者&#xff1a;上山打鼠 一、简介 话说上次root手机都已经是初中的时候了&#xff0c;那时候捣鼓手机不亦乐乎&#xff0c;Android4.4的系统先解锁&#xff0c;再刷入第三方Recovery&#xff0c;然后再刷入Root包去获取Root权限 想学点逆向的知识&#xff0c;所以要root一下…

算法通关村第5关【青铜】| Hash和队列的特征

1.Hash基础 &#xff08;1&#xff09;基础 哈希也称为散列&#xff0c;通过算法变成固定长度的输出值&#xff0c;存入对应的位置 例如这个算法为取模算法&#xff0c;indexnumber 模 7 存入1到15 &#xff08;2&#xff09;碰撞处理 当多个元素映射到同一位置上时就产生…

L Grayscale Confusion【2023牛客多校第10场】【拓扑排序】

来源&#xff1a;“范式杯”2023牛客暑期多校训练营10 —— L Grayscale Confusion 题意&#xff1a;给定 n 个三元组 ( r i , g i , b i ) 。构造一个长度为 n 的数组 w&#xff0c; 使得 ①w1 w 2 ②对于任意 i, j &#xff0c;若 r i > r j , g i > g …

python之Numpy

ndarray数组对象 NumPy定义了一个n维数组对象&#xff0c;简称ndarray对象&#xff0c;它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块 ndarray 对象采用了数组的索引机制&#xff0c;将数组中的每个元素映射到内存块上&#xff0c;并且按…

C++笔记之虚函数重写规则、返回类型协变、函数的隐藏

C笔记之虚函数重写规则、返回类型协变、函数的隐藏 code review! 文章目录 C笔记之虚函数重写规则、返回类型协变、函数的隐藏1.返回类型协变2.C中函数的隐藏 —— C Primer Plus &#xff08;第6版&#xff09; —— cppreference 1.返回类型协变 2.C中函数的隐藏 在C中&a…

深入理解AQS和ReentrantLock

AQS 之前介绍synchronized关键字时提到过管程的概念&#xff0c;synchronized就是JVM内置管程&#xff0c;其使用的是管程的MESA模型。但是synchronized有一些缺点&#xff1a; 非公平锁&#xff0c;可能会使得一些线程长久抢占不到锁&#xff0c;导致其处于饥饿状态&#xf…

5.分布式事务管理-Seata

由于Transactional注解只能控制所在服务器A的事务&#xff0c;当方法中调用其他服务器B的方法&#xff0c;当A中该方法出错时&#xff0c;Transactional只能回滚A中该方法中的SQL&#xff0c;而A调用B的方法中的SQL无法回滚 1.Seata Seata&#xff08;分布式事务解决方案&…

Electron入门,项目运行,只需四步轻松搞定。

electron 简单介绍&#xff1a; 实现&#xff1a;HTML/CSS/JS桌面程序&#xff0c;搭建跨平台桌面应用。 electron 官方文档&#xff1a; [https://electronjs.org/docs] 本文是基于以下2篇文章且自行实践过的&#xff0c;可行性真实有效。 文章1&#xff1a; https://www.cnbl…

Centos开启防火墙和端口命令

Centos开启防火墙和端口命令 1. 开启查看关闭firewalld服务状态2. 查看端口是否开放3. 新增开放端口4. 查看开放的端口 1. 开启查看关闭firewalld服务状态 #启动/关闭firewall systemctl start/stop firewalld #查看防火墙状态 systemctl status firewalld #禁用或者启用 syst…

sql in mac学习记录

鉴于有一段时间没有访问mysql了&#xff0c;最近打算在mac 系统上下载mysql 练习一下sql的使用&#xff0c;于是 First, the mysql download https://dev.mysql.com/downloads/mysql/ Second, Mysql install steps Install the software by normally install one software …

mysql 、sql server trigger 触发器

sql server mySQL create trigger 触发器名称 { before | after } [ insert | update | delete ] on 表名 for each row 触发器执行的语句块## 表名&#xff1a; 表示触发器监控的对象 ## before | after : 表示触发的时间&#xff0c;before : 表示在事件之前触发&am…

cloud_mall-notes02

1、多条件分页查询page ApiOperation("多条件分页查询xxxx")GetMapping("page")PreAuthorize("hasAuthority(模块权限:权限:page)")public ResponseEntity<Page<实体类>> loadxxxxPage(Page<实体类> page,实体类 domain) {pag…