界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
效率与协作 · SKILL.md

analyzing-command-and-control-communication

analyzing-command-and-control-communication

【效率与协作】分析恶意软件命令与控制(C2)通信协议,以了解 beacon 模式、命令结构、数据编码和基础设施。 涵盖 HTTP、HTTPS、DNS 和自定义协议 C2 分析,用于检测规则开发和威胁情报。 适用于 C2 分析、beacon 检测、C2 协议逆向工程或命令与控制基础设施绘图相关请求。

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: analyzing-command-and-control-communication description: > 分析恶意软件命令与控制(C2)通信协议,以了解 beacon 模式、命令结构、数据编码和基础设施。 涵盖 HTTP、HTTPS、DNS 和自定义协议 C2 分析,用于检测规则开发和威胁情报。 适用于 C2 分析、beacon 检测、C2 协议逆向工程或命令与控制基础设施绘图相关请求。 domain: cybersecurity subdomain: malware-analysis tags: [malware, C2, command-and-control, beacon, protocol-analysis] version: 1.0.0 author: mahipal license: Apache-2.0

分析命令与控制通信

适用场景

  • 对恶意软件样本的逆向工程揭示了需要协议分析的网络通信
  • 为特定 C2 框架(Cobalt Strike、Metasploit、Sliver)构建网络级检测签名
  • 绘制 C2 基础设施图,包括主服务器、备用域名和投弃站
  • 分析加密或编码的 C2 流量以了解命令集和数据格式
  • 基于 C2 基础设施模式和工具对恶意软件进行威胁行为者溯源归因

不适用于一般网络异常检测;本技能专门用于从恶意软件分析中了解已知或疑似 C2 协议。

前置条件

  • 恶意软件网络流量的 PCAP 捕获(来自沙箱、网络分流或全包捕获)
  • Wireshark/tshark 用于数据包级分析
  • 逆向工程工具(Ghidra、dnSpy)用于了解恶意软件二进制文件中的 C2 代码
  • Python 3.8+,安装 scapy、dpkt 和 requests 用于协议分析和重放
  • 威胁情报数据库用于 C2 基础设施关联(VirusTotal、Shodan、Censys)
  • JA3/JA3S 指纹数据库用于基于 TLS 的 C2 识别

工作流程

步骤 1:识别 C2 通道

确定用于 C2 通信的协议和传输方式:

C2 通信通道:
━━━━━━━━━━━━━━━━━━━━━━━━━
HTTP/HTTPS:    最常见;使用标准 Web 流量进行混入
                指标:定期 POST/GET 请求、特定 URI 模式、自定义请求头

DNS:           通过 DNS 查询和响应进行数据隧道传输
                指标:大量 TXT 查询、长子域名、高熵值

自定义 TCP/UDP:使用非标准端口的私有二进制协议
                指标:高端口上的非 HTTP 流量、未知协议

ICMP:          编码在 ICMP 回显/回复载荷中的数据
                指标:具有大型或非标准载荷的 ICMP 数据包

WebSocket:     用于实时 C2 的持久双向连接
                指标:WebSocket 升级后跟随二进制帧

云服务:        使用合法 API(Telegram、Discord、Slack、GitHub)
                指标:非预期进程向云服务进行 API 调用

电子邮件:      使用 SMTP/IMAP 进行 C2 命令和数据外泄
                指标:非电子邮件进程的自动化邮件操作

步骤 2:分析 Beacon 模式

对周期性通信模式进行特征分析:

from scapy.all import rdpcap, IP, TCP
from collections import defaultdict
import statistics
import json

packets = rdpcap("c2_traffic.pcap")

# 按目标分组 TCP SYN 数据包
connections = defaultdict(list)
for pkt in packets:
    if IP in pkt and TCP in pkt and (pkt[TCP].flags & 0x02):
        key = f"{pkt[IP].dst}:{pkt[TCP].dport}"
        connections[key].append(float(pkt.time))

# 分析每个目标的 beacon 行为
for dst, times in sorted(connections.items()):
    if len(times) < 3:
        continue

    intervals = [times[i+1] - times[i] for i in range(len(times)-1)]
    avg_interval = statistics.mean(intervals)
    stdev = statistics.stdev(intervals) if len(intervals) > 1 else 0
    jitter_pct = (stdev / avg_interval * 100) if avg_interval > 0 else 0
    duration = times[-1] - times[0]

    beacon_data = {
        "destination": dst,
        "connections": len(times),
        "duration_seconds": round(duration, 1),
        "avg_interval_seconds": round(avg_interval, 1),
        "stdev_seconds": round(stdev, 1),
        "jitter_percent": round(jitter_pct, 1),
        "is_beacon": 5 < avg_interval < 7200 and jitter_pct < 25,
    }

    if beacon_data["is_beacon"]:
        print(f"[!] 检测到 BEACON:{dst}")
        print(f"    间隔:{avg_interval:.0f}s +/- {stdev:.0f}s({jitter_pct:.0f}% 抖动)")
        print(f"    会话:{len(times)} 次,持续 {duration:.0f}s")

