
CHARON — pre-built PoC for CVE-2026-46333 (Linux ptrace mm==NULL fd theft)
____ _ _ _ ____ ___ _ _
/ ___|| | | | / \ | _ \ / _ \| \ | |
| | | |_| | / _ \ | |_) | | | | \| |
| |___ | _ |/ ___ \| _ <| |_| | |\ |
\____||_| |_/_/ \_\_| \_\\___/|_| \_|
在 exit-mm() Styx 上渡送文件描述符
CVE-2026-46333 / Linux <= 6.12.89
"落入永生神的手中是一件可怕的事。" — 希伯来书 10:31
一个紧凑、无依赖的 CVE-2026-46333 概念验证:Qualys 于 2026-05-15 披露的
__ptrace_may_access mm==NULL 绕过。Charon 将 pidfd_getfd(2) 与一个正在退出的 SUID-root 进程进行竞态,
以在其 do_exit() 中短暂的 mm-NULL 窗口期间提取其打开的 /etc/shadow 文件描述符。
以普通用户身份在受影响系统上运行;它将 /etc/shadow 内容输出到标准输出。
$ ./charon
[banner on stderr]
[*] lure /usr/bin/chage target /etc/shadow
root:$y$j9T$ztS5H...$hz9W87TlqxEW...:...
daemon:*:20582:0:99999:7:::
bin:*:20582:0:99999:7:::
...
典型命中率:在 4 核虚拟机上不到一秒,烟雾测试中约 137 次尝试。
当 task->mm == NULL 时,__ptrace_may_access() 会短路其可转储性检查。
快速路径是为内核线程(swapper 等)编写的,它们合法地没有 mm 且绝不应被 ptraced。
但 do_exit() 在 exit_files() 之前 运行 exit_mm(),这意味着一个用户空间 SUID 进程短暂地具有:
task->mm == NULL(mm 被回收)→ 可转储性检查被跳过setreuid() 后的权限降级 → 访问检查通过pidfd_getfd(2) 信任该访问检查,并将 SUID 进程的打开文件描述符交给攻击者。
do_exit()
├── exit_mm() ← task->mm = NULL
├── ... ← __ptrace_may_access() 现在撒谎
└── exit_files() ← fd 表被回收
Jann Horn 于 2020 年 10 月在 lore.kernel.org 上标记了 FD 窃取的形状。该修复在维护者审查中搁置了约 6 年,直到 Qualys 将其重新提上日程。
上游修复: 31e62c2ebbfd
(Linus 2026-05-14)。截至 2026-05-15,该反向移植尚未进入 linux-6.12.y 或 linux-6.6.y 稳定分支。
| 稳定分支 | 状态 |
|---|---|
| linux-6.12.y (≤ 6.12.89) | ❌ 存在漏洞 |
| linux-6.6.y (修复反向移植前) | ❌ 存在漏洞 |
| mainline ≥ 6.15-rc1 | ✅ 已修补 (31e62c2ebbfd) |
| 发行版 |
|---|
PR / 滚动状态表将在反向移植落地后更新。
# 小巧的 38 KB 静态二进制(推荐)
sudo apt-get install musl-tools
make static
# 或者仅标准 glibc 构建
make
输出:单个 ELF 文件 ./charon。
./charon # 转储 /etc/shadow(默认)
./charon -q # 无横幅/进度信息,仅将 shadow 输出到 stdout
./charon -v # 显示每次命中 + 最终统计
./charon -r 5000 # 为慢速系统增加耐心
./charon -t /etc/ssh/ssh_host_ecdsa_key # 不同目标(使用 ssh-keysign 诱饵)
./charon -a # 如果内置诱饵失败,则自动发现 SUID/SGID 诱饵
./charon -L # 列出候选诱饵而不进行任何尝试
./charon --help
--auto 遍历 /usr/bin、/usr/sbin、/usr/local/{bin,sbin}、
/usr/lib/openssh、/usr/libexec、/bin、/sbin,查找每个
SUID/SGID 常规文件(排除交互式诱饵如 su、sudo、newgrp、pkexec),
并针对请求的目标尝试每个作为诱饵。每个诱饵的预算很紧(5 轮 × 2000 次内部循环),
因此即使没有匹配项,完整扫描也大约在 10 秒内完成。
--list-baits 是只读版本——它在不触发漏洞的情况下枚举相同的候选诱饵。
用于调查各个发行版搭载了哪些诱饵。
| 退出码 | 含义 |
|---|---|
| 0 | 成功——文件内容已输出到 stdout |
Charon 内置了四个已知的 SUID 诱饵:
添加诱饵只需编辑 charon.c 中 lures[] 数组的 3 行代码。
31e62c2ebbfd。pidfd_getfd(2)。chage 和 passwd 的 setuid 位。no_new_privs 会完全阻断此原语——容器内的每个 "SUID" 都会变得无效,使 Charon 没有猎物。Google kernelctf VRP 挑战虚拟机在 nsjail 沙箱中运行玩家的 bash,沙箱带有 clone_newuser:true(uid 0 未映射)、
chroot:/chroot 和 no_new_privs:1。在 no_new_privs 下,setuid 位是无效的,因此沙箱内没有真正的 SUID 猎物,
而 /flag 位于沙箱外的宿主机上。因此 Charon 无法赢得 kCTF VRP。它在裸机 Debian / Ubuntu / RHEL 家族安装上仍然是合法的 Linux LPE。
仅限教育和授权防御用途。
⛵ STYX ⛵
╔══════════════════════════════╗
║ do_exit(): ║
║ ├── exit_mm() ← task->mm ║
║ │ = NULL ║
║ ├── ... ← 渡船 ║
║ └── exit_files() ║
╚══════════════════════════════╝
| 内核 |
|---|
| 状态 (2026-05-15) |
|---|
| Debian trixie | 6.12.86+deb13 | ❌ |
| AlmaLinux 10.1 | 6.12.0-124.55.3 | ❌ |
| Ubuntu 26.04 | 7.0.0-15 | ⚠️ 检查 |
| Fedora 44 | 7.0.4-200 | ⚠️ 检查 |
| 1 |
| 此系统上没有 SUID 诱饵打开请求的文件 |
| 2 | 内核似乎已修补(CVE-2026-46333 已关闭) |
| 3 | 循环次数用完仍未命中(罕见;尝试 -r 5000) |
| 4 | CLI / IO 错误 |
| 二进制 | 它打开的文件 | 发行版覆盖范围 |
|---|
/usr/bin/chage (chage -l <user>) | /etc/shadow | 大多数 Debian、Ubuntu、Fedora |
/usr/sbin/chage | /etc/shadow | RHEL / Rocky / Alma 家族 |
/usr/bin/passwd (passwd -S <user>) | /etc/shadow | 大多数发行版 |
/usr/lib/openssh/ssh-keysign | /etc/ssh/ssh_host_*_key | 启用了 HostbasedAuthentication 的发行版 |