malware · cryptomining · rootkit · linux · kernel · monero · privilege-escalation · cve-2026-31431 · container-escape

Rootpacket:一个藏身内核的 Linux 挖矿木马工具包

Kinryū Labs 分析了 Rootpacket,一个 Linux 挖矿木马工具包:它携带一个内核 rootkit 来伪造 CPU 与内存占用,通过 CVE-2026-31431(一个 AF_ALG 页缓存缺陷,还能从容器逃逸到主机)提权到 root,伪装成 Intel 驱动,并关闭竞争对手矿工赖以进入的那些暴露服务。

作者 Davis Zheng·

CVE
CVE-2026-31431
CVSS
7.8 (CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

TLP:CLEAR。已批准公开发布。这是纯静态分析:未执行任何样本,所有结论均来自字符串提取、反汇编与源码审阅。攻击者的门罗币钱包、矿池与基础设施作为防御指标予以公开。

摘要

  • ~45%top 显示的占用率,而它实际跑在接近 100%
  • 3种持久化机制
  • 7.8CVSS,CVE-2026-31431(AF_ALG 页缓存 LPE)
  • 主机从一个无特权容器拿到 root

Rootpacket 是一个面向 Linux 的多组件挖矿木马工具包。它打包了一个用于隐身的内核级 rootkit、一个针对 Linux AF_ALG 加密接口中 CVE-2026-31431 的提权漏洞利用、一个被改名为 xrandom 的 UPX 加壳 XMRig 6.26.0 门罗币矿工,以及一个竞争对手清除脚本。代码大量使用土耳其语(变量名、注释、状态字符串),指向一名讲土耳其语的操作者。

该工具包以两种模式之一运行。在 root 模式下,它加载一个伪装成 intel_uncore_freq_aux 的可加载内核模块(LKM)rootkit,通过 DKMS 安装以便在内核升级后依然存活,注册一个 systemd 服务,并把机器上的对手清理干净。当拿不到 root 时,它回退到一种用户态模式,通过 crontab 持久化,并以守护进程方式运行矿工。矿工通过 stratum+ssl 连接到 pool.supportxmr.com:443,用 RandomX 挖门罗币。

值得细看的组件是 rootkit。当矿工把处理器顶在接近 100% 时,rootkit 改写 /proc/stat,让 tophtop 报告一个平静的 40 到 50 percent,并用 jiffies 让这个数字上下波动,使负载看起来真实,而不是钉死在一个常数上。它对 /proc/meminfo 做同样的事,还会过滤目录列表以隐藏自己的进程和文件。

关键判断

  • 目标是挖矿(高置信度)。工具包携带 XMRig 6.26.0、一个硬编码的门罗币钱包,以及一份 pool.supportxmr.com 矿池配置,并关闭了 XMRig 的开发者捐赠,使所有收益都归操作者。
  • 提权利用的是 CVE-2026-31431(“Copy Fail”),Linux AF_ALG algif_aead 路径中一处确定性的页缓存写入(CVSS 7.8,2026 年 4 月披露)。由于页缓存是全主机共享的,同一处写入会从容器逃逸出去、拿到主机的 root,因此一个被感染的容器就等于一台被攻陷的主机(高置信度)。
  • 操作者的水平远高于典型的「丢下去就挖」团伙(高置信度)。带 ftrace 钩子的定制 LKM rootkit、会为新内核自动重建的 DKMS 持久化、一个可用的 CVE-2026-31431 页缓存利用,以及分层的 systemd/DKMS/cron 持久化,是大多数挖矿木马从未达到的工程水平。
  • 操作者很可能讲土耳其语(中等置信度)。土耳其语的变量名、注释以及诸如 ROOT ele gecirildi! 的状态信息贯穿整个工具包。
  • Rootpacket 的设计是独占一台主机并把它守住。它的 killservice.sh 移除竞争对手矿工,然后关闭挖矿木马用于初始访问的那些对外暴露的服务,包括 2375/2376 上的 Docker API——正是我们在 RedTail 报告 中记录过的那个向量。这些团伙都在争夺同一批配置错误的机器。

工具包架构

Rootpacket 是一个模块化的投放器。各个部件:

setup.sh         入口点。检查权限级别,选择部署模式。
getroot          提权。利用 CVE-2026-31431(AF_ALG)实现本地 root。
xrandom          UPX 加壳的 XMRig 6.26.0,已改名以躲避基于名称的检测。
kernel/
  stealth.c      LKM rootkit,通过 DKMS 编译,伪装成 Intel 驱动。
  install.sh     DKMS 持久化引擎。
killservice.sh   竞争对手清除与「加固」。
rootpacket.tar.gz  整个工具包的内层副本,打包以供再分发。

Root 模式。 若尚非 root,setup.sh 会运行 getroot,把 xrandom 复制到 /opt/kernel-kd/,创建一个 systemd 服务,运行 kernel/install.sh 通过 DKMS 编译并加载 rootkit,运行 killservice.sh 清除竞争对手,然后以持久化服务方式启动矿工。

用户态回退。 当 root 触不可及时,setup.shxrandom 复制到 ~/.xrandom/,写入一个带 PID 锁的启动器,安装一个在重启时及每分钟触发的 crontab 条目,并用 setsid 启动矿工,使其在父 shell 退出后依然存活。

特性Root 模式用户态模式
矿工位置/opt/kernel-kd/xrandom~/.xrandom/xrandom
持久化systemd(kernel-kd.servicecrontab(@reboot + */1 * * * *
Rootkit有(通过 DKMS 的 LKM)
竞争对手清除有(killservice.sh
运行身份root(systemd)当前用户(setsid 守护进程)

getroot:CVE-2026-31431,借页缓存破坏拿到 root

getroot 是一个静态链接、未 strip 的 ELF64 x86-64 二进制,由 getroot.c 构建。它利用 CVE-2026-31431(“Copy Fail”),Linux 内核 AF_ALG algif_aead 接口中的一个逻辑缺陷,于 2026 年 4 月 29 日披露(CVSS 7.8)。该漏洞给出一个确定的、攻击者可控的 4 字节写入到内核页缓存,而 getroot 用它在内存中打补丁一个 SUID 二进制,然后以 root 身份走出来。

属性
类型ELF 64-bit LSB executable,x86-64,静态链接,未 strip
CVECVE-2026-31431 “Copy Fail”(CVSS 7.8,AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
子系统AF_ALG algif_aead,AEAD 模板 authencesn(hmac(sha256),cbc(aes))
受影响Linux 4.14 到 6.19.11(缺陷于 2017 年随提交 72548b093ee3 引入);已在 6.18.22、6.19.12、7.0+ 修复
目标/usr/bin/su——其内存中的 .text 在页缓存里被打补丁
可靠性确定性,无竞态条件
用法 / 兜底./getroot <cmd> [args...];若利用未命中,它仍会以当前权限运行该命令

机制。 2017 年 AEAD 代码中的一处就地优化,让被 splice 的页缓存页同时留在源 scatterlist 和目标 scatterlist 中。当 authencesn 模板在攻击者选定的偏移 assoclen + cryptlen 处写入它那 4 字节的 ESN 临时值时,该写入会落在一个用户可读文件的页缓存页内。随后 HMAC 校验失败、recvmsg() 返回 EBADMSG,但内核从不回滚这次写入。getroot 解析 /usr/bin/su 的 ELF 头以计算其入口点的文件偏移,然后循环执行 splicesendmsg(在 AAD 中携带要写入的 4 字节)→ recvmsg,每 4 字节的 shellcode 一次,在页缓存里给 /usr/bin/su 打补丁。接着它 execve /usr/bin/su:内核加载那个已被破坏的页,shellcode 以 SUID-root 运行,getroot 在运行操作者的命令之前确认 getuid() == 0(并打印土耳其语 [+] ROOT ele gecirildi!,意为「已拿到 root」)。磁盘上的文件从未被触碰,因此文件完整性监控什么也看不到。

逃逸到主机。 Linux 页缓存是全主机共享的;容器并没有自己的页缓存。一个无特权容器内的进程,若 splice 主机的 /usr/bin/su,破坏的是主机那份缓存副本,于是 execve 产出的是主机上的 root,而不仅是容器内的。因此一个被感染的容器就等于一台被攻陷的主机,而 setup.sh 接下来还会把内核 rootkit 加载进主机。停止并删除容器是不够的;主机必须重建。

我们在一台隔离的虚拟机(Kali,内核 6.6.15)上运行过一次 getroot。它执行了完整的 AF_ALG 序列,但在该构建上未拿到 root,回退为以非特权方式运行命令——这与一个针对特定内核布局的利用相吻合。我们没有运行矿工。

xrandom:矿工

xrandom 是开源门罗币矿工 XMRig 6.26.0 的一个改名、UPX 加壳副本。

属性
真实身份XMRig 6.26.0
加壳UPX 4.2.4(加壳 2.8 MB,解包 10.1 MB)
算法RandomX(rx/0
矿池通过 stratum+sslpool.supportxmr.com:443
钱包46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ
捐赠等级0(已禁用 XMRig 开发者捐赠)

通过 443 端口 + TLS 挖矿,让流量乍看之下能混入普通的 HTTPS,不过 stratum 握手对任何细看的人来说有着不同的 TLS 指纹。

stealth.c:内核 rootkit

这是整个工具包里最成熟的部分。它是一个 LKM rootkit,使用 ftrace 函数钩子来拦截内核函数、抹除恶意软件的痕迹,并自始至终伪装成一个 Intel 硬件驱动。

属性
模块名intel_uncore_freq_aux
伪造元数据MODULE_AUTHOR("Intel Corporation")MODULE_DESCRIPTION("Intel Uncore Frequency Control Driver")MODULE_VERSION("1.2.0")
钩子方式通过 kallsyms_lookup_name 的 ftrace(在 5.7 及以后的内核上通过一个 kprobe 解析)
控制位于 /sys/kernel/intel_uncore_freq/ 的 sysfs(enabledcpu_locpu_himem_lomem_hihide_tag

它钩了什么,以及为什么:

  • CPU 掩盖。 它钩 show_stat 来改写 /proc/stat,在可配置的上下界之间(默认 40 到 50 percent)伪造利用率,并用 jiffies 让数字波动,使其像真实负载一样移动,而不是平躺不动。
  • 内存掩盖。 它钩 meminfo_proc_show 来改写 /proc/meminfo,伪造 MemFreeMemAvailableBuffersCachedActiveInactive
  • 进程隐藏。 它钩 iterate_dir 来过滤 /proc 列表,隐藏名字匹配一组硬编码集合的 PID:stealthmasscansshrunsransomxcpumaskxrandomcpm_kcpmmask_helperftrhookkintel_aux。操作者可在运行时通过 /sys/kernel/intel_uncore_freq/hide_tag 添加更多名字。
  • 文件隐藏。 它隐藏匹配 stealthcpumaskkintel_auxintel_uncore_freq_aux 以及 sysfs 目录本身的路径。
  • 自我隐藏。 加载时它用 list_del_init 把自己从 /proc/modules/sys/module/ 中移除,删除自己的 sysfs kobject,并用 try_module_get 增加自身引用计数,使 rmmod 无法卸载它。

那份隐藏清单本身也是一个线索:除了矿工,它还隐藏了 masscansshrunsransomx,所以操作者很可能在运行一个扫描器,并且手里可能不止一个矿工。

实际效果是:一名盯着 top 的管理员,看到的是一台繁忙但正常的机器,找不到流氓进程,也看不到那个正在撒谎的内核模块。破绽是物理的、带外的:机器发烫、风扇转起来、功耗攀升,而这些都不是 rootkit 能伪造的。

持久化:三种机制,按模式区分

Rootpacket 的持久化取决于它落入哪种模式。在 root 模式下,它叠加两种互相加强的机制;在用户态模式下,它回退到第三种。

#机制模式细节
1systemd 服务rootkernel-kd.serviceType=simpleRestart=alwaysRestartSec=3
2DKMS 模块root把 rootkit 安装到 /lib/modules/$(uname -r)/extra/ 下;可在内核升级后存活
3crontabuser@reboot 加每分钟(* * * * *),带 PID 锁与 setsid

DKMS 条目是最顽固的那个:它通过内核自己的模块构建系统安装 rootkit,因此一次例行的内核升级会重建并重新武装它,而不是移除它。

killservice.sh:清场并封死主机

脚本在其横幅里自称「cryptojacker hardening」(挖矿木马加固),而从操作者的视角看,这个描述很准确。它分三个阶段运行。

阶段 1:关闭暴露的服务。 它针对监听在 0.0.0.0 上、常见的挖矿木马入口,逐一停止、禁用并屏蔽(mask),对其二进制设置 chmod 000,并添加 iptables DROP 规则:

服务端口
Redis6379
Docker2375/2376
PostgreSQL5432
MongoDB27017
Elasticsearch9200/9300
Memcached11211
Hadoop YARN8088
Jenkins8080
Confluence8090

Docker 这一行是连向我们 RedTail 报告 的纽带:Rootpacket 关上的,正是 RedTail 走进来的那扇 2375/2376 门。先落地的操作者会挖掉这台主机,然后把下一个团伙锁在门外,用对手本会使用的技术来加固这台机器。

阶段 2:移除竞争对手矿工。 它杀进程、删文件、清理 cron 任务,并清除与已知挖矿家族关联的 SSH 密钥,这些家族包括 XMRig、Kinsing(kdevtmpfsi)、TeamTNT(tntrechtmdrfckr)、susteswatchdogsminerd,以及 masscanpnscanzgrab 等扫描器。

阶段 3:移除用户态 rootkit。 它从 /etc/ld.so.preload 中剥除已知的恶意 LD_PRELOAD 条目(libprocesshider.solibjdk.solibpamx.so、一个伪造的 libselinux.so.3,以及 xhide)并删除这些库,清掉可能干扰自己的竞争对手用户态 rootkit。

归因

工具包里土耳其语的变量名、注释与状态字符串(例如 ROOT ele gecirildi!,意为「已拿到 root」)以中等置信度指向一名讲土耳其语的操作者。我们发现了一个位于 linuxutil5.pages[.]dev 的分发或暂存 URL,托管在 Cloudflare Pages 上,这与「把载荷暂存在免费、声誉良好的基础设施上以混入其中」的套路相符。内层的 rootpacket.tar.gz 是整个工具包的自包含副本,给了操作者一个随时可推送到下一台主机的现成包。

失陷指标

网络

指标说明
pool.supportxmr.com / pool.supportxmr.com:443主门罗币矿池,stratum+ssl
linuxutil5.pages[.]dev分发 / 暂存(Cloudflare Pages)
api.xmrig.comrandomx.xmrig.com:443XMRig API 与基准测试端点
donate.v2.xmrig.comdonate.ssl.xmrig.comXMRig 开发者捐赠矿池(存在,但捐赠已禁用)
到 443 端口的 stratum+ssl://外连的 TLS 挖矿流量

门罗币钱包: 46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ

文件(SHA-256)

文件SHA-256MD5
rootpacket.tar.gz(外层)e2d0dab6b29df89d123fe8581047a03ac9b89ae8fa0d1f334b5aefbb93152857
getrootdda96d8a4bcc39dc7679347a4386bf1024152d2ccc46d333725ad0cda855d952
xrandom(加壳)ec3ef3dce99fa6cbc480f0f0b0c292676afed68704c44396271c7dc6afea2937

Build ID:getroot 148d8d902efd93ed892a541972fbcea3a99d05a3xrandom d7a91225bdd2e3ab67cabded9d7809bcc724401f

主机痕迹

路径说明
/opt/kernel-kd/xrandom矿工二进制(root 模式)
~/.xrandom/xrandom~/.xrandom/run.sh矿工与启动器(用户态模式)
/tmp/.xrandom.lockPID 锁(用户态模式)
/etc/systemd/system/kernel-kd.service恶意 systemd 单元
/usr/src/intel_uncore_freq_aux-1.2.0/rootkit 的 DKMS 源码
/sys/kernel/intel_uncore_freq/rootkit 的 sysfs 控制接口
/lib/modules/*/extra/intel_uncore_freq_aux.ko编译好的 rootkit 模块

行为特征

  • 一个名为 xrandom、以 root 或当前用户身份运行的进程。
  • 与硬件性能计数器(perf stat)、或与风扇转速和功耗对不上的 /proc/stat CPU 数字。
  • 一个 systemd 服务 kernel-kd(已启用,Type=simpleRestart=always)。
  • 一条标记为 # xrandom-userland-autostart 的 cron 条目。
  • 一个在启动时加载、却不出现在 lsmod 中的内核模块 intel_uncore_freq_aux

检测

如果 rootkit 未加载

systemctl status kernel-kd.service
ls -la /opt/kernel-kd/ ~/.xrandom/
dkms status | grep intel_uncore_freq
crontab -l | grep xrandom
lsmod | grep intel_uncore

如果 rootkit 已加载

用户态视图已被攻陷,因此检测必须来自 rootkit 之下或之旁:

  • perf stat/proc/stat 的 CPU 与硬件计数器对比。差距大就是破绽。
  • 留意对 show_statmeminfo_proc_showiterate_dir 的 ftrace 钩子。
  • 把「报告出的 CPU」与「真实功耗、发热或风扇转速」之间的不一致,当作一个强信号。

捕获提权行为

  • 一个并非已知加密工具(cryptsetupopensslgpgsystemd-cryptsetup)的进程打开了一个 AF_ALGSOCK_SEQPACKET 套接字,这是核心破绽。完整顺序是 socket(AF_ALG)bindsetsockopt(SOL_ALG)acceptpipesplicesendmsgsplicerecvmsg(重复),然后 execve(/usr/bin/su)
  • 把每个 SUID 二进制的磁盘字节与其页缓存视图对比。sha256sum 通过缓存读取,显示的是被破坏的副本,所以请用 dd if=<file> iflag=direct 直接读磁盘并对其求哈希,再做 diff。一个 SUID 二进制上的不匹配,就是页缓存破坏。

候选 YARA

rule Rootpacket_Cryptojacker
{
    meta:
        description = "Rootpacket Linux cryptojacking toolkit"
        reference   = "Kinryu Labs CTI 2026-06-16"
    strings:
        $wallet = "46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ" ascii
        $svc    = "kernel-kd" ascii
        $cron   = "xrandom-userland-autostart" ascii
        $mod    = "intel_uncore_freq_aux" ascii
    condition:
        $wallet or 2 of ($svc, $cron, $mod)
}

修复措施

  1. 从一个已知干净的状态移除 rootkit。 从 live 或恢复介质启动。删除 /lib/modules/*/extra/intel_uncore_freq_aux.ko* 并运行 dkms remove intel_uncore_freq_aux/1.2.0 --all,然后删除 /usr/src/intel_uncore_freq_aux-1.2.0/ 并重建 initramfs(update-initramfs -udracut -fmkinitcpio -P)。DKMS 条目必须清除,否则它会重建。
  2. 移除服务: systemctl stop kernel-kd; systemctl disable kernel-kd; rm /etc/systemd/system/kernel-kd.service; systemctl daemon-reload
  3. 移除矿工: rm -rf /opt/kernel-kd/ ~/.xrandom/ /tmp/.xrandom.lock,然后 pkill -9 -f xrandom
  4. 清理 cron 中的 # xrandom-userland-autostart 行。
  5. 恢复 killservice.sh 破坏的东西。 它对 Redis、Docker、PostgreSQL、MongoDB 及其他二进制设置了 chmod 000 并添加了 iptables DROP 规则。请重装受影响的软件包并复查防火墙。
  6. 横向排查。 内层的 rootpacket.tar.gz 是为再分发而打包的,所以请检查其他主机是否有相同指标,并审阅日志,查找 killservice.sh 中那些服务被利用的痕迹,以找到入口。
  7. 封堵 CVE-2026-31431。 升级到已修复的内核(6.18.22、6.19.12、7.0+,或你发行版的回合补丁)。在无法立即打补丁的地方,禁用脆弱的接口:echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif-aead.conf,然后 rmmod algif_aead。对于容器,在 seccomp 配置中封禁 AF_ALG(family 38)。
  8. 从容器即推定主机失陷。 由于页缓存写入会跨越容器边界,请把任何运行过 setup.sh 的主机(哪怕是从容器内部运行)都当作已完全失陷。重建主机,而不只是删除容器。

MITRE ATT&CK 映射

战术技术
初始访问T1190 Exploit Public-Facing Application(Redis、Docker、MongoDB、Elasticsearch、Jenkins、Hadoop YARN,隐含)
执行T1059.004 Unix Shell
提权T1068 Exploitation for Privilege Escalation(CVE-2026-31431,AF_ALG algif_aead);T1611 Escape to Host(共享页缓存)
持久化T1543.002 Systemd Service;T1053.003 Cron;T1547.006 Kernel Modules(DKMS)
防御规避T1014 Rootkit;T1036.005 Masquerading: Match Legitimate Name;T1027.002 Software Packing(UPX);T1070.004 File Deletion;T1564.001 Hidden Files
发现T1057 Process Discovery(猎杀对手)
横向移动T1570 Lateral Tool Transfer(内层再分发包)
影响T1496 Resource Hijacking(门罗币挖矿)

方法论与分析师备注

  • 分析主要为静态(字符串提取、反汇编、源码审阅、结构分析),在 Kali Linux x86-64 上进行。我们也在一台隔离虚拟机(内核 6.6.15)上运行过一次 getroot 以观察其行为:它尝试了 AF_ALG 序列,在该构建上未拿到 root,并回退为以非特权方式运行命令。矿工未运行,也未上传任何东西。
  • 提权组件被判定为 CVE-2026-31431,依据是绑定到 AF_ALG 套接字的 authencesn(hmac(sha256),cbc(aes)) 模板、/usr/bin/su 这一页缓存目标,以及二进制中的 splice/sendmsg/recvmsg 写入循环。
  • 样本(工具包及其各组件)可应其他研究者与防御方的请求提供。请发邮件至 [email protected],并简短说明你的身份以及索取用途。
How to cite
Kinryū Labs (2026). Rootpacket:一个藏身内核的 Linux 挖矿木马工具包. https://kinryu.sh/zh/reports/rootpacket-linux-cryptojacking-rootkit/