CobaltStrike逆向学习系列(1):控制端登陆流程分析
字数 2567 2025-08-29 08:30:36
CobaltStrike逆向学习系列(1):控制端登陆流程分析 - 教学文档
1. 名词定义
- Controller: CobaltStrike的客户端界面,用于操作和控制
- TeamServer: CobaltStrike的服务端,负责与Beacon通信
- Beacon: 植入目标系统的payload,执行命令并回传结果
2. 整体流程概述
Controller连接TeamServer的完整流程分为以下几个阶段:
- 密码校验阶段
- aggressor.authenticate认证
- aggressor.metadata元数据交换
- 数据同步阶段
- 常态化通信
3. 密码校验详细流程
3.1 TeamServer准备阶段
- TeamServer启动后创建
SecureServerSocket对象 - 循环调用
acceptAndAuthenticate方法等待Controller连接 - 验证成功后调用
clientAuthenticated方法 - 创建线程执行
ManageUser处理Controller信息
3.2 Controller连接阶段
- 点击Connect按钮触发
dialogAction方法 - 创建
SecureSocket对象 - 调用
authenticate方法进行验证
3.3 握手与验证过程
- TeamServer进入
SecureServerSocket.this.authenticate方法- 在
var4.readInt()处阻塞等待Controller发送数据
- 在
- Controller构造数据包:
- 先写入标志位
48879(int) - 写入密码长度(byte)
- 写入密码
- 用
65填充剩余空间 - 总长度不超过261字节(256+5)
- 先写入标志位
- TeamServer验证:
- 检查标志位是否正确
- 读取密码
- 读取填充字符
- 对比密码
- 验证成功则写回标志位
51966
- Controller验证返回的标志位
4. aggressor.authenticate流程
4.1 TeamServer处理
- 创建Socket连接
- 创建
ManageUser对象处理Controller信息
4.2 Controller处理
- 创建
TeamQueue处理与TeamServer通信- 构造函数中创建两个线程:
TeamReader: 读取TeamServer数据TeamWriter: 向TeamServer发送数据
- 构造函数中创建两个线程:
- 调用
call方法发送aggressor.authenticate- 传递user、pass、版本号组成的对象
call方法关键操作:- 使用
addRequest将构造好的Request对象存入LinkedList TeamWriter线程从LinkedList中取数据发送
- 使用
4.3 请求处理流程
- TeamServer的
ManageUser循环等待请求 - 进入
process方法处理请求- 根据任务类型执行对应操作
- 验证版本和密码
- 验证成功返回
SUCCESS - 启动
BroadcastWriter线程
4.4 响应处理
- Controller的
TeamReader接收响应- 接收的是
Reply对象(与Request结构相似)
- 接收的是
- 使用之前存储的
callback值调用对应类的result方法 - 判断返回值为
SUCCESS后发送aggressor.metadata
5. aggressor.metadata流程
- Controller调用
call发送aggressor.metadata- 参数为当前时间戳
- TeamServer的
ManageUser处理请求- 执行一系列Map操作
- 返回信息给Controller
- Controller处理响应
- 进入
Connect处理aggressor.metadata - 调用
AggressorClient.setup方法初始化界面 - 发送
aggressor.ready表示完成
- 进入
6. 数据同步流程
6.1 TeamServer处理
- 在
register方法中:- 将user与对应的
manageUser存入Map - 调用
playback处理同步
- 将user与对应的
playback方法:- 计算
this.transcripts与this.replayme总大小 - 调用
send方法发送数据
- 计算
send方法:- 通过用户名从Map获取对应的
ManageUser - 打包信息为
Reply或Request发送
- 通过用户名从Map获取对应的
6.2 Controller处理
TeamReader接收消息callback为0时进入else分支- 调用
DataManager.result方法处理
- 判断
sent与total是否相等- 确认同步是否完成
- 遍历并调用对应的
result方法
6.3 数据发送细节
- TeamServer遍历
this.transcripts和this.replayme- 修改当前message信息
- 先发送
playback.status包 - 再发送Key、Value数据
- 递增
sent计数器
- Controller处理:
- 判断为Data类型进入对应分支
- 非
ChangeLog类型内容存入Map
- 提供当前用户信息给Controller
7. 常态化通信
- TeamServer处理:
- 接收Controller的
aggressor.ping BroadcastWriter回写Beacons信息
- 接收Controller的
- 进入稳定通信状态
8. 流程图
Controller连接流程:
1. 密码校验
Controller -> [48879标志+密码+填充] -> TeamServer
TeamServer -> [51966标志] -> Controller
2. aggressor.authenticate
Controller -> [认证请求] -> TeamServer
TeamServer -> [SUCCESS] -> Controller
3. aggressor.metadata
Controller -> [元数据请求] -> TeamServer
TeamServer -> [元数据响应] -> Controller
Controller -> [aggressor.ready] -> TeamServer
4. 数据同步
TeamServer -> [同步数据] -> Controller
5. 常态化通信
Controller <-> [ping/数据交换] <-> TeamServer
9. 关键数据结构
- Request: 请求数据结构
- Reply: 响应数据结构
- TeamQueue: 通信队列
- TeamReader: 读取线程
- TeamWriter: 写入线程
- ManageUser: TeamServer端用户管理
- BroadcastWriter: 广播写入线程
10. 参考实现要点
- 密码校验使用固定标志位(48879/51966)
- 通信使用自定义协议封装
- 多线程处理请求和响应
- 回调机制处理异步通信
- 数据同步采用增量方式
11. 安全注意事项
- 密码传输未加密(仅简单填充)
- 固定标志位可能被识别
- 通信协议可被逆向分析
- 缺乏强加密机制