
CHARON — pre-built PoC for CVE-2026-46333 (Linux ptrace mm==NULL fd theft)
____ _ _ _ ____ ___ _ _
/ ___|| | | | / \ | _ \ / _ \| \ | |
| | | |_| | / _ \ | |_) | | | | \| |
| |___ | _ |/ ___ \| _ <| |_| | |\ |
\____||_| |_/_/ \_\_| \_\\___/|_| \_|
переправляет fd через Стикс exit-mm()
CVE-2026-46333 / Linux <= 6.12.89
«Страшно впасть в руки Бога живого». — Евреям 10:31
Компактный PoC без зависимостей для CVE-2026-46333: обход проверки
__ptrace_may_access при mm==NULL, раскрытый Qualys 2026-05-15. Charon
гоняет pidfd_getfd(2) наперегонки с умирающим SUID-root процессом,
чтобы вытащить его открытый файловый дескриптор /etc/shadow через
короткое окно mm-NULL в do_exit(). Запускайте от непривилегированного
пользователя на затронутой системе; он выводит /etc/shadow в stdout.
$ ./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 попыток в смоук-тесте.
__ptrace_may_access() пропускает свою проверку возможности дампа,
когда task->mm == NULL. Быстрый путь был написан для потоков ядра
(swapper и др.), у которых законно нет mm и к которым никогда не должен
применяться ptrace. Но do_exit() выполняет exit_mm() до
exit_files(), а значит пользовательский SUID-процесс на короткое
время имеет:
task->mm == NULL (mm уничтожен) → проверка возможности дампа пропущенаsetreuid() → проверка доступа проходитpidfd_getfd(2) доверяет этой проверке доступа и отдаёт атакующему
открытые файловые дескрипторы SUID-процесса.
do_exit()
├── exit_mm() ← task->mm = NULL
├── ... ← __ptrace_may_access() now lies
└── exit_files() ← fd table reaped
Джанн Хорн указал на схему кражи FD в lore.kernel.org в октябре 2020-го. Исправление около 6 лет пролежало на ревью у мейнтейнеров, прежде чем Qualys вернул его в начало очереди.
Исправление в апстриме: 31e62c2ebbfd
(Линус, 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 / текущего статуса будет обновляться по мере выхода бэкпортов.
# Tiny 38 KB static binary (recommended)
sudo apt-get install musl-tools
make static
# Or just the standard glibc build
make
Результат: один ELF-файл ./charon.
./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 обходит /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 — версия только для чтения: она перечисляет тех же
кандидатов, не запуская эксплойт. Полезна для оценки того, какие
дистрибутивы поставляют какие приманки.
| Код | Значение |
|---|
Charon поставляется с четырьмя известными SUID-приманками:
Добавление приманки — это правка из трёх строк в массиве lures[]
в charon.c.
31e62c2ebbfd напрямую.pidfd_getfd(2) через seccomp на production-хостах.chage и passwd, если непривилегированным
пользователям не нужно узнавать срок действия паролей.no_new_privs на хосте полностью
блокирует примитив — каждый «SUID» внутри контейнера становится
инертным, и Charon остаётся без добычи.ВМ челленджа Google kernelctf VRP запускает bash игрока внутри песочницы
nsjail с clone_newuser:true (uid 0 не отображён), chroot:/chroot
и no_new_privs:1. При no_new_privs setuid-бит инертен, поэтому
внутри песочницы нет настоящих SUID-жертв, а /flag лежит на хосте за
пределами chroot. Поэтому Charon не может выиграть kCTF VRP. Он остаётся
полноценным LPE для Linux на физических установках Debian / Ubuntu /
семейства RHEL.
Только для образовательного и санкционированного защитного использования.
⛵ STYX ⛵
╔══════════════════════════════╗
║ do_exit(): ║
║ ├── exit_mm() ← task->mm ║
║ │ = NULL ║
║ ├── ... ← ferry ║
║ └── 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 | ⚠️ проверить |
| 0 | Успех — содержимое файла в stdout |
| 1 | Ни одна SUID-приманка в системе не открывает запрошенный файл |
| 2 | Похоже, ядро пропатчено (CVE-2026-46333 закрыта) |
| 3 | Закончились раунды без попадания (редко; попробуйте -r 5000) |
| 4 | Ошибка CLI / ввода-вывода |
| Бинарник | Открываемый файл | Покрытие дистрибутивов |
|---|
/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 |