RustDuck: 双阶段僵尸网络深度剖析
概述
自 2026 年 2 月起,XLAB大网威胁感知系统监测到一种新型的、采用 Loader + Core(双阶段加载) 架构的恶意软件家族活跃于网络空间。目前该家族已衍生出多个变种,主要核心功能为执行大规模分布式拒绝服务(DDoS)攻击。并具备较强的跨平台适配与持续演化能力。
尽管该家族当前 DDoS 攻击活动中的活跃度和影响力尚不及部分主流僵尸网络,但其技术演进速度值得重点关注。研究发现,该家族正在经历从 C 语言向 Rust 语言 的全面技术转型,其对抗防御和流量加密的手段也在疯狂迭代。基于其技术栈从C转向Rust语言和早期核心Payload加密编码3个duckdns的C2域名的特点,我们将其命名为RustDuck。
样本传播方面,该家族样本的传播链主要覆盖 IoT 设备、Web 应用及企业基础设施,攻击方式以弱口令爆破(Telnet/SSH)与多类 RCE 漏洞利用为主,涉及 Android ADB、TVT API、Ruijie、TP-Link、ZTE、 等设备漏洞,以及 ThinkPHP、Jenkins、YARN 等 Web/组件漏洞,并结合部分历史 CVE (CVE-2025-29635、CVE-2017-17215、CVE-2018-8007、CVE-2024-1781) 扩大攻击面。整体呈现“弱口令 + IoT 漏洞 + Web RCE”的组合型传播特征,可覆盖路由器、摄像头、Android 终端及服务器环境,实现大规模自动化入侵与载荷投递。目前监测到20多个IP参与传播RustDuck僵尸网络,其中最活跃的植入样本源IP为:176.65.139[.]204

样本分析
一、 Loader 的进化与聚类分析
Loader 阶段的样本通常采用精简的三段式设计:加载代码(Loading Code)、压缩数据(Compressed Core) 和 配置信息(Config)。
其经典的文件布局如下:加载代码驻留在标准 ELF 文件的开头代码段中,而核心的压缩数据与配置信息则作为 Overlay(附加数据)紧跟在文件末尾。

通过对文件尾部的配置信息(Config)进行结构化逆向,我们可以将该家族的 Loader 明确聚类为以下四个演进阶段:
| 阶段 | SHA1 (前8位) | 配置大小 | 解密算法 | 解压算法 | Magic 校验特点 |
|---|---|---|---|---|---|
| loader变种1 | 8315f650 |
16 字节 | LCG + XOR | LZ4 | 动态校验(ROL4 + XOR) |
| loader变种2 | 6aa791c7 |
33 字节 | Xoshiro128 + XOR | BLZ | 引入动态常量 |
| loader变种3 | 4d11bd49 |
48 字节 | 标准 XOR | LZ4 | 固定明文 "ASHPCK\x01\x00" |
| loader变种4 | d39a3ee9 |
32 字节 | ChaCha20 | LZ4 | 固定明文 "iEMPK\x02\x00\x00" |
1. loader变种1
SHA1:
8315f650e9e4f67c00277b076ab304eed23db47d
-
配置大小: 16 字节(均分为 4 个字段,每字段 4 字节)
-
内存布局:
+--------------+-------------------+---------------------+--------------+ | Key (4B) | Compress_Size(4B) | Decompress_Size(4B) | Magic (4B) | +--------------+-------------------+---------------------+--------------+ -
Magic 校验算法: 引入循环左移(ROL)与异或组合校验:
comperss_size ^ decompress_size ^ ROL4(key, 13) ^ 0x5A3C9E7F == magic
- 加解密与解压: 采用线性同余生成器(LCG)产生伪随机数序列进行 XOR 解密,随后使用 LZ4 算法解压。
2. loader变种2
SHA1:
6aa791c76b3107fca9d57b7ecea8f46d97d83738
- 配置大小: 33 字节
- 内存布局:
+---------------+-------------------+---------------------+---------------+---------------+ | Key (16B) | Compress_Size(4B) | Decompress_Size(4B) | Magic (8B) | Noise_Size(4B)| +---------------+-------------------+---------------------+---------------+---------------+ - 加解密与解压: 升级为 Xoshiro128 + XOR 解密,解压算法更换为 BLZ。
- 对抗特点: 该变种引入了多个硬编码常量来混淆解密和 Magic 验证过程。由于不同样本之间的常量是动态变化的,导致安全人员极难进行静态批量解密。
3. loader变种3
SHA1:
4d11bd496da82d15b3ed13050f414e44f5a892d4
- 配置大小: 48 字节
- 内存布局:
+-------------------+---------------------+-------------------------------+---------------+ | Compress_Size(4B) | Decompress_Size(4B) | Key (32B) | Magic (8B) | +-------------------+---------------------+-------------------------------+---------------+ - Magic 校验: 固定为明文字符串
"ASHPCK\x01\x00"。 - 加解密与解压: 回归标准 XOR 解密与 LZ4 解压,结构走向标准化。
4. loader变种4
SHA1:
d39a3ee96be6b8f5238cb1253514ab55c88f714c
-
配置大小: 32 字节
-
内存布局:
+-------------------+---------------------+-------------------------------+---------------+ | Compress_Size(4B) | Decompress_Size(4B) | Key (16B) | Magic (8B) | +-------------------+---------------------+-------------------------------+---------------+ -
Magic 校验: 固定为明文字符串
"iEMPK\x02\x00\x00"。 -
加解密与解压: 引入高强度的 ChaCha20 流加密算法,解压依然采用 LZ4。
二、 Core 阶段的质变进化
随着编程语言向 Rust 切换,该家族的 Core(核心模块)在密钥派生、反分析以及通信协议上展现出了极高的工程复杂度。
1. 密钥生成与加解密算法
在密钥派生方面,新变种统一引入了 HKDF-SHA256 算法,目前观测到两种并存的密钥生成源:
- 基于 UTC 时间的动态密钥: 步调与时钟同步,每 10 分钟强制更新一次,用以对抗重放攻击和长期的流量审计。
- 非对称密钥交换: 采用 Curve25519(Noise_IK_25519) 架构实现前向安全。
在对称加解密算法上,演进路线分裂为两条分支:
- 分支 A: 全程采用经过魔术修改(Permutation 变换)的 Ascon128 轻量级加密算法。
- 分支 B: 采用混合加密体制。握手阶段使用 ChaCha20-Poly1305,握手合规后切入 AES-GCM。
2. 多维度反调试与环境泛滥检测
为了阻断沙箱自动分析和逆向分析师的动态调试,Core 模块内置了一套动态权重评分机制。软件运行时会遍历执行各项环境检测,当累加的风险得分超过预设阈值时,程序将自动擦除痕迹并退出。

