本页为译文。英文版本为权威文本。 阅读英文版
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·
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,让 top 和 htop 报告一个平静的 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 Entry point. Checks privilege level, picks a deployment mode.
getroot Privilege escalation. Exploits CVE-2026-31431 (AF_ALG) for local root.
xrandom UPX-packed XMRig 6.26.0, renamed to dodge name-based detection.
kernel/
stealth.c LKM rootkit, compiled via DKMS, disguised as an Intel driver.
install.sh DKMS persistence engine.
killservice.sh Competitor elimination and "hardening".
rootpacket.tar.gz An inner copy of the whole toolkit, packaged for redistribution.
Root 模式。 若尚非 root,setup.sh 会运行 getroot,把 xrandom 复制到 /opt/kernel-kd/,创建一个 systemd 服务,运行 kernel/install.sh 通过 DKMS 编译并加载 rootkit,运行 killservice.sh 清除竞争对手,然后以持久化服务方式启动矿工。
用户态回退。 当 root 触不可及时,setup.sh 把 xrandom 复制到 ~/.xrandom/,写入一个带 PID 锁的启动器,安装一个在重启时及每分钟触发的 crontab 条目,并用 setsid 启动矿工,使其在父 shell 退出后依然存活。
| 特性 | Root 模式 | 用户态模式 |
|---|---|---|
| 矿工位置 | /opt/kernel-kd/xrandom | ~/.xrandom/xrandom |
| 持久化 | systemd(kernel-kd.service) | crontab(@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 |
| CVE | CVE-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 头以计算其入口点的文件偏移,然后循环执行 splice → sendmsg(在 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+ssl 的 pool.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(enabled、cpu_lo、cpu_hi、mem_lo、mem_hi、hide_tag) |
它钩了什么,以及为什么:
- CPU 掩盖。 它钩
show_stat来改写/proc/stat,在可配置的上下界之间(默认 40 到 50 percent)伪造利用率,并用 jiffies 让数字波动,使其像真实负载一样移动,而不是平躺不动。 - 内存掩盖。 它钩
meminfo_proc_show来改写/proc/meminfo,伪造MemFree、MemAvailable、Buffers、Cached、Active和Inactive。 - 进程隐藏。 它钩
iterate_dir来过滤/proc列表,隐藏名字匹配一组硬编码集合的 PID:stealth、masscan、sshruns、ransomx、cpumask、xrandom、cpm_、kcpm、mask_helper、ftrhook、kintel_aux。操作者可在运行时通过/sys/kernel/intel_uncore_freq/hide_tag添加更多名字。 - 文件隐藏。 它隐藏匹配
stealth、cpumask、kintel_aux、intel_uncore_freq_aux以及 sysfs 目录本身的路径。 - 自我隐藏。 加载时它用
list_del_init把自己从/proc/modules和/sys/module/中移除,删除自己的 sysfs kobject,并用try_module_get增加自身引用计数,使rmmod无法卸载它。
那份隐藏清单本身也是一个线索:除了矿工,它还隐藏了 masscan、sshruns 和 ransomx,所以操作者很可能在运行一个扫描器,并且手里可能不止一个矿工。
实际效果是:一名盯着 top 的管理员,看到的是一台繁忙但正常的机器,找不到流氓进程,也看不到那个正在撒谎的内核模块。破绽是物理的、带外的:机器发烫、风扇转起来、功耗攀升,而这些都不是 rootkit 能伪造的。
持久化:三种机制,按模式区分
Rootpacket 的持久化取决于它落入哪种模式。在 root 模式下,它叠加两种互相加强的机制;在用户态模式下,它回退到第三种。
| # | 机制 | 模式 | 细节 |
|---|---|---|---|
| 1 | systemd 服务 | root | kernel-kd.service,Type=simple,Restart=always,RestartSec=3 |
| 2 | DKMS 模块 | root | 把 rootkit 安装到 /lib/modules/$(uname -r)/extra/ 下;可在内核升级后存活 |
| 3 | crontab | user | @reboot 加每分钟(* * * * *),带 PID 锁与 setsid |
DKMS 条目是最顽固的那个:它通过内核自己的模块构建系统安装 rootkit,因此一次例行的内核升级会重建并重新武装它,而不是移除它。
killservice.sh:清场并封死主机
脚本在其横幅里自称「cryptojacker hardening」(挖矿木马加固),而从操作者的视角看,这个描述很准确。它分三个阶段运行。
阶段 1:关闭暴露的服务。 它针对监听在 0.0.0.0 上、常见的挖矿木马入口,逐一停止、禁用并屏蔽(mask),对其二进制设置 chmod 000,并添加 iptables DROP 规则:
| 服务 | 端口 |
|---|---|
| Redis | 6379 |
| Docker | 2375/2376 |
| PostgreSQL | 5432 |
| MongoDB | 27017 |
| Elasticsearch | 9200/9300 |
| Memcached | 11211 |
| Hadoop YARN | 8088 |
| Jenkins | 8080 |
| Confluence | 8090 |
Docker 这一行是连向我们 RedTail 报告 的纽带:Rootpacket 关上的,正是 RedTail 走进来的那扇 2375/2376 门。先落地的操作者会挖掉这台主机,然后把下一个团伙锁在门外,用对手本会使用的技术来加固这台机器。
阶段 2:移除竞争对手矿工。 它杀进程、删文件、清理 cron 任务,并清除与已知挖矿家族关联的 SSH 密钥,这些家族包括 XMRig、Kinsing(kdevtmpfsi)、TeamTNT(tntrecht、mdrfckr)、sustes、watchdogs 和 minerd,以及 masscan、pnscan、zgrab 等扫描器。
阶段 3:移除用户态 rootkit。 它从 /etc/ld.so.preload 中剥除已知的恶意 LD_PRELOAD 条目(libprocesshider.so、libjdk.so、libpamx.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.com、randomx.xmrig.com:443 | XMRig API 与基准测试端点 |
donate.v2.xmrig.com、donate.ssl.xmrig.com | XMRig 开发者捐赠矿池(存在,但捐赠已禁用) |
到 443 端口的 stratum+ssl:// | 外连的 TLS 挖矿流量 |
门罗币钱包: 46NVDFL6v5STw5Qw4j77PoBSHRTYnHZGZ8WRoGvHmpaMX7ZyhNUP2u24TLV9pNgncz1bZF2Vm8KkaNTzU7SXqrnFUx5zgHQ
文件(SHA-256)
| 文件 | SHA-256 | MD5 |
|---|---|---|
rootpacket.tar.gz(外层) | e2d0dab6b29df89d123fe8581047a03ac9b89ae8fa0d1f334b5aefbb93152857 | |
getroot | dda96d8a4bcc39dc7679347a4386bf1024152d2ccc46d333725ad0cda855d952 | |
xrandom(加壳) | ec3ef3dce99fa6cbc480f0f0b0c292676afed68704c44396271c7dc6afea2937 |
Build ID:getroot 148d8d902efd93ed892a541972fbcea3a99d05a3,xrandom d7a91225bdd2e3ab67cabded9d7809bcc724401f。
主机痕迹
| 路径 | 说明 |
|---|---|
/opt/kernel-kd/xrandom | 矿工二进制(root 模式) |
~/.xrandom/xrandom、~/.xrandom/run.sh | 矿工与启动器(用户态模式) |
/tmp/.xrandom.lock | PID 锁(用户态模式) |
/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/statCPU 数字。 - 一个 systemd 服务
kernel-kd(已启用,Type=simple,Restart=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_stat、meminfo_proc_show和iterate_dir的 ftrace 钩子。 - 把「报告出的 CPU」与「真实功耗、发热或风扇转速」之间的不一致,当作一个强信号。
捕获提权行为
- 一个并非已知加密工具(
cryptsetup、openssl、gpg、systemd-cryptsetup)的进程打开了一个AF_ALG、SOCK_SEQPACKET套接字,这是核心破绽。完整顺序是socket(AF_ALG)→bind→setsockopt(SOL_ALG)→accept→pipe→splice→sendmsg→splice→recvmsg(重复),然后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)
}
修复措施
- 从一个已知干净的状态移除 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 -u、dracut -f或mkinitcpio -P)。DKMS 条目必须清除,否则它会重建。 - 移除服务:
systemctl stop kernel-kd; systemctl disable kernel-kd; rm /etc/systemd/system/kernel-kd.service; systemctl daemon-reload。 - 移除矿工:
rm -rf /opt/kernel-kd/ ~/.xrandom/ /tmp/.xrandom.lock,然后pkill -9 -f xrandom。 - 清理 cron 中的
# xrandom-userland-autostart行。 - 恢复 killservice.sh 破坏的东西。 它对 Redis、Docker、PostgreSQL、MongoDB 及其他二进制设置了
chmod 000并添加了 iptables DROP 规则。请重装受影响的软件包并复查防火墙。 - 横向排查。 内层的
rootpacket.tar.gz是为再分发而打包的,所以请检查其他主机是否有相同指标,并审阅日志,查找killservice.sh中那些服务被利用的痕迹,以找到入口。 - 封堵 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)。 - 从容器即推定主机失陷。 由于页缓存写入会跨越容器边界,请把任何运行过
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写入循环。 - 样本(工具包及其各组件)可应其他研究者与防御方的请求提供。请发邮件至 contact@kinryu.sh,并简短说明你的身份以及索取用途。