C2(Command and Control)框架是红队基础设施的核心。它不只是发命令收结果这么简单——通信隐蔽性、会话管理、任务编排和抗检测能力,每一层都有大量工程细节。
这篇文章从原理出发,拆解 C2 框架的核心模块和设计取舍。下一篇会动手写一个最小化的 HTTP beacon,把注册、心跳、任务轮询和回传跑通。
C2 框架的核心模块
一个完整的 C2 框架由几个逻辑组件构成,不管用 Cobalt Strike 还是开源项目如 Sliver、Havoc、Mythic,架构大同小异。
1. Listener
Listener 是服务端暴露的入口,负责接收 beacon 的通信请求。核心决策是协议和传输层。
常见类型:
-
HTTP/HTTPS Listener:最通用。beacon 定期 GET/POST 到指定 URI,请求体里编码任务和结果。HTTPS 比 HTTP 难检测很多,TLS 加密后的请求在流量侧看和正常 API 调用没有区别。但 HTTPS 引出一个实际的问题:证书必须可信或允许忽略证书校验。公共 CDN 的证书在目标机器上是受人信任的,自签名证书容易触发企业证书固定检测。
-
DNS Listener:利用 DNS 查询做通信。beacon 查询特定域名,编码后的命令藏在子域名里,结果通过 TXT 记录回传。DNS 流量几乎不会被防火墙阻断——大多数企业不会封 DNS 出站。代价是延迟大、带宽小,一个完整的载荷可能需要拆成几十次 DNS 查询才能传完。DNS 缓存也是问题——递归 DNS 服务器的 TTL 缓存会让部分查询走不到你的权威 DNS 服务器。
-
TCP Listener:直连通信,效率和响应速度最好。但 TCP 连接特征是明显的——持久连接、心跳包频率固定,入侵检测系统很容易识别。Cobalt Strike 的 TCP beacon 虽然有阶段化处理,但在流量层面 TCP 流模式的熵值远低于正常业务流量。
-
SMB / Named Pipe Listener:只在 Windows 内网横向移动时用,不出网,完全在内网管道上通信。用的 Windows 命名管道(
\\.\pipe\),流量不走网络栈,绕着走。优点是杀毒软件和 EDR 对命名管道的监控强度远低于对网络端口的监控。
Listener 设计有个硬约束:隐蔽性和带宽不可兼得。HTTPS 扫不出但延迟 100-200ms,DNS 哪里都能通但有效带宽可能不到 10 bps。实战中通常配两个 listener——一个高隐蔽低带宽的用于心跳保活,一个高带宽的用于数据传输。
2. Beacon
Beacon 是植入受害者机器的 Agent,负责执行服务端下发的任务并回传结果。它的生命周期管理是框架最复杂的部分。
回连间隔与 Jitter:beacon 每隔 sleep_time +/- jitter 秒发起一次连接。这个间隔通常 30 秒到数分钟。加 jitter 的目的是让间隔不是固定值——固定 60 秒一次的 beacon 在流量时序图上就是完美的等距脉冲,检测规则就一行 abs(interval - 60) < 2 的事。好的 jitter 实现是高斯分布,让时序图看起来像正常的业务请求模式。
# 一个典型的 sleep + jitter 实现
sleep_base = 60 # 秒
jitter_pct = 0.2 # 20%
actual_sleep = sleep_base * (1 + random.gauss(0, jitter_pct))
time.sleep(max(actual_sleep, sleep_base * 0.5))
任务队列模型:beacon 服务端下发任务后不会立刻执行,而是等 beacon 下一次回连时拉取。异步模型的优点是不要求受害机器持续在线——笔记本合盖断网、虚拟机挂起,任务依旧在队列里等待。缺点也很实在:调试时发一个命令要等 60 秒才知道结果。
注册与心跳:beacon 首次启动会发一个注册请求,向服务端声明自己的身份(机器名、用户名、内网IP、操作系统版本)。之后的每次回连是心跳 + 任务拉取 + 结果回传的合并操作。心跳的间隔和格式是流量检测的重点关注区域——太多框架的心跳请求路径是硬编码的 /news.asp 或 /__utm.gif。
内存执行 vs 磁盘写入:现代 C2 框架的 beacon 大部分任务直接在内存中完成——反射式 DLL 注入(Reflective DLL Injection)、进程镂空(Process Hollowing)、直接系统调用(Direct Syscall)。一个写入磁盘的操作可能在杀毒软件的实时监控缓冲区里存活不到 30 秒。
Artifact 管理:beacon 的生成二进制是杀毒软件的重点检测对象。同一个 beacon 编译两次,特征字符串(C2 域名、内置 User-Agent、证书指纹)如果不随机化,生成的二进制会被 AV 用签名匹配直接标记。好的框架在 beacon 生成阶段做三步处理:特征字符串替换、分阶段加载器(stager → stager2 → payload)、以及通过直接系统调用绕过用户态钩子。
# Cobalt Strike artifact kit 的核心逻辑:
# 1. 替换 artifact 中所有 C2 域名和端口
# 2. 重新混淆字符串表,避免 YARA 规则命中
# 3. 改变入口点代码布局,改变哈希签名
# 这一步不做,VT 上传率 80%+
3. 通信协议设计
C2 通信的协议设计直接决定框架能不能执行完任务。
几种常见的设计模式:
-
轮询式:beacon 定时发起连接拉取任务。最简单、最稳定。问题是流量模式固定,检测工具提取时序特征后可以精确分类。
-
长连接式:WebSocket 或反向 SSL 隧道。延迟低,适合交互式操作。但连接长时间存活对 NTA(网络流量分析)来说是一个明显的持续信号。
-
异步混合式:心跳用 DNS 或 ICMP 做轻量存活检测,数据传输切到 HTTPS 通道。复杂但隐蔽性好。DNS 通道在正常流量中的占比是极低的——一个机器每分钟查询几十次 DNS 属于正常,如果同时产生大量异常格式的 DNS 查询,那也会触发检测。
-
协议模仿:把 C2 流量包装成目标机器上常见的应用协议。请求伪装成 API 调用,响应格式对齐 JSON:API 标准。Payload 可以藏在 JWT 的 payload 段里,或者编码成 Base64 图片参数。
C2 流量检测的难点在于区分正常的 API 调用和 beacon。看请求的顺序性:beacon 的序列是固定的(注册→心跳→任务拉取→结果回传),时序上是等间隔的脉冲。真实 API 的调用分布是随机的、跟着人走的。AI 驱动的流量分析工具正是在利用这个统计特征做分类。
JA3 指纹是一个常被忽视的问题:beacon 的 TLS Client Hello 参数包含密码套件顺序、扩展列表、椭圆曲线偏好等特征。Cobalt Strike 默认配置下 JA3 指纹是固定的。如果一个机器上的浏览器和 beacon 发出不同的 JA3 指纹,流量分析设备很容易标记这个异源 TLS 会话。定制 JA3 指纹的能力应该是选 C2 框架时的硬性要求。
4. 任务执行引擎
任务引擎把服务端指令翻译成实际的行为。常见任务类型:
| 类型 | 例子 |
|---|---|
| 命令执行 | cmd /c whoami |
| 文件操作 | 下载、上传、删除、搜索 |
| 进程管理 | 注入、迁移、dump |
| 网络侦察 | 端口扫描、路由表、ARP 表 |
| 凭据窃取 | Mimikatz、DPAPI、Browser data |
| 隧道转发 | SOCKS 代理、端口转发 |
任务执行的一个坑:调用系统的 cmd.exe 执行命令会在进程树上留下 cmd.exe → whoami.exe 的父子关系。这个进程树特征在 EDR 的事件日志里是一个高置信度的检测指标。好的框架用 CreateProcess + WMI、COM 对象调用或者直接 shellcode 执行来降低日志面上的噪音。实操中可以用 COM 的 WScript.Shell 对象或者 WMIC 进程创建,它们不走 CreateProcess 的标准路径,在进程树上的父进程签名会更像业务行为。
红队选框架时的几件事
选择 C2 框架不只看功能列表:
- Profile 可定制深度:能不能自定义 HTTP 请求头顺序、URI 路径模式、JA3 指纹。Cobalt Strike 的 Malleable C2 Profile 是行业标准。一个典型的 profile 片段:
http-get {
set uri "/api/v2/status";
client {
header "Accept" "application/json";
header "X-Requested-With" "XMLHttpRequest";
metadata {
base64url;
prepend "session=";
header "Cookie";
}
}
server {
header "Content-Type" "application/json";
output {
base64;
print;
}
}
}
这个配置把 beacon 的 HTTP GET 请求伪装成了前端轮询后端状态的 AJAX 调用。请求头、Cookie 格式、URI 路径都和正常业务一致,混在流量里很难被挑出来。不能自定义 profile 的框架出框率极低。
-
Artifact 更新频率:框架的 beacon 样本被 AV 厂商标记后,响应速度是关键。商业化框架有专门团队更新 artifact kit,开源项目依赖社区 PR,响应速度是硬伤。
-
日志和审计:红队也是团队协作。框架需要记录谁在什么时间对哪台机器执行了什么操作,方便回顾和写报告。
-
Pivot 能力:能不能拿一台受控机器当跳板继续向内网渗透。好的框架内置 SOCKS proxy 和端口转发,差的框架需要手工配合 sshuttle 或者 frp。
写在后面
C2 框架不只是渗透工具,它是对网络通信、进程管理和对抗检测的综合工程实践。理解 C2 的原理想对防守者也同样重要——只有理解攻击者的通信模型,才能设计有效的检测策略。
从简单开始总没错,但做 C2 框架的人必须一开始就理解这些设计的权衡,否则做出来的东西只能在内网靶场跑一跑,上不了真正的对抗场景。
⚠️ 网络安全免责声明
本文内容仅供技术研究与安全学习之用。文章中描述的 C2 框架原理和模块设计旨在帮助安全从业者深入理解攻击基础设施的运作机制,从而提升检测和防御能力,并非提供可供直接部署的攻击工具。
作者对 C2 框架的研究基于公开资料和开源项目(如 Cobalt Strike 公开文档、Sliver、Havoc、Mythic 等),文中所有描述均为技术原理层面的探讨。
任何利用文中所述技术原理进行未经授权的渗透测试或攻击行为,均与本文作者无关。进行渗透测试前请确保已获得目标系统的书面授权。未经授权的渗透测试违反中华人民共和国《网络安全法》及相关法律法规。
浙公网安备 33010602011771号