具体检测项与权重划分如下:
| 检测技术项 | 风险权重 | 检测原理与对抗逻辑 |
|---|---|---|
| Analysis Tools Check | 100 | 检索进程列表,查杀抓包工具(wireshark, tcpdump 等)与逆向分析工具(gdb, ida, frida, x64dbg 等)。 |
| Debug Check | 100 | 读取 /proc/self/status,检测 TracerPid 是否不为 0。 |
| Lib Check | 100 | 解析 /proc/self/maps,检测是否存在 frida, asan, ubsan, libdl-inject 等注入或调测库。 |
| SHA256 Checksum | 100 | 校验文件末尾附带的 SHA256 签名,若文件被逆向人员修改或下断点(修改了 Opcode),则拒绝运行。 |
| Honeypot Check | 50 | 检查系统关键路径下是否存在蜜罐特征文件,如 Cowrie (/etc/cowrie/cowrie.cfg) 或 Dionaea。 |
| Env Check | 40 | 检查环境变量(environ)中是否包含 sandbox, malware, virus, sample 等敏感字眼。 |
| Network Blackhole | 35 | 异步连接保留测试 IP 192.0.2.1。若能在 0.5s 内连通,说明处于假冒 Internet 的欺骗性沙箱环境中。 |
| Time Travel Check | 30 | 双时钟源交叉时间差校验。通过 usleep 前后对比系统时间与单调时间,防范沙箱时间加速或逆向断点卡顿。 |
| Hardware Check | 25 | 读取 DMI 信息及 SCSI 设备接口,检索是否包含 virtualbox, vbox, bochs 等虚拟化硬件关键字。 |
| VM MAC Check | 20 | 遍历网卡 MAC 地址,比对是否属于 VBox (08:00:27)、VMware 或 Parallels 的特定 OUI 厂商前缀。 |
| PID Density Check | 10 | 检测当前系统总进程数是否小于 5,过滤极其纯净的极简模拟器环境。 |
关键反调试代码实现参考:
// 1. Time Travel Check:双时钟源交叉校验
int check_timing_safetly() {
struct timeval tv1, tv2;
struct timespec ts1, ts2;
gettimeofday(&tv1, NULL);
clock_gettime(CLOCK_MONOTONIC, &ts1);
usleep(500000); // 故意挂起 0.5 秒
gettimeofday(&tv2, NULL);
clock_gettime(CLOCK_MONOTONIC, &ts2);
long v2 = (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec) / 1000;
long v3 = (ts2.tv_sec - ts1.tv_sec) * 1000 + (ts2.tv_nsec - ts1.tv_nsec) / 1000000;
// 必须实际睡眠超过 300ms,且两个时钟源的系统误差在 1000ms 以内
if (v2 > 299 && v3 > 299 && abs(v3 - v2) <= 1000) {
return 1; // 环境正常
}
return 0; // 时间异常:可能被沙箱快进,或被逆向断点阻断
}
// 2. Network Blackhole Check:网络黑洞/沙箱盲连检测
int check_network_blackhole() {
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) return 0;
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // 设置非阻塞
struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(80) };
addr.sin_addr.s_addr = inet_addr("192.0.2.1"); // RFC 5737 测试保留IP(正常网络绝对不可达)
connect(fd, (struct sockaddr *)&addr, sizeof(addr));
fd_set writeset;
FD_ZERO(&writeset);
FD_SET(fd, &writeset);
struct timeval tv = { .tv_sec = 0, .tv_usec = 500000 }; // 异步等待 0.5 秒
int res = select(fd + 1, NULL, &writeset, NULL, &tv);
close(fd);
// 如果超时不可写,说明该 IP 符合预期的“黑洞”状态(通过检测)
if (res <= 0 || !FD_ISSET(fd, &writeset)) {
return 1;
}
return 0; // 居然意外连通,说明身处全流量接管的伪造沙箱中
}
3. 高强度通信协议与流量对抗
新变种的网络通信协议深度参考了 Noise 协议框架的 IK 模式。依靠客户端硬编码的服务器静态公钥与运行时生成的临时公钥进行 ECDH,混合派生出会话密钥。另外,协议在全阶段引入了全局 MsgID,用于消息序列验证并参与新密钥的滚动生成。这种设计切断了在网络侧通过明文密钥解密流量的可能性。
整个通信生命周期严格划分为两个阶段:
阶段 A:握手/验证阶段
- 消息封装格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| plen (2B) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
+ nonce (12B) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
// cipher (Variable Length) //
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ tag (16B) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 传输加密: ChaCha20
握手交互时序:
- Key Exchange: 客户端上传 32 字节的客户端临时公钥;随后接收服务器下发的 32 字节公钥。
- KDF 派生: 双方利用各自手上的私钥与对方公钥完成魔改的密钥交换,将共享密钥合并作为
master,公钥拼接物作为salt,通过 HKDF-SHA256 派生出后续所需的chacha20Key与aesGCMKey:

- 四步合规验证: 基于
chacha20Key+HMAC-SHA256建立严格的身份确认:
login (0xa0): 客户端生成 16 字节随机密文,并上报当前架构、CPU 核心数、内存大小。verify (0xa1): 服务器返回随机消息,并附带针对 login 阶段的login_hmac。confirm (0xa2): 客户端校验成功后,向服务端发送verify_hmac及本机的唯一botid(64字节十六进制字符串)。ack (0xa3): 服务端发送确认包,正式宣告握手阶段结束。

阶段 B:指令循环(C2 Command Loop)
握手成功后,通信立即切换至高强度的指令循环阶段。
- 消息封装格式: 头部增加了 3 字节的仿 SSL 伪装魔术字。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| magic[0] (0x17) | magic[1] (0x03) | magic[2] (0x03) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| plen (2B) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
+ nonce (12B) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
// cipher (Variable Length) //
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ tag (16B) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 传输加密: AES-GCM 体制。
为了最大化提升对抗中间人攻击(MITM)的能力,该阶段在进行数据加密和解密时,采用了上下行分离的独立密钥体制。先前派生的 88 字节 aesGCMKey 被精确切割为四个部分:
- Client 发送(上行)流量: 使用
clientKey与clientNonceKey加密。 - Server 接收(下行)指令: 使用
serverKey与serverNonceKey解密。
C2 指令集(msgType)定义:
| msgType (Hex/Dec) | 指令名称 | 行为描述 |
|---|---|---|
| 3 / 8 | Attack | 启动 DDoS 攻击任务(支持各类混合泛洪攻击) |
| 9 | Stop Attack | 紧急停止当前的 DDoS 攻击 |
| 10 | Update | 远程拉取新变种样本并执行热更新 |
| 11 | Get Status | 上报当前的受控端存活状态与资源占用 |
| 14 | Update C2 | 动态下发并切换新的基础设施 C2 域名/IP |
Loader SHA1
8315f650e9e4f67c00277b076ab304eed23db47d
6aa791c76b3107fca9d57b7ecea8f46d97d83738
4d11bd496da82d15b3ed13050f414e44f5a892d4
d39a3ee96be6b8f5238cb1253514ab55c88f714c
C2 Domain
gayporn.twilightparadox[.com
bigniggadick.ignorelist[.com
ilovefemboy.mooo[.com
igmc.duckdns.org
qewqewqewqtq.duckdns[.org
qewqewqewqtqthree.duckdns[.org
qewqewqewqtqtwo.duckdns[.org
disciplinenahidwin[.st
criminalcloudflare[.online
dhdsjsdjxc.duckdns[.org
fcfrfxrfrsfs5f.duckdns[.org