步骤 3:解码 C2 协议结构

从捕获的流量中逆向工程消息格式:

# 基于 HTTP 的 C2 协议分析
import dpkt
import base64

with open("c2_traffic.pcap", "rb") as f:
    pcap = dpkt.pcap.Reader(f)

for ts, buf in pcap:
    eth = dpkt.ethernet.Ethernet(buf)
    if not isinstance(eth.data, dpkt.ip.IP):
        continue
    ip = eth.data
    if not isinstance(ip.data, dpkt.tcp.TCP):
        continue
    tcp = ip.data

    if tcp.dport == 80 or tcp.dport == 443:
        if len(tcp.data) > 0:
            try:
                http = dpkt.http.Request(tcp.data)
                print(f"\n--- C2 请求 ---")
                print(f"方法:{http.method}")
                print(f"URI:{http.uri}")
                print(f"请求头:{dict(http.headers)}")
                if http.body:
                    print(f"正文({len(http.body)} 字节):")
                    # 尝试 Base64 解码
                    try:
                        decoded = base64.b64decode(http.body)
                        print(f"  解码后:{decoded[:200]}")
                    except:
                        print(f"  原始:{http.body[:200]}")
            except:
                pass

步骤 4:识别 C2 框架

将观察到的模式与已知 C2 框架进行匹配:

已知 C2 框架签名:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Cobalt Strike:
  - 默认 URI:/pixel、/submit.php、/___utm.gif、/ca、/dpixel
  - Malleable C2 配置文件可自定义所有流量特征
  - JA3:随配置文件变化
  - Beacon 配置中的水印(每个许可证唯一)
  - 配置提取:使用 CobaltStrikeParser 或 1768.py

Metasploit/Meterpreter:
  - 默认分段 URI 模式:随机 4 字符校验和
  - 反向 HTTP(S) 处理器模式
  - Meterpreter TLV(类型-长度-值)协议结构

Sliver:
  - mTLS、HTTP、DNS、WireGuard 传输选项
  - Protobuf 编码消息
  - 通信中的唯一植入物 ID

Covenant:
  - 基于 .NET 的 C2 框架
  - HTTP 加可自定义配置文件
  - 基于任务的命令执行

PoshC2:
  - 基于 PowerShell/C#
  - HTTP 加加密载荷
  - 基于 Cookie 的会话管理
# 从 PCAP 或样本中提取 Cobalt Strike beacon 配置
python3 << 'PYEOF'
# 使用 CobaltStrikeParser(pip install cobalt-strike-parser)
from cobalt_strike_parser import BeaconConfig

try:
    config = BeaconConfig.from_file("suspect.exe")
    print("Cobalt Strike Beacon 配置:")
    for key, value in config.items():
        print(f"  {key}: {value}")
except Exception as e:
    print(f"不是 Cobalt Strike beacon 或解析错误:{e}")
PYEOF

步骤 5:绘制 C2 基础设施图

记录完整的 C2 基础设施和故障转移机制:

# 基础设施绘图
import requests
import json

c2_indicators = {
    "primary_c2": "185.220.101.42",
    "domains": ["update.malicious.com", "backup.evil.net"],
    "ports": [443, 8443],
    "failover_dns": ["ns1.malicious-dns.com"],
}

# 通过 Shodan 丰富信息
def shodan_lookup(ip, api_key):
    resp = requests.get(f"https://api.shodan.io/shodan/host/{ip}?key={api_key}")
    if resp.status_code == 200:
        data = resp.json()
        return {
            "ip": ip,
            "ports": data.get("ports", []),
            "os": data.get("os"),
            "org": data.get("org"),
            "asn": data.get("asn"),
            "country": data.get("country_code"),
            "hostnames": data.get("hostnames", []),
            "last_update": data.get("last_update"),
        }
    return None

# 通过被动 DNS 丰富信息
def pdns_lookup(domain):
    # 使用 VirusTotal 被动 DNS
    resp = requests.get(
        f"https://www.virustotal.com/api/v3/domains/{domain}/resolutions",
        headers={"x-apikey": VT_API_KEY}
    )
    if resp.status_code == 200:
        data = resp.json()
        resolutions = []
        for r in data.get("data", []):
            resolutions.append({
                "ip": r["attributes"]["ip_address"],
                "date": r["attributes"]["date"],
            })
        return resolutions
    return []

步骤 6:创建网络检测签名

根据分析的 C2 特征构建检测规则:

# 针对分析 C2 的 Suricata 规则
cat << 'EOF' > c2_detection.rules
# HTTP beacon 模式
alert http $HOME_NET any -> $EXTERNAL_NET any (
    msg:"MALWARE MalwareX C2 HTTP Beacon";
    flow:established,to_server;
    http.method; content:"POST";
    http.uri; content:"/gate.php"; startswith;
    http.header; content:"User-Agent: Mozilla/5.0 (compatible; MSIE 10.0)";
    threshold:type threshold, track by_src, count 5, seconds 600;
    sid:9000010; rev:1;
)

