CobaltStrike逆向学习系列(2):Stageless Beacon 生成流程分析
字数 2261 2025-08-29 08:30:36
CobaltStrike逆向学习系列(2):Stageless Beacon生成流程分析
1. Stageless Beacon概述
CobaltStrike的Beacon生成分为两种类型:
- Stage Beacon:分阶段加载,最终文件较小,需要从网络中拉取后续阶段
- Stageless Beacon:无阶段加载,最终文件较大,包含所有功能
本文重点分析Stageless Beacon的生成流程,使用的payload示例为windows/beacon_http/reverse_http。
2. Stageless Beacon生成流程
2.1 初始处理阶段
- 用户点击生成时,进入
WindowsExecutableStageDialog.dialogAction方法 - 根据界面选择的输出类型决定生成文件后缀
- 弹出文件保存对话框
- 用户选择保存位置后,进入
dialogResult方法处理Patch操作
2.2 Patch Beacon核心流程
2.2.1 准备工作
- 获取当前选择的Listener名称和架构(x86/x64)
- 进入关键方法
export
2.2.2 export方法处理
- 根据选择的payload决定调用哪个处理函数
- 根据架构选择核心功能DLL(Beacon文件)
执行两个关键处理:
exportBeaconStage:处理C2Profile相关内容pe.process:处理PE格式、ReflectiveLoad和引导头
2.2.3 exportBeaconStage处理
- 根据Beacon路径读取相应文件
- 解析C2Profile:
- 这是BeaconEye、CobaltStrikeScan等工具检测的根本依据
- 解析逻辑是检测与绕过的关键点
- 处理完成后:
- 将数据转换为特定格式的byte数组
- 设置总大小为4096字节,不足部分用随机字符填充
- 调用
beacon_obfuscate进行混淆(逐字节异或)
- 将处理后的内容Patch到Beacon中
2.2.4 PE处理(pe.process)
分为两个主要步骤:
-
pre_process:- 从C2Profile中取出与PE相关的项
- 通过PEEditor进行基本处理
-
post_process:- 添加ReflectiveLoad和引导头
- 使用PEParser解析Beacon(注意:作者实现的解析类存在一些小BUG)
ReflectiveLoad处理细节
-
获取导出函数
ReflectiveLoad的偏移 -
Patch引导头:
- 利用PE头中的原始数据字节作为指令
- 覆盖不重要的PE结构
- 在堆栈平衡前提下执行自定义功能
- 通过偏移跳转执行ReflectiveLoad函数
-
调用
getReflectiveLoaderFunction添加ReflectiveLoad函数:- CobaltStrike使用自定义实现的ReflectiveLoad,非公开的RDI项目
- 提供三份备用方案,区别在于内存分配函数:
HeapAllocVirtualAllocMapViewOfFile
-
将ReflectiveLoad和引导头放到对应位置
2.3 Patch Loader阶段
CobaltStrike不会直接保存处理后的Beacon,而是:
-
根据选择的文件类型选择对应的Loader:
- Stageless使用的Loader名称中包含"big"
- Stage使用的Loader名称不包含"big"
-
调用
_patchArtifact方法:- 处理基本信息
- 随机生成数值用于异或整个Beacon
-
Patch操作:
- 找到Patch点(1024个'A'的位置)
- 构造Patch内容:
- Patch+16的位置(4字节)
- Beacon总长度(4字节)
- 异或加密Key(4字节)
- GetModuleHandleA地址(4字节)
- GetProcAddress地址(4字节)
- 异或后的Beacon
- 第一个存储位置指向GetProcAddress地址
-
执行Patch并返回
-
写入文件完成生成
3. 文件对比分析
3.1 beacon.x64.dll分析
- 直接搜索可找到Patch点
- 导出函数附近可见一串
90 CC占位(NOP INT3指令)
3.2 生成文件对比
对比生成的Beacon与artifact64big.exe可验证上述流程。
4. 关键点总结
-
C2Profile处理:
- 是检测工具的主要依据
- 了解其解析逻辑可实现检测绕过或更精确的检测
-
ReflectiveLoad实现:
- CobaltStrike使用自定义实现
- 三种内存分配方案提供灵活性
-
引导头技术:
- 利用PE头数据作为指令
- 覆盖不重要PE结构实现功能
-
Loader Patch机制:
- 使用特定位置的占位符进行Patch
- 包含关键API地址和加密信息
-
架构差异:
- 处理流程会根据x86/x64架构选择不同资源
5. 检测与对抗思路
-
检测点:
- C2Profile特定格式和结构
- ReflectiveLoad的特征
- 引导头的特殊实现方式
- Loader中的Patch模式
-
绕过思路:
- 修改C2Profile的存储和混淆方式
- 自定义ReflectiveLoad实现
- 改变引导头的实现逻辑
- 调整Loader的Patch机制
-
增强检测:
- 深入分析C2Profile解析逻辑
- 识别自定义ReflectiveLoad的特征
- 检测PE头异常使用情况
- 监控Loader中的特定Patch模式