C2通信
概念
C2(Command and Control,命令与控制)通信,是木马与攻击者控制端之间交换心跳、主机信息、任务和结果的通信机制。它通常不只是“连接一个服务器”,而是一整套协议,包括:
初始化
→ 注册主机
→ 获取唯一标识
→ 建立加密会话
→ 周期性心跳
→ 接收任务
→ 回传结果
→ 失败重试或切换备用地址
从木马行为分析角度,C2 的价值主要体现在三点:
- 让攻击者持续控制受害主机;
- 为后续命令、下载、注入和数据窃取提供通道;
- 通过加密、伪装和周期性通信降低被发现的概率。
因此,检测 C2 不能只依赖域名或 IP 黑名单,还需要把网络流量、进程行为、主机标识采集和加密实现结合起来分析。
通信阶段
1. 初始连接与注册
木马首次运行时,通常会向 C2 发送一条注册请求,用于报告主机环境并获取后续配置:
启动
→ 收集主机信息
→ 生成或读取主机 ID
→ 发送注册包
→ 接收会话参数、任务或心跳间隔
注册信息可能包括:
- 主机唯一标识;
- 计算机名、用户名和当前会话;
- Windows 版本、语言和时区;
- 处理器、内存和磁盘信息;
- 当前权限、是否为虚拟机以及安全软件信息;
- IP 地址、代理配置和网络环境;
- 木马版本、功能模块和已执行阶段。
首次注册前出现大量硬件、系统和安全软件信息采集,再紧接着访问低信誉公网地址,是较有价值的行为组合。
2. 心跳与任务轮询
注册完成后,木马可能采用固定周期、随机抖动或失败退避机制发送心跳:
等待 N 秒
→ 发送心跳或拉取任务
→ 解析响应
→ 执行任务
→ 回传结果
→ 进入下一轮等待
Beacon 是什么
Beacon 在 C2 通信中通常指木马按照一定策略,周期性向控制端“报到”或请求任务的通信行为,也可以指实现这种通信功能的木马组件。中文语境中常译为:
信标 / 心跳 / 上线探测
一次典型 Beacon 可以抽象为:
等待一段时间
→ 连接 C2
→ 发送 Host ID、状态和结果
→ 拉取待执行任务
→ 接收响应
→ 断开或保持连接
它的核心作用是维持“主机仍然在线”的状态,并让控制端能够在不主动连接受害主机的情况下下发命令。Beacon 不一定每次都包含完整任务,有时只发送状态和主机标识;如果服务端有任务,才会返回命令、配置或下载地址。
Beacon 与普通心跳的侧重点略有不同:
- 心跳更强调连接是否存活或服务是否正常;
- Beacon通常还承担上线、主机识别、任务轮询、结果回传和会话维持。
实际实现中两者经常混用,因此检测时重点应放在通信时序和上下文,而不是术语本身。
Beacon 的时间策略
为了避免形成过于明显的固定周期,木马可能使用以下策略:
固定间隔:每隔 N 秒通信
随机抖动:N ± 随机时间
失败退避:连接失败后逐渐延长等待时间
任务唤醒:收到任务后立即回连或上传结果
工作时段:只在特定时间范围内通信
长短睡眠:根据任务类型切换等待时间
例如,观察到的连接间隔可能并不完全相同,但仍会围绕某个基准值分布。随机抖动会降低简单的固定间隔规则效果,却通常不能消除长期统计上的周期性。
Beacon 的通信内容
Beacon 请求或响应中可能包含:
- Host ID、木马版本和会话标识;
- 当前用户名、计算机名、权限和在线状态;
- 上一次任务的执行结果或错误码;
- 待执行命令、模块下载地址和配置更新;
- 文件列表、系统信息或其他收集结果;
- 下一次通信间隔、备用 C2 和代理配置。
如果采用自定义加密协议,网络侧可能只能看到固定头部、长度字段和高熵数据,但仍可通过请求方向、包长、间隔、重试和进程上下文识别 Beacon。
常见任务类型包括:
- 下载或更新模块;
- 执行命令或脚本;
- 收集文件、屏幕或系统信息;
- 上传压缩包或执行结果;
- 加载内存模块、注入其他进程;
- 修改配置、持久化或自删除。
周期性不一定是严格固定的。较成熟的实现会加入随机延迟、失败重试、代理切换和睡眠时间,以减少简单的固定间隔检测。
主机唯一标识
标识的作用
C2 需要知道“当前连接来自哪台主机”,因此木马通常会在首次运行时生成或收集一个 Host ID,并在后续请求中重复携带。服务端可能据此:
- 区分不同受害主机;
- 关联同一主机的多次上线;
- 保存任务状态和配置;
- 防止重复注册;
- 判断主机是否已经执行过某个阶段。
Host ID 只是主机标识,不等于安全认证。若协议没有额外的会话认证,攻击者或分析人员可能伪造该字段。
常见组成字段
较常见的组合是读取多个系统属性,再拼接、编码或哈希生成最终标识:
主板 UUID
+ OS 序列号
+ HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid
+ 计算机名或磁盘信息
→ 规范化
→ 哈希 / 编码
→ Host ID
其中:
- 主板 UUID:通常来自 SMBIOS,可通过 WMI、系统固件信息或其他硬件查询接口获得;
- OS 序列号:可能来自系统授权或操作系统相关信息;
- MachineGuid:常见位置为
HKLM\SOFTWARE\Microsoft\Cryptography\MachineGuid,用于区分 Windows 安装实例; - 计算机名、用户名、磁盘序列号:有时作为补充字段,帮助提高区分度。
在 Windows 遥测中,可能看到以下相关访问:
WMI / SMBIOS 查询
+ 注册表读取 MachineGuid
+ 系统版本与序列号查询
+ 随后访问公网 C2
生成方式
一种常见抽象流程是:
读取多个字段
→ 去除空格、大小写和分隔符差异
→ 按固定顺序拼接
→ Hash / HMAC
→ Base64、十六进制或自定义编码
例如,分析时可以把以下字段作为候选输入进行验证:
normalized(board_uuid + os_serial + machine_guid)
→ SHA-256 或其他摘要
→ 截取部分字节作为 Host ID
实际样本可能使用 MD5、SHA-1、SHA-256、CRC、异或或自定义混淆。不要因为 Host ID 看起来是十六进制字符串,就直接断定它使用了某一种哈希算法。应结合样本中的输入长度、调用 API、输出长度和多台主机样本进行验证。
稳定性与误判
硬件和系统字段并不总是稳定:
- 虚拟机克隆可能产生重复或相同的 UUID;
- 重装系统可能改变
MachineGuid; - 主板更换可能改变 SMBIOS UUID;
- 某些设备字段为空、格式异常或被厂商统一填充;
- 隐私工具、系统加固或权限限制可能阻止部分查询。
因此,木马可能采用多字段回退逻辑:某个字段读取失败时使用其他字段,或者将首次生成的随机 ID 写入注册表、文件或配置中长期保存。
检测时,单独读取 MachineGuid 或查询 SMBIOS 并不等于恶意;更有价值的是:
多种硬件 / 系统标识采集
→ 本地拼接、哈希或编码
→ 立即向异常公网地址发送
加密通信
加密的目的
C2 加密通常用于保护以下内容:
- Host ID 和注册信息;
- 命令、任务和执行参数;
- 文件列表、系统信息和凭据;
- 下载模块或更新包;
- 心跳、错误码和结果数据。
加密不一定意味着使用了标准 TLS。木马可能使用:
HTTPS / TLS
自定义 TCP + 对称加密
HTTP 外观 + 加密 Body
DNS 查询中的编码数据
WebSocket 或其他长连接
需要区分“传输层加密”和“应用层加密”:
TLS
→ 保护传输通道
应用层 AES / RC4 / XOR / 自定义算法
→ 保护消息内容
两者可以单独使用,也可能叠加使用。
Windows CryptoAPI 密钥派生
较早或兼容性较强的 Windows 木马可能使用 CryptoAPI 生成或派生对称密钥。典型 API 组合可以抽象为:
CryptAcquireContextW
→ 获取 CSP 密码服务提供程序上下文
→ CryptCreateHash
→ CryptHashData(种子、配置或主机相关数据)
→ CryptDeriveKey
→ CryptEncrypt / CryptDecrypt
其中:
CryptAcquireContextW:获取或创建加密服务提供程序(CSP)上下文,本身不等于完成密钥派生;CryptCreateHash、CryptHashData:将密码、配置、硬编码常量或主机信息处理为哈希对象;CryptDeriveKey:根据哈希结果派生对称密钥,例如用于 AES、RC4 或 3DES;CryptEncrypt/CryptDecrypt:对 C2 请求、响应或本地载荷进行加解密。
常见抽象链路是:
硬编码密钥 / 配置种子 / Host ID
→ HashData
→ CryptDeriveKey
→ 加密注册包、心跳和任务数据
也可能使用随机数生成会话材料:
CryptAcquireContextW
→ CryptGenRandom
→ 生成随机密钥或 IV
→ 加密通信内容
需要注意,CryptAcquireContextW + CryptDeriveKey 只能说明样本使用了 CryptoAPI 相关能力,不能单独证明算法、密钥和通信协议。仍需结合 ALG_ID、密钥长度、哈希输入、初始化向量和调用上下文分析。
CNG 与其他实现
较新的实现可能使用 Windows CNG:
BCryptOpenAlgorithmProvider
→ BCryptGenerateSymmetricKey
→ BCryptEncrypt / BCryptDecrypt
也可能静态或动态链接第三方密码库。常见分析线索包括:
- AES、RC4、ChaCha20 等算法常量;
- Base64、十六进制和自定义编码函数;
- 固定 IV、固定密钥或配置中的密钥材料;
- 加密前后的长度变化、填充和消息头;
- 哈希、HMAC、随机数和密钥派生调用。
弱加密与协议特征
恶意样本中的“加密通信”不一定安全。常见问题包括:
- 密钥硬编码在样本或配置中;
- 多台主机使用相同密钥;
- 直接用 Host ID 作为密钥;
- 固定 IV 或没有随机数;
- 只加密 Body,不验证完整性;
- 自定义 XOR、滚动异或或压缩后编码;
- TLS 证书校验被关闭或使用固定证书指纹。
这些问题既有助于逆向还原协议,也有助于网络检测和流量聚类。
常见 C2 传输形态
HTTP / HTTPS
常见表现是向固定或动态 URL 发起周期性请求,将注册信息、心跳或加密数据放入:
- POST Body;
- Cookie;
- 查询参数;
- 自定义 Header;
- multipart 或伪装成图片、更新包的响应。
可重点观察:
固定 URI / Header 顺序
+ 固定或相近请求体长度
+ 周期性访问
+ 响应中出现高熵二进制数据
DNS C2
木马可能把 Host ID、命令片段或结果编码到子域名中,通过 TXT、A 或 AAAA 查询与控制端交互。重点特征包括:
- 子域名长度异常;
- 字符集集中在 Base32、Base64 变体或十六进制;
- 查询频率固定;
- 同一主机持续查询大量低信誉子域名;
- NXDOMAIN 比例异常或域名生命周期很短。
长连接与自定义 TCP
木马可能建立长连接,使用自定义头部、长度字段、序列号和加密 Body:
连接建立
→ 握手 / 注册
→ 长时间保持
→ 心跳
→ 双向任务与结果
即使无法解密,也可以通过连接时长、包长、方向、间隔和重连规律进行行为分析。
C2 流量检测
IOC 检测
IOC 适合快速阻断和回溯,常见维度包括:
- C2 IP、域名、URL 和 URI;
- TLS 证书指纹、证书主题和异常自签名证书;
- SNI、JA3 / JA4、HTTP User-Agent;
- DNS TXT 查询、异常子域名和注册信息;
- 代理、跳板、重定向和云存储地址;
- 下载文件、配置文件、互斥体、注册表键和任务名称;
- Host ID 字段格式、固定请求头和加密包头。
IOC 的局限是容易变更。攻击者更换 IP、域名、证书或路径后,静态规则可能立即失效,因此 IOC 应与行为规则结合。
网络行为检测
周期性 Beacon
检测同一进程到同一目的地的重复连接,重点计算 Beacon 的时间和内容特征:
- 连接间隔的平均值和方差;
- 连接间隔是否围绕固定基准值或呈现随机抖动;
- 请求和响应大小;
- 请求方向是否稳定为“客户端发起、服务端短响应”;
- 是否存在注册包、心跳包、任务包和结果包的不同长度模式;
- 失败后的重试与退避;
- 工作时间外的连接;
- 多台主机是否出现相似目的地和时间模式。
典型行为是:
低频、长时间、固定目的地
+ 请求长度相近
+ 间隔具有周期性或稳定抖动
+ 进程本身不是常见网络客户端
异常加密流量
加密本身不能作为恶意判定依据,但以下组合值得关注:
- 非浏览器、非更新程序发起 TLS 连接;
- 目的地稀有、注册时间短或信誉低;
- TLS 指纹与进程正常业务不匹配;
- 证书校验异常、固定证书或自签名证书;
- 连接前刚刚采集 MachineGuid、SMBIOS 和系统序列号;
- 加密请求中存在固定长度、固定头部或明显的注册—心跳时序。
DNS 异常
可结合以下指标:
- 子域名熵和长度;
- 唯一子域名数量;
- 请求间隔;
- NXDOMAIN 和 TXT 响应比例;
- 域名年龄、解析变化和 ASN;
- 同一进程是否直接访问 DNS,而不是通过企业解析链路。
终端行为检测
将网络连接与进程、文件和系统 API 关联,通常比单纯分析流量更容易定性:
用户目录 / 临时目录进程
→ 查询 MachineGuid、SMBIOS、OS 序列号
→ CryptAcquireContextW / CryptDeriveKey
→ 访问稀有公网地址
→ 周期性发送加密数据
重点关联:
- 发起连接的进程路径、签名和父子进程关系;
- 是否刚完成 UAC 绕过、令牌复制或进程注入;
- 是否在联网前读取主机唯一标识;
- 是否加载 WinINet、WinHTTP、Schannel 或自定义网络库;
- 是否使用 CryptoAPI、CNG 或第三方加密库;
- 是否同时创建配置文件、互斥体、服务或计划任务;
- 网络连接后是否出现命令执行、文件下载、内存加载或数据压缩。
流量聚类与关联
当域名和 IP 不稳定时,可使用以下特征进行聚类:
- 请求 URI 和 Header 顺序;
- 请求、响应长度分布;
- Beacon 间隔和重试模式;
- TLS ClientHello 指纹;
- DNS 子域名编码格式;
- 加密数据包头和版本字段;
- Host ID 长度、字符集和位置;
- 进程路径、启动来源和访问目标的组合。
这类特征适合发现同一木马的不同基础设施,而不依赖某一个固定 IOC。
高价值检测链
注册型 C2
读取 MachineGuid / SMBIOS UUID / OS 序列号
→ 拼接、哈希或编码
→ 读取配置中的地址
→ 首次 HTTP(S) 注册
→ 周期性心跳
自定义加密 C2
CryptAcquireContextW
→ CryptCreateHash / CryptHashData
→ CryptDeriveKey
→ CryptEncrypt / CryptDecrypt
→ WinHTTP / WinINet / 原生 Socket 通信
提权后 C2
提权或进程注入
→ 收集主机和安全产品信息
→ 加密注册
→ 周期性 Beacon
→ 下载模块、执行命令或回传数据
如果 C2 进程同时具备高权限、异常宿主进程、加密 API 调用、硬件标识采集和周期性外联,优先级应明显高于单独的网络连接事件。
研判边界
需要区分以下结论:
- 访问
MachineGuid、SMBIOS 或系统序列号,只能说明进行了主机信息采集; - 调用
CryptAcquireContextW或CryptDeriveKey,只能说明使用了 CryptoAPI 相关能力; - 周期性 HTTPS 连接不等于 C2,备份、更新和监控软件也可能有类似行为;
- 高熵数据不等于恶意加密,正常压缩、上传和加密业务同样可能产生高熵流量;
- 域名或 IP 命中 IOC 可以提升风险,但仍应结合进程、时间线和后续任务行为;
- 加密流量无法解密时,仍可通过连接元数据、时序、包长、TLS 指纹和终端行为进行判断。
较高置信度的结论通常来自下面的组合:
异常进程
+ 主机唯一标识采集
+ 自定义加密或异常 TLS 行为
+ 周期性外联
+ 稀有或低信誉目的地
+ 后续命令、下载、注入或数据回传
小结
C2 通信可以概括为:
识别主机
→ 建立加密通道
→ 周期性保持上线
→ 接收任务
→ 执行并回传结果
其中,主板 UUID、OS 序列号和 MachineGuid 等字段常被组合成 Host ID;CryptAcquireContextW、CryptDeriveKey 及相关哈希、加密 API 可能用于生成会话密钥和保护数据。
检测时不要只看一个域名、一个 IP 或一个加密 API,而要把以下证据串起来:
主机标识采集
+ 密钥派生 / 加密
+ 周期性网络连接
+ 稀有目的地或异常协议
+ 进程和后续任务行为
这比单独依赖 IOC 更能发现更换基础设施、使用 HTTPS 或采用自定义加密协议的 C2。