KaraZajac/CHARON

GitHub: KaraZajac/CHARON

针对 CVE-2026-46333 Linux 内核 ptrace 漏洞的紧凑无依赖 PoC,通过竞态条件窃取 SUID 进程的文件描述符实现本地提权。

Stars: 0 | Forks: 0

#### CVE-2026-46333 / Linux <= 6.12.89 / ___|| | | | / \ | _ \ / _ \| \ | | | | | |_| | / _ \ | |_) | | | | \| | | |___ | _ |/ ___ \| _ <| |_| | |\ | \____||_| |_/_/ \_\_| \_\\___/|_| \_| 将 fd 摆渡穿过 exit-mm() 冥河 ## 这是什么 这是一个针对 **CVE-2026-46333** 紧凑且无依赖的 PoC:即 Qualys 于 2026-05-15 披露的 `__ptrace_may_access` mm==NULL 绕过漏洞。 Charon 利用 `pidfd_getfd(2)` 与正在消亡的 SUID-root 进程展开竞速, 通过 `do_exit()` 中短暂的 mm-NULL 窗口提取其打开的 `/etc/shadow` 文件描述符。 #### 以非特权用户身份在受影响的机器上运行它;它会将 `/etc/shadow` 的内容输出到标准输出。 $ ./charon [标准错误输出上的横幅] [*] lure /usr/bin/chage target /etc/shadow root:$y$j9T$ztS5H...$hz9W87TlqxEW...:... daemon:*:20582:0:99999:7::: bin:*:20582:0:99999:7::: #### ... 典型命中率:在 4 核虚拟机上不到一秒,冒烟测试中约 **~137 次尝试**。 ## 30 秒了解该漏洞 当 `task->mm == NULL` 时,`__ptrace_may_access()` 会短路其可转储性检查。 这个快速路径是为内核线程(如 swapper 等)编写的,它们合法地没有 mm,且永远不应被 ptrace。 但 `do_exit()` 会在 `exit_files()` *之前*运行 `exit_mm()`, 这意味着一个用户空间的 SUID 进程会短暂地具有以下状态: - `task->mm == NULL`(mm 已被回收)→ 可转储性检查被跳过 - 文件表仍然存在 → fd 仍然可以被获取 - 凭证反映了 `setreuid()` 之后的降级状态 → 访问检查通过 `pidfd_getfd(2)` 信任该访问检查,并将 SUID 进程打开的文件描述符交给攻击者。 #### 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`](https://github.com/torvalds/linux/commit/31e62c2ebbfdc3fe3dbdf5e02c92a9dc67087a3a) (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`) | | 发行版 | 内核 | 状态 (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 | ⚠️ 需检查 | 随着反向移植的落地,PR / 滚动状态表将会更新。 ## 构建 ``` # 仅 38 KB 的 Tiny 静态二进制文件(推荐) sudo apt-get install musl-tools make static # 或者仅使用标准的 glibc 构建 #### make Output: a single ELF `./charon`. ## 运行 ```sh ./charon # dump /etc/shadow (default) ./charon -q # no banner / progress, just shadow on stdout ./charon -v # show per-hit + final stats ./charon -r 5000 # more patience for slow systems ./charon -t /etc/ssh/ssh_host_ecdsa_key # different target (uses ssh-keysign bait) ./charon -a # auto-discover SUID/SGID baits if built-ins miss ./charon -L # list candidate baits without trying any #### ./charon --help ### 自动发现 `--auto` walks `/usr/bin`, `/usr/sbin`, `/usr/local/{bin,sbin}`, `/usr/lib/openssh`, `/usr/libexec`, `/bin`, `/sbin`, finds every SUID/SGID regular file (excluding interactive baits like `su`, `sudo`, `newgrp`, `pkexec`), and tries each as a bait against the requested target. Per-bait budget is tight (5 rounds × 2000 inner) so a full scan finishes in ~10 seconds even when nothing matches. `--list-baits` is the read-only version — it enumerates the same candidates without firing the exploit. Useful for surveying which distros ship which baits. ### Exit codes | Code | Meaning | |---|---| | 0 | Success — file contents on stdout | | 1 | No SUID lure on this system opens the requested file | | 2 | Kernel appears patched (CVE-2026-46333 closed) | | 3 | Ran out of rounds without a hit (rare; try `-r 5000`) | | 4 | CLI / IO error | ### Lures Charon ships with four known SUID lures: | Binary | File it opens | Distro coverage | |---|---|---| | `/usr/bin/chage` (`chage -l `) | `/etc/shadow` | Most Debian, Ubuntu, Fedora | | `/usr/sbin/chage` | `/etc/shadow` | RHEL / Rocky / Alma family | | `/usr/bin/passwd` (`passwd -S `) | `/etc/shadow` | Most distros | | `/usr/lib/openssh/ssh-keysign` | `/etc/ssh/ssh_host_*_key` | Distros with HostbasedAuthentication enabled | Adding a lure is a 3-line edit to the `lures[]` array in `charon.c`. ## 缓解措施,直到您的发行版发布 backport - Apply `31e62c2ebbfd` directly. - Disable `pidfd_getfd(2)` via seccomp on production hosts. - Remove the setuid bit from `chage` and `passwd` if you do not need unprivileged users to query password aging. - For containerized workloads, enabling `no_new_privs` on the host blocks the primitive entirely — every "SUID" inside the container becomes inert, leaving Charon with no prey. ## 并非 kernelctf VRP 候选 The Google kernelctf VRP challenge VM runs the player's bash inside an `nsjail` sandbox with `clone_newuser:true` (uid 0 unmapped), `chroot:/chroot`, and `no_new_privs:1`. Under `no_new_privs` the setuid bit is inert, so there are no real SUID prey inside the sandbox, and `/flag` lives on the host outside the chroot. Charon therefore cannot win kCTF VRP. It remains a legitimate Linux LPE on bare-metal Debian / Ubuntu / RHEL family installations. ## 出处 - Bug discovered & disclosed by Qualys → oss-security 2026-05-15. - Reference PoCs by [@0xdeadbeefnetwork](https://github.com/0xdeadbeefnetwork/ssh-keysign-pwn). - Charon rewrites the lure-and-race loop into a single hardened binary, adds CLI ergonomics, patched-kernel auto-detection, and per-distro lure fallback. ## License #### 仅供教学和授权防御使用。 ⛵ STYX ⛵ ╔══════════════════════════════╗ ║ do_exit(): ║ ║ ├── exit_mm() ← task->mm ║ ║ │ = NULL ║ ║ ├── ... ← ferry ║ ║ └── exit_files() ║ #### ╚══════════════════════════════╝ ```
标签:CVE-2026-46333, HTTP工具, Linux内核安全, Linux内核漏洞, meg, pidfd_getfd, PoC, ptrace, SUID, Web报告查看器, 信息安全, 协议分析, 安全渗透, 客户端加密, 影子文件读取, 文件描述符窃取, 暴力破解, 本地提权, 权限提升, 条件竞争, 概念验证代码, 竞态条件, 零依赖