AdaptixC2通信机制与流量解密分析(listener_beacon_http)
字数 3340 2025-09-23 19:27:46

AdaptixC2 listener_beacon_http 通信机制与流量解密技术详解

一、 分析环境与工具准备

在进行逆向与流量分析前,需搭建以下环境:

  1. AdaptixC2 源码:需自备 AdaptixC2_main_v0.8 源码,这是分析的基础。关键代码位于 Extenders/AdaptixServer/ 目录。
  2. 分析工具
    • mitmproxy:用作中间人(MITM)代理,拦截并解密 HTTPS 流量(降级为 HTTP 明文)。使用命令:
      mitmproxy --listen-port 8080 --ssl-insecure --set ssl_version_client=TLSv1_2 -w output.mitm
      
    • Wireshark:进行原始流量抓包。需配置 sslkeys.log 环境变量以解密 TLS 流量。
  3. 编程环境:使用 IDE(如 VS Code 或 GoLand) 阅读和跟踪 Go 语言源码。同时需准备 Python 环境来编写解密脚本。

二、 核心通信机制与加解密流程

AdaptixC2 的通信采用多层加密,理解其密钥体系是解密的关键。

1. 初始心跳(注册)与静态 RC4 密钥
  • 触发:Agent(agent.x64.exe)首次上线时,向 C2 Server 发送一个 HTTP GET 请求作为心跳包。
  • 密钥生成与存储
    • 当在 C2 Server 端创建 listener_beacon_http 监听器时,会随机生成一个 16 字节的加密密钥
    • 该密钥存储在 HTTPConfig.EncryptKey 中。
    • 此密钥会持久化保存在服务端的数据库 adaptixserver.db 中。
    • 在提供的例子中,该密钥的 Base64 编码为:kJiY+eNoaq/j8VvSHUOl0Q==
  • 数据携带:Agent 将心跳数据(称为 beat)通过 HTTP 头 x-nws-log-uuid 发送(该示例中)或类似的自定义头。
  • 第一层解密(心跳包)
    • C2 Server 从 HTTP 头中读取 Beat 数据(Base64 编码)。
    • 使用监听器的静态 EncryptKey 进行 RC4 解密
    • 解密后的明文 beat 数据结构如下:
      • 前 8 字节Agent Type (4 字节) + Agent ID (4 字节)
      • 后续部分:包含 Flags 字段和多个可变长度字符串(如 Hostname, Username, Executable 路径等)。
    • 在此 beat 数据的偏移量 36 字节后,存储着用于后续通信的 SessionKey
2. 会话密钥 (SessionKey) 与动态加密
  • SessionKey 的提取:服务端的 CreateAgent 函数(位于 pl_agent.go)在解析初始心跳包时,会从解密后的 beat 数据中提取出 SessionKey。这是 Agent 与 C2 后续所有通信的对称会话密钥
  • 双重加密模型:后续的任务下发和结果回传都采用两层加密
    1. 第一层(外层):使用监听器的静态 EncryptKeykJiY...)进行 RC4 加密。
    2. 第二层(内层):使用本次会话的动态 SessionKey 进行 RC4 加密。

三、 流量解密实战分析

通信过程包含三个关键数据包,下图清晰地展示了其交互流程和解密层次:

sequenceDiagram
    participant A as Agent
    participant S as C2 Server
    participant M as mitmproxy/Wireshark

    Note over A, S: 1. 初始心跳 (注册)
    A->>S: HTTP GET<br/>Header: x-nws-log-uuid=RC4(EncryptKey, beat_data)
    Note left of A: beat_data中包含SessionKey
    S-->>A: HTTP Response<br/>(无任务data字段为空)

    Note over A, S: 2. 任务下发 (C2 -> Agent)
    S->>A: HTTP Response<br/>Body: { data: RC4(EncryptKey, RC4(SessionKey, Task)) }
    Note right of S: 任务示例: whoami
    M->>M: 解密外层(RC4_EncryptKey)<br/>得到: RC4(SessionKey, Task) 密文

    Note over A, S: 3. 任务执行与结果回传 (Agent -> C2)
    A->>S: HTTP POST<br/>Body: RC4(EncryptKey, RC4(SessionKey, Result))
    Note left of A: 执行命令,回传结果
    M->>M: 解密外层(RC4_EncryptKey)<br/>得到: RC4(SessionKey, Result) 密文

接下来,我们对每个阶段进行详细剖析。

阶段一:解密初始心跳包

目标:验证静态密钥并提取 Agent 信息。

  • 源码定位AdaptixC2_main_v0.8/Extenders/listener_beacon_http/pl_http.go
  • 解密脚本 (Beacon_Http_Rc4_Decode.py):
#!/usr/bin/env python3
import base64
from Crypto.Cipher import ARC4
import argparse

def main():
    parser = argparse.ArgumentParser(description='Decode AdaptixC2 Beacon HTTP Traffic')
    parser.add_argument('--key', required=True, help='Base64 encoded RC4 key')
    parser.add_argument('--header', required=True, help='Base64 encoded data from header')
    args = parser.parse_args()

    # Decode the key and data
    rc4_key = base64.b64decode(args.key)
    encrypted_data = base64.b64decode(args.header)

    # Decrypt with RC4
    cipher = ARC4.new(rc4_key)
    decrypted_data = cipher.decrypt(encrypted_data)

    print(f"Decrypted Hex: {decrypted_data.hex()}")
    print(f"Decrypted Raw: {decrypted_data}")

if __name__ == '__main__':
    main()
  • 操作命令与结果
    python .\Beacon_Http_Rc4_Decode.py --key kJiY+eNoaq/j8VvSHUOl0Q== --header QCcNx3EyLCgMPAr+TnGdPy5RQIdfmYiADUkr3b11iT4laCf11qgYliN/2zwR8T1rFBOnksPrZ/Q6prmuCbfsHRtYHggVmMaoQ1mFkZftDQx6nZd0pkguBWgO4fAFuy93jJoWi7FXSEPzoTAWUjmG0C7fzW70qHxD4Q==
    
  • 输出分析:解密后的数据应包含可读的字符串(主机名、用户名、进程路径等),与 C2 控制台界面显示的信息一致。SessionKey 也包含在这段解密后的数据中,为后续通信所用。
阶段二:解密任务下发包 (C2 -> Agent)

目标:解密 C2 服务器下发给 Agent 的指令。

  • 流量特征:在 Wireshark 或 mitmproxy 中,此包是 Server 对 Agent 心跳的 HTTP 响应包。其 HTTP Body 是一个 JSON,其中包含一个 data 字段,值为长长的 Base64 字符串。

  • 解密步骤

    1. Base64 解码 data 字段的值,得到密文 C1
    2. 使用监听器的静态 EncryptKeyC1 进行 RC4 解密,得到中间密文 C2C2 实际上是使用 SessionKey 加密后的任务数据。
    3. 使用从阶段一获取的 SessionKeyC2 进行 第二次 RC4 解密,得到最终的明文任务数据。
  • 明文任务格式:解密后通常为二进制格式,可能包含指令类型(如 0x0001 代表 shell)、任务 ID 以及具体的命令(如 C:\Windows\System32\cmd.exe /c whoami)。明文数据周围常包含填充字符(如 0x00)以规避简单的流量特征检测。

阶段三:解密结果回传包 (Agent -> C2)

目标:解密 Agent 执行命令后返回给 C2 的结果数据。

  • 流量特征:通常是 Agent 发出的 HTTP POST 请求,请求体内包含加密的二进制数据。
  • 解密步骤
    1. 提取 HTTP 请求体(Raw Body)。
    2. 使用监听器的静态 EncryptKey 进行 第一层 RC4 解密
    3. 使用 SessionKey 对上述结果进行 第二层 RC4 解密,得到命令执行输出的明文(如 desktop-123\user)。

四、 核心代码逻辑追溯

理解代码调用链对深入分析至关重要:

  1. 服务端任务打包

    • 入口AdaptixC2_main_v0.8/AdaptixServer/core/server/ts_agent.go 中的 TsAgentGetHostedAll 函数。它从数据库获取任务队列。
    • 调用:调用 ts.Extender.ExAgentPackData(位于 AdaptixServer/core/extender/ex_agent.go)。
    • 路由ExAgentPackData 根据 Agent 类型,找到对应的 Agent 插件(如 agent_beacon)。
    • 最终加密:插件中的 AgentPackData 方法(位于 Extenders/agent_beacon/pl_main.go)将任务数据序列化后,用 SessionKey 加密,再交由监听器用 EncryptKey 加密。
  2. 客户端加解密函数

    • Extenders/agent_beacon/pl_agent.go 中定义了 AgentEncryptDataAgentDecryptData 函数,其内部就是标准的 RC4 算法操作,用于处理 SessionKey 层的加解密。

五、 总结与完整解密思路

AdaptixC2 (listener_beacon_http) 的通信保密性通过两层加密实现:

  1. 第一层(固定层):使用监听器初始化时生成的 EncryptKey。用于加密初始心跳包和所有后续通信的外层
  2. 第二层(会话层):每个 Agent 上线时在心跳包中携带的 SessionKey。用于加密内层的实际任务和结果数据。

因此,完整的解密前提是

  • 获取到 C2 Server 配置中或数据库中的静态 EncryptKey
  • 成功解密第一个心跳包,并从明文中提取出 SessionKey

一旦同时拥有这两个密钥,即可完全解密该监听器下所有 Agent 的整个通信过程。这种分析手法对于深度威胁狩猎、C2 流量监控和恶意软件逆向工程具有重要价值。


AdaptixC2 listener_ beacon_ http 通信机制与流量解密技术详解 一、 分析环境与工具准备 在进行逆向与流量分析前,需搭建以下环境: AdaptixC2 源码 :需自备 AdaptixC2_main_v0.8 源码,这是分析的基础。关键代码位于 Extenders/ 和 AdaptixServer/ 目录。 分析工具 : mitmproxy :用作中间人(MITM)代理,拦截并解密 HTTPS 流量(降级为 HTTP 明文)。使用命令: Wireshark :进行原始流量抓包。需配置 sslkeys.log 环境变量以解密 TLS 流量。 编程环境 :使用 IDE(如 VS Code 或 GoLand) 阅读和跟踪 Go 语言源码。同时需准备 Python 环境来编写解密脚本。 二、 核心通信机制与加解密流程 AdaptixC2 的通信采用多层加密,理解其密钥体系是解密的关键。 1. 初始心跳(注册)与静态 RC4 密钥 触发 :Agent( agent.x64.exe )首次上线时,向 C2 Server 发送一个 HTTP GET 请求作为心跳包。 密钥生成与存储 : 当在 C2 Server 端创建 listener_beacon_http 监听器时,会 随机生成一个 16 字节的加密密钥 。 该密钥存储在 HTTPConfig.EncryptKey 中。 此密钥会 持久化保存 在服务端的数据库 adaptixserver.db 中。 在提供的例子中,该密钥的 Base64 编码为: kJiY+eNoaq/j8VvSHUOl0Q== 。 数据携带 :Agent 将心跳数据(称为 beat )通过 HTTP 头 x-nws-log-uuid 发送(该示例中)或类似的自定义头。 第一层解密(心跳包) : C2 Server 从 HTTP 头中读取 Beat 数据(Base64 编码)。 使用监听器的静态 EncryptKey 进行 RC4 解密 。 解密后的明文 beat 数据结构如下: 前 8 字节 : Agent Type (4 字节) + Agent ID (4 字节) 后续部分 :包含 Flags 字段和多个可变长度字符串(如 Hostname , Username , Executable 路径等)。 在此 beat 数据的 偏移量 36 字节后 ,存储着用于后续通信的 SessionKey 。 2. 会话密钥 (SessionKey) 与动态加密 SessionKey 的提取 :服务端的 CreateAgent 函数(位于 pl_agent.go )在解析初始心跳包时,会从解密后的 beat 数据中提取出 SessionKey 。这是 Agent 与 C2 后续所有通信的 对称会话密钥 。 双重加密模型 :后续的任务下发和结果回传都采用 两层加密 : 第一层(外层) :使用监听器的静态 EncryptKey ( kJiY... )进行 RC4 加密。 第二层(内层) :使用本次会话的动态 SessionKey 进行 RC4 加密。 三、 流量解密实战分析 通信过程包含三个关键数据包,下图清晰地展示了其交互流程和解密层次: 接下来,我们对每个阶段进行详细剖析。 阶段一:解密初始心跳包 目标 :验证静态密钥并提取 Agent 信息。 源码定位 : AdaptixC2_main_v0.8/Extenders/listener_beacon_http/pl_http.go 解密脚本 ( Beacon_Http_Rc4_Decode.py ): 操作命令与结果 : 输出分析 :解密后的数据应包含可读的字符串(主机名、用户名、进程路径等),与 C2 控制台界面显示的信息一致。 SessionKey 也包含在这段解密后的数据中 ,为后续通信所用。 阶段二:解密任务下发包 (C2 -> Agent) 目标 :解密 C2 服务器下发给 Agent 的指令。 流量特征 :在 Wireshark 或 mitmproxy 中,此包是 Server 对 Agent 心跳的 HTTP 响应包 。其 HTTP Body 是一个 JSON,其中包含一个 data 字段,值为长长的 Base64 字符串。 解密步骤 : Base64 解码 data 字段的值,得到密文 C1 。 使用监听器的静态 EncryptKey 对 C1 进行 RC4 解密 ,得到中间密文 C2 。 C2 实际上是使用 SessionKey 加密后的任务数据。 使用从阶段一获取的 SessionKey 对 C2 进行 第二次 RC4 解密 ,得到最终的明文任务数据。 明文任务格式 :解密后通常为二进制格式,可能包含指令类型(如 0x0001 代表 shell )、任务 ID 以及具体的命令(如 C:\Windows\System32\cmd.exe /c whoami )。明文数据周围常包含填充字符(如 0x00 )以规避简单的流量特征检测。 阶段三:解密结果回传包 (Agent -> C2) 目标 :解密 Agent 执行命令后返回给 C2 的结果数据。 流量特征 :通常是 Agent 发出的 HTTP POST 请求 ,请求体内包含加密的二进制数据。 解密步骤 : 提取 HTTP 请求体(Raw Body)。 使用监听器的静态 EncryptKey 进行 第一层 RC4 解密 。 使用 SessionKey 对上述结果进行 第二层 RC4 解密 ,得到命令执行输出的明文(如 desktop-123\user )。 四、 核心代码逻辑追溯 理解代码调用链对深入分析至关重要: 服务端任务打包 : 入口 : AdaptixC2_main_v0.8/AdaptixServer/core/server/ts_agent.go 中的 TsAgentGetHostedAll 函数。它从数据库获取任务队列。 调用 :调用 ts.Extender.ExAgentPackData (位于 AdaptixServer/core/extender/ex_agent.go )。 路由 : ExAgentPackData 根据 Agent 类型,找到对应的 Agent 插件(如 agent_beacon )。 最终加密 :插件中的 AgentPackData 方法(位于 Extenders/agent_beacon/pl_main.go )将任务数据序列化后,用 SessionKey 加密,再交由监听器用 EncryptKey 加密。 客户端加解密函数 : 在 Extenders/agent_beacon/pl_agent.go 中定义了 AgentEncryptData 和 AgentDecryptData 函数,其内部就是标准的 RC4 算法操作,用于处理 SessionKey 层的加解密。 五、 总结与完整解密思路 AdaptixC2 ( listener_beacon_http ) 的通信保密性通过两层加密实现: 第一层(固定层) :使用监听器初始化时生成的 EncryptKey 。用于加密初始心跳包和所有后续通信的 外层 。 第二层(会话层) :每个 Agent 上线时在心跳包中携带的 SessionKey 。用于加密 内层 的实际任务和结果数据。 因此,完整的解密前提是 : 获取到 C2 Server 配置中或数据库中的静态 EncryptKey 。 成功解密第一个心跳包,并从明文中提取出 SessionKey 。 一旦同时拥有这两个密钥,即可完全解密该监听器下所有 Agent 的整个通信过程。这种分析手法对于深度威胁狩猎、C2 流量监控和恶意软件逆向工程具有重要价值。