cobaltstrike4.5 stageless beacon 通信分析
字数 2215 2025-08-25 22:59:02
Cobalt Strike 4.5 Stageless Beacon 通信分析教学文档
1. 环境准备
1.1 调试环境搭建
- 使用IDEA反编译Cobalt Strike并导入原jar包作为依赖进行调试跟踪
- 从
.cobaltstrike.beacon_keys文件中取出序列化存储的RSA公私钥
1.2 通信配置
为了便于手动解密通信数据,使用以下profile配置将所有通信数据Base64编码:
http-get {
set uri "/ca /dpixel /__utm.gif /pixel.gif /g.pixel /dot.gif /updates.rss /fwlink /cm /cx /pixel /match /visit.js /load /push /ptj /j.ad /ga.js /en_US/all.js /activity /IE9CompatViewList.xml";
client {
metadata {
base64;
header "Cookie";
}
}
server {
header "Content-Type" "application/octet-stream";
output {
base64;
print;
}
}
}
http-post {
set uri "/submit.php";
client {
header "Content-Type" "application/octet-stream";
id {
parameter "id";
}
output {
base64;
print;
}
}
server {
header "Content-Type" "text/html";
output {
base64;
print;
}
}
}
2. Beacon上线与心跳通信
2.1 上线过程
- 第一个GET请求包含metadata信息
- 服务端返回空响应包
- metadata默认使用RSA公钥加密放在Cookie中
2.2 心跳通信
- 后续心跳请求使用相同结构
- 服务端通过心跳响应包下发命令
3. TeamServer请求处理流程
3.1 请求处理入口
NanoHTTPD.run方法接收请求- 传递给
WebServer.serve - 最终由
WebServer._serve处理
3.2 请求过滤
-
检查User-Agent:
- 黑名单检测(
blockedByUA) - 白名单检测(
allowedByUA) - 默认黑名单:curl/lynx/wget*
- 必须满足
allowedByUA && !blockedByUA才会继续处理
- 黑名单检测(
-
OPTIONS方法直接返回200和允许的方法
-
检查URI是否在profile定义的
http-get.set uri或http-post.set uri中
3.3 请求处理链
- 匹配的URI由
MalleableHook.serve处理 - 最终调用
BeaconHTTP._A.serve处理metadata
4. Metadata处理
4.1 处理流程
BeaconHTTP._A.serve获取客户端IP- 使用
recover方法对metadata进行Base64解码 - 传入
process_beacon_metadata处理
4.2 Metadata数据结构
4字节: 固定magic number 48897
4字节: 数据长度
16字节: SHA256哈希的前16字节为AES密钥,后16字节为HMAC密钥
2字节: 大端字节序编码类型(WindowsCharsets.getName)
2字节: 大端字节序编码类型
4字节: Beacon会话ID
4字节: PID
2字节: SSH端口
1字节: 系统信息标志位(按位与判断):
+4: 64位系统
+2: 64位程序
+8: SYSTEM权限
+1: 获取信息失败
2字节: Windows NT版本
2字节: Windows Build号
4字节: 未知作用
4字节: ptr_gmh
4字节: ptr_gpa
4字节: 大端字节序表示的内网IP地址
剩余部分: 计算机信息(计算机名\n用户名\n程序名)
5. 任务下发机制
5.1 任务数据结构
TeamServer使用metadata中的:
- AES密钥加密任务数据
- HMAC密钥作为盐计算哈希签名
- 硬编码IV:
abcdefghijklmnop
5.2 任务构造示例(shell whoami)
任务数据结构:
4字节: 命令类型(78表示shell)
4字节: 数据长度
数据部分: "%COMSPEC%\n/C whoami"
具体构造流程:
BeaconConsole.actionPerformed根据命令类型进入对应方法shell方法构造任务结构:- 添加4字节的
%COMSPEC%长度和内容 - 添加命令编码后的长度和内容(各4字节)
- 添加2字节的0
- 添加4字节的
- 在数据前添加4字节命令类型和4字节数据长度
5.3 TeamServer任务队列
- TeamServer启动监听循环
- 客户端命令转换为
Request对象:call属性为beacon.taskargs为加工后的参数
Beacon.call方法处理任务:- 获取对应Beacon ID的任务队列
- 添加任务数据到队列
5.4 Beacon获取任务
BeaconHTTP._A.serve调用dump方法- 从
this.queues获取对应Beacon ID的任务 - 加密任务数据:
- 添加4字节时间戳
- 添加4字节任务数据长度
- 使用AES加密
- 计算HMAC签名
- 拼接加密数据和签名(前16字节)
6. 任务结果回传
6.1 POST请求处理
- Beacon通过POST回传结果
BeaconHTTP._B.serve处理POST数据- Session ID默认放在URL中
6.2 数据处理流程
- Base64解码POST数据
process_beacon_data处理:- 前4字节为数据长度
- 剩余部分传入
process_beacon_callback
- 解密数据:
- 后16字节为HMAC签名
- 验证完整性
- AES解密剩余数据
- 解析任务结果:
- 前4字节防重放验证
- 接着4字节为数据长度
- 然后4字节为任务类型(30表示shell)
6.3 任务结果数据结构
4字节: 数据长度
[AES加密数据]
4字节: 防重放int
4字节: 数据长度
4字节: 任务类型
任务结果数据
其他数据(shell类型有8字节)
16字节: HMAC哈希签名
7. 实用工具与参考
7.1 解析脚本
- Python实现的metadata解析工具:https://github.com/l3anma/cobaltstrike4.5_http_dec
7.2 参考资源
- Cobalt Strike原理介绍:https://wbglil.gitbook.io/cobalt-strike/cobalt-strike-yuan-li-jie-shao/cs-mu-biao-shang-xian-guo-cheng#yuan-shu-ju
- Palo Alto Networks分析报告:https://unit42.paloaltonetworks.com/cobalt-strike-metadata-encryption-decryption/
8. 关键点总结
-
通信加密:
- 初始metadata使用RSA加密
- 后续通信使用AES加密(密钥来自metadata)
- HMAC用于完整性验证
-
任务机制:
- 心跳GET请求用于下发任务
- POST请求用于回传结果
- 任务队列存储在TeamServer
-
数据结构:
- 所有关键数据都有长度前缀
- 使用固定magic number标识
- 系统信息高度压缩编码
-
安全措施:
- User-Agent过滤
- 防重放机制
- 数据完整性验证