CobaltStrike逆向学习系列(5):Bypass BeaconEye
字数 1112 2025-08-29 08:31:35
CobaltStrike逆向学习系列(5): Bypass BeaconEye检测技术详解
1. BeaconEye检测原理分析
BeaconEye是通过YARA规则来检测Cobalt Strike Beacon的,其核心检测逻辑基于Beacon的C2Profile结构特征:
- C2Profile解析后,每一项固定占16字节
- 前8字节是type类型标识
- 后8字节是data数据
- 检测规则主要匹配特定的内存结构模式
具体检测规则示例(YARA第一条):
- 全零检测:Beacon解析时直接偏移index位置
- 类型序列:short(1)、short(1)、int(2)、int(2)、short(1)
- 值对应关系严格匹配
2. Bypass方法一:破坏内存结构
基本原理
通过打破原有的16字节规则结构来实现绕过检测。
实现方法
-
内存初始化修改:
- 申请内存时设置非零值填充
- 关键位置保留type和data,中间填充随机/无效数据
-
寄存器操作:
mov edx, [其他寄存器] ; 通过寄存器值替换破坏原有结构 -
Inline Hook技术:
- 在关键内存操作点插入hook
- 动态修改内存布局
3. Bypass方法二:全面HOOK方案
整体架构
重写Loader并HOOK关键函数,实现更彻底的绕过:
Controller → 生成数组 → Patch到beacon.dll → Patch到Loader → Beacon解析使用
关键HOOK点
需要修改的两类函数:
-
解析函数:
- 当
fdwReason=1时执行的C2Profile解析函数 - 完全HOOK此函数实现自定义解析
- 当
-
取值函数(共4个):
- GetShortValue
- GetIntValue
- GetPtrValue
- 解析函数
X64偏移地址
ULONG_PTR ulParseProfile = ImageBase + 0x18694;
ULONG_PTR ulGetShortValue = ImageBase + 0x18664;
ULONG_PTR ulGetIntValue = ImageBase + 0x185DC;
ULONG_PTR ulGetPtrValue = ImageBase + 0x18630;
X86特殊处理
X86架构下需要注意:
- 参数通过EDX寄存器传递而非堆栈
- 需要使用内联汇编获取参数:
__asm mov index, edx;
数据存储方案
提供两种实现思路:
-
简单罗列:
- 数据线性存储
- 取值时需要额外定位逻辑
- 实现简单但效率较低
-
复杂混淆:
- 定长存储+大量垃圾字符填充
- 自定义加密格式
- 实现复杂但隐蔽性高
4. 实现建议
-
HOOK库选择:
- 选择熟悉的HOOK库(如Detours、MinHook等)
- 确保稳定性与兼容性
-
内存管理:
- 自定义内存分配策略
- 考虑内存属性设置(RWX等)
-
兼容性处理:
- 区分X86/X64架构
- 处理不同Windows版本差异
-
测试验证:
- 使用BeaconEye扫描验证绕过效果
- 确保功能完整性不被破坏
5. 扩展思路
-
动态变异:
- 每次加载时生成不同的内存结构
- 增加检测难度
-
多阶段解析:
- 分阶段解析C2Profile
- 增加分析复杂度
-
环境感知:
- 检测调试/扫描环境
- 动态调整绕过策略
通过以上方法,可以有效绕过BeaconEye的检测机制,同时为后续的Beacon功能扩展和定制化开发奠定基础。