RustDuck: 双阶段僵尸网络深度剖析

概述

自 2026 年 2 月起,XLAB大网威胁感知系统监测到一种新型的、采用 Loader + Core(双阶段加载) 架构的恶意软件家族活跃于网络空间。目前该家族已衍生出多个变种,主要核心功能为执行大规模分布式拒绝服务(DDoS)攻击。并具备较强的跨平台适配与持续演化能力。

尽管该家族当前 DDoS 攻击活动中的活跃度和影响力尚不及部分主流僵尸网络,但其技术演进速度值得重点关注。研究发现,该家族正在经历从 C 语言向 Rust 语言 的全面技术转型,其对抗防御和流量加密的手段也在疯狂迭代。基于其技术栈从C转向Rust语言和早期核心Payload加密编码3个duckdns的C2域名的特点,我们将其命名为RustDuck

attack incident
攻击事件趋势

样本传播方面,该家族样本的传播链主要覆盖 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

176.65.139.204-2026-06-22 18.53.16.png


样本分析

一、 Loader 的进化与聚类分析

Loader 阶段的样本通常采用精简的三段式设计:加载代码(Loading Code)压缩数据(Compressed Core)配置信息(Config)

其经典的文件布局如下:加载代码驻留在标准 ELF 文件的开头代码段中,而核心的压缩数据与配置信息则作为 Overlay(附加数据)紧跟在文件末尾。

elf_overlay.png

通过对文件尾部的配置信息(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 算法,目前观测到两种并存的密钥生成源:

  1. 基于 UTC 时间的动态密钥: 步调与时钟同步,每 10 分钟强制更新一次,用以对抗重放攻击和长期的流量审计。
  2. 非对称密钥交换: 采用 Curve25519(Noise_IK_25519) 架构实现前向安全。

在对称加解密算法上,演进路线分裂为两条分支:

  • 分支 A: 全程采用经过魔术修改(Permutation 变换)的 Ascon128 轻量级加密算法。
  • 分支 B: 采用混合加密体制。握手阶段使用 ChaCha20-Poly1305,握手合规后切入 AES-GCM

2. 多维度反调试与环境泛滥检测

为了阻断沙箱自动分析和逆向分析师的动态调试,Core 模块内置了一套动态权重评分机制。软件运行时会遍历执行各项环境检测,当累加的风险得分超过预设阈值时,程序将自动擦除痕迹并退出。

sandbox_check.png

具体检测项与权重划分如下:

检测技术项 风险权重 检测原理与对抗逻辑
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

握手交互时序:

  1. Key Exchange: 客户端上传 32 字节的客户端临时公钥;随后接收服务器下发的 32 字节公钥。
  2. KDF 派生: 双方利用各自手上的私钥与对方公钥完成魔改的密钥交换,将共享密钥合并作为 master,公钥拼接物作为 salt,通过 HKDF-SHA256 派生出后续所需的 chacha20KeyaesGCMKey

key_derivation.png

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

handshake_verify.png


阶段 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 发送(上行)流量: 使用 clientKeyclientNonceKey 加密。
  • Server 接收(下行)指令: 使用 serverKeyserverNonceKey 解密。

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