# JA3 指纹匹配
alert tls $HOME_NET any -> $EXTERNAL_NET any (
    msg:"MALWARE MalwareX TLS JA3 指纹";
    ja3.hash; content:"a0e9f5d64349fb13191bc781f81f42e1";
    sid:9000011; rev:1;
)

# DNS beacon 检测(高熵子域名)
alert dns $HOME_NET any -> any any (
    msg:"MALWARE 疑似 DNS C2 隧道";
    dns.query; pcre:"/^[a-z0-9]{20,}\./";
    threshold:type threshold, track by_src, count 10, seconds 60;
    sid:9000012; rev:1;
)

# 基于证书的检测
alert tls $HOME_NET any -> $EXTERNAL_NET any (
    msg:"MALWARE MalwareX 自签名 C2 证书";
    tls.cert_subject; content:"CN=update.malicious.com";
    sid:9000013; rev:1;
)
EOF

核心概念

术语定义
Beaconing(信标)恶意软件定期向 C2 服务器发送的签到通信,通常带有抖动以避免模式检测
Jitter(抖动)应用于 beacon 间隔的随机化(如 60s +/- 15%),使时序模式不可预测、更难检测
Malleable C2Cobalt Strike 功能,允许操作者自定义 C2 流量的所有方面(URI、请求头、编码),以模仿合法服务
Dead Drop(投弃站)中间位置(粘贴网站、云存储、社交媒体),C2 命令发布于此供恶意软件检索
域前置(Domain Fronting)在 TLS SNI 中使用受信任的 CDN 域,同时路由到不同后端,使 C2 流量看似流向合法服务
Fast Flux(快速通量)快速更改 C2 域的 DNS 记录,分散到许多 IP,以抵抗清除工作
C2 框架提供 C2 服务器、植入物生成器和操作者界面的软件工具包(Cobalt Strike、Metasploit、Sliver、Covenant)

工具与系统

  • Wireshark:数据包分析器,用于在数据包级别进行详细的 C2 协议分析
  • RITA(实时智能威胁分析):开源工具,分析 Zeek 日志用于 beacon 检测和 DNS 隧道检测
  • CobaltStrikeParser:从样本和内存转储中提取 Cobalt Strike beacon 配置的工具
  • JA3/JA3S:TLS 指纹方法,通过 TLS 实现特征识别 C2 框架
  • Shodan/Censys:互联网扫描平台,用于绘制 C2 基础设施图和识别相关服务器

常见场景

场景:逆向工程自定义 C2 协议

场景背景:一个恶意软件样本通过 TCP 8443 端口使用未知二进制协议与 C2 服务器通信。需要解码该协议以了解命令集并构建检测签名。

方法:

  1. 过滤 PCAP 中的 TCP 8443 对话并提取 TCP 流
  2. 分析前几次交换以识别握手/认证机制
  3. 映射消息结构(长度前缀、类型字段、载荷编码)
  4. 与 Ghidra 对恶意软件中发送/接收函数的反汇编进行交叉参考
  5. 识别命令调度器并记录每个命令代码的功能
  6. 用 Python 构建协议解码器用于持续流量分析
  7. 创建匹配协议握手或静态头字节的 Suricata 规则

常见陷阱:

  • 假设协议是静态的;某些 C2 框架在握手期间协商加密
  • 未捕获足够的流量以查看所有命令类型(某些命令很少见)
  • 遗漏备用 C2 通道(DNS、ICMP),这些通道在主通道失败时激活
  • 将加密载荷数据与协议帧结构混淆

输出格式

C2 通信分析报告
===================================
样本:           malware.exe(SHA-256:e3b0c44...)
C2 框架:        Cobalt Strike 4.9

BEACON 配置
C2 服务器:      hxxps://185.220.101[.]42/updates
Beacon 类型:    HTTPS(反向)
休眠:           60 秒
抖动:           15%
User-Agent:     Mozilla/5.0 (Windows NT 10.0; Win64; x64)
URI(GET):     /dpixel
URI(POST):    /submit.php
水印:           1234567890

协议分析
传输:           HTTPS(TLS 1.2)
JA3 哈希:       a0e9f5d64349fb13191bc781f81f42e1
证书:           CN=Microsoft Update(自签名)
编码:           Base64 加 XOR 密钥 0x69
命令格式:       [4B 长度][4B 命令 ID][载荷]

命令集
0x01 - Sleep          更改 beacon 间隔
0x02 - Shell          执行 cmd.exe 命令
0x03 - Download       从 C2 传输文件
0x04 - Upload         外泄文件到 C2
0x05 - Inject         进程注入
0x06 - Keylog         启动键盘记录
0x07 - Screenshot     截屏

基础设施
主要:           185.220.101[.]42(AS12345,托管商,荷兰)
备用:           91.215.85[.]17(AS67890,VPS 提供商,俄罗斯)
DNS:            update.malicious[.]com -> 185.220.101[.]42
注册商:         NameCheap
注册日期:       2025-09-01

检测签名
SID 9000010:    HTTP beacon 模式
SID 9000011:    JA3 TLS 指纹
SID 9000013:    C2 证书匹配
我的收藏