В мае 2026-го Qualys Threat Research Unit раскрыла CVE-2026-46333 - логическую ошибку в
__ptrace_may_access() ядра Linux. Баг прожил в mainline-коде девять лет, начиная с v4.10-rc1 (ноябрь 2016). Четыре рабочих эксплойта - против дефолтных инсталляций Debian 13, Ubuntu 24.04/26.04, Fedora 43 и 44. Непривилегированный локальный пользователь мог читать /etc/shadow, красть SSH host private keys или получить root-шелл через hijack D-Bus соединений к systemd. Публичные PoC появились почти сразу после раскрытия: по оценке CISA-ADP, технический импакт - total, статус эксплуатации - poc. Волна ядерных LPE-уязвимостей мая 2026 не ограничилась одним CVE: помимо CVE-2026-46333 были раскрыты PinTheft, DirtyClone (CVE-2026-43503, CVSS 8.8, CWE-664) и pedit COW (CVE-2026-46331, CWE-190/CWE-787). CVE-2026-31431 (не путать с CVE-2026-46333), с которой CVE-2026-46333 объединяется в цепочку эксплуатации, актуально эксплуатируется и внесена в CISA KEV (дедлайн патчинга - 2026-05-15; short description: "Linux Kernel Incorrect Resource Transfer Between Spheres Vulnerability").Ситуация стандартная: ты уже на сервере. Получил шелл от
www-data через RCE в веб-приложении, зашёл по SSH с угнанными low-priv credentials или попал на хост через скомпрометированный CI-раннер. Между тобой и полным контролем - барьер привилегий ядра. И вот тут начинается самое интересное.По MITRE ATT&CK эксплуатация SUID/SGID-бинарей - это T1548.001 (Setuid and Setgid, тактика Privilege Escalation). В отличие от классических GNU/Linux privesc-техник - misconfigured sudo, writable cron (T1053.003), capabilities с
cap_setuid - здесь не нужна misconfiguration на целевой системе. Уязвимость сидит в самом ядре. Дефолтная конфигурация дистрибутива - достаточное условие для эксплуатации. Никаких кривых sudoers, никаких забытых cron-скриптов. Просто ядро с багом, который девять лет никто не замечал.Финансовый импакт: на shared hosting или в мультитенантных средах одна скомпрометированная учётка - путь к root на всём хосте. Украденные SSH host keys открывают on-path атаки на SSH-соединения, а хеши из
/etc/shadow - offline-брутфорс паролей.[Применимо: внутренний пентест, post-exploitation на Linux-хостах, grey box с low-priv credentials]
Анатомия CVE-2026-46333: логическая ошибка dumpable-проверки в ptrace ядра Linux
По NVD, CVSS 3.1 score - 7.1 (HIGH); вектор:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N. Разберём компоненты: AV:L - только локальный доступ; AC:L - низкая сложность (race condition воспроизводится стабильно); PR:L - нужен любой непривилегированный пользователь; C:H/I:H - полная компрометация конфиденциальности и целостности; A:N - доступность не затрагивается. Подробнее - в нашем руководстве по linux для пентестера.Классификация: CWE-269 (Improper Privilege Management). Уязвимые ветки по OSV.dev: 4.10.0–5.10.255, 5.11.0–5.15.206, а также 5.16.0+ (проверьте свою ветку по OSV.dev). Red Hat подтвердила уязвимость для RHEL 8, 9, 10 и OpenShift Container Platform 4.
Механика: окно гонки при do_exit() и pidfd_getfd()
Функция__ptrace_may_access() использует флаг dumpable, чтобы определить - можно ли присоединиться к чужому процессу через ptrace. Флаг концептуально привязан к наличию memory map (mm). А проблема - в логической ошибке проверки dumpable при transient-состоянии teardown (официальный CWE - CWE-269, Improper Privilege Management; эксплуатация имеет race-подобный характер, но первопричина - некорректная логика get_dumpable() при mm == NULL). Возникает при завершении привилегированного процесса.Последовательность событий в
do_exit() привилегированного SUID-бинаря:- Процесс (например,
ssh-keysign) выполняет работу с повышенными привилегиями, открывает/etc/ssh/*_key - Процесс вызывает
exit(), ядро начинает teardown exit_mm()освобождает memory map - указательmmстановится NULL- Файловые дескрипторы и IPC-соединения ещё открыты - вот оно, окно гонки
- Только потом ядро закрывает open file descriptors
__ptrace_may_access() видит mm == NULL и пропускает ветку if (mm && …) - проверка dumpable не выполняется. При дефолтном ptrace_scope=1 YAMA LSM разрешает доступ parent→child. В нормальных условиях ptrace_may_access() всё равно блокировал бы доступ к SUID-процессу из-за сброшенного dumpable-флага, но после exit_mm() эта проверка не срабатывает - оба барьера сняты одновременно. Атакующий вызывает pidfd_getfd() (syscall, добавленный в v5.6-rc1, январь 2020) и копирует открытые файловые дескрипторы привилегированного процесса к себе.Ключевой момент: для SUID-бинарей
ptrace_may_access() обычно блокирует доступ из-за смены euid и сброса dumpable-флага, но после exit_mm() проверка dumpable пропускается (mm == NULL), а YAMA при ptrace_scope=1 разрешает доступ parent->child. Два барьера падают одновременно.Upstream fix - кеширование последнего состояния dumpability для процессов с mm == NULL и требование CAP_SYS_PTRACE для доступа к таким процессам.
Когда ptrace уязвимость Linux не работает
Техника блокируется если:kernel.yama.ptrace_scopeравен 2 (только CAP_SYS_PTRACE) или 3 (полный запрет). YAMA LSM отклоняет pidfd_getfd() для непривилегированных пользователей- Ядро обновлено до 5.10.256+ или 5.15.207+
- На хосте нет SUID/SGID-бинарей с доступом к чувствительным файлам (маловероятно для дефолтных инсталляций - такое бывает разве что на hardened-контейнерах)
- Ядро старше v5.6 - syscall pidfd_getfd() отсутствует; PoC-примитив недоступен, хотя ядра 4.10–5.5 содержат уязвимый код
- Контейнерные среды: по оценке Canonical, утечка ограничена контейнером и "generally unlikely to be useful to an attacker"
Четыре вектора эксплуатации CVE-2026-46333
Требования к окружению
- ОС: Linux с ядром 4.10 - 5.15.206 (не включая патченные ветки)
- Привилегии: любой непривилегированный пользователь
- ptrace_scope: дефолтное значение 1 (проверить:
sysctl kernel.yama.ptrace_scope) - pidfd_getfd: ядро 5.6+ (есть в большинстве дистрибутивов с 2020 года)
- SUID/SGID бинари:
/usr/bin/chage,/usr/lib/openssh/ssh-keysign,/usr/bin/pkexec - RAM: от 512 МБ (эксплойт нетребователен)
- Сеть: не требуется (полностью локальная атака)
Bash:
uname -r # версия ядра
sysctl kernel.yama.ptrace_scope # должно быть 1 для эксплуатации
find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null | head -20 # SUID/SGID бинари
Утечка credentials: /etc/shadow и SSH host keys
chage -- /etc/shadow. На Debian/Ubuntuchage по умолчанию стоит с set-gid-shadow. Вызываешь chage -l root - она открывает /etc/shadow, потом завершается. В окне между exit_mm() и закрытием дескрипторов атакующий через pidfd_getfd() перехватывает FD и читает содержимое - хеши паролей всех локальных пользователей. Canonical оговаривается, что алгоритмы хеширования Ubuntu (SHA-512/yescrypt) стойки к offline-брутфорсу при сильных паролях. Но "сильные пароли" на shared hosting - скорее исключение, чем правило. Уязвимость воспроизводится на современных дистрибутивах с ядрами 4.10–5.15.206.ssh-keysign -- SSH host private keys. SUID-бинарь
/usr/lib/openssh/ssh-keysign при запуске открывает /etc/ssh/*_key. Атакующий перехватывает дескриптор - и вот у него приватные ключи хоста. Импакт: on-path атаки (MitM) на SSH-соединения, компрометация host-based authentication. Публичный PoC-репозиторий KaraZajac/CHARON содержит pre-built эксплойт: порождает дочерний процесс, открывает pidfd и многократно сканирует файловые дескрипторы через pidfd_getfd(), сверяя каждый дуплицированный дескриптор с целевым файлом через /proc/self/fd/<n>.pkexec и accounts-daemon: произвольный код от root
Два продвинутых вектора дают не чтение файлов, а полноценное выполнение команд от root. Тут уже не просто утечка - это полный захват.pkexec (set-uid-root): атакующий перехватывает аутентифицированное D-Bus соединение к systemd. Предусловие - наличие
allow_active сессии на консоли, что работает даже при удалённом SSH-подключении, если кто-то залогинен локально. Применимо к дистрибутивам с ядрами 4.10–5.15.206 и дефолтным ptrace_scope=1.accounts-daemon (root daemon): эксплойт ищет PID accounts-daemon через
/proc, триггерит активность через busctl и AccountsService, затем гоночными потоками вызывает pidfd_getfd() для кражи D-Bus сокета. Через украденный сокет отправляются handcrafted D-Bus-сообщения: SetShell, SetAccountType(admin), SetPassword с контролируемым хешем. Результат - текущий пользователь получает административные права. Красиво, если честно. Применимо к дистрибутивам с уязвимыми ядрами и дефолтным ptrace_scope=1.Разбор PoC: как работает локальный эксплойт Linux
Публичный репозиторий KaraZajac/CHARON (GitHub, обновлён 2026-05-21, 6 звёзд) содержит pre-built PoC для CVE-2026-46333 (Linux ptrace mm==NULL fd theft). Алгоритм работы:
- Атакующий вызывает целевой SUID/SGID-бинарь как дочерний процесс, перенаправляя stdout/stderr в
/dev/null - Немедленно открывает pidfd через syscall
pidfd_open() - В цикле (сотни итераций, десятки раундов) вызывает
pidfd_getfd(pidfd, target_fd, 0)для диапазона файловых дескрипторов (3-63 для ssh-keysign, 3-499 для research-версий) - Большинство вызовов возвращают
-EPERM- процесс жив, dumpable-проверка работает штатно - В момент, когда дочерний процесс входит в
do_exit()иexit_mm()обнуляет mm, pidfd_getfd() проходит - дескриптор дублируется - Атакующий проверяет путь через
/proc/self/fd/<n>, при совпадении с целевым файлом - читает содержимое
Primitive стабилен: окно между
exit_mm() и закрытием FD достаточно широкое для многократных probe-попыток. AC:L в CVSS-векторе - не для красоты, race действительно воспроизводится с первых попыток.EPSS - 0.9627 (перцентиль 99.87, Top 1%), экстремально высокая вероятность эксплуатации. CISA-ADP SSVC decision: Act - патчить немедленно.
Механика цепочки:
- Через полученный примитив предположительно модифицируется
/etc/shadow- хеш пароля root заменяется на контролируемый - Атакующий выполняет
su rootс новым паролем
Обнаружение и защита от race condition exploit Linux
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
; D3-PLA (Process Lineage Analysis) - выявление аномальных parent-child цепочек.
Чеклист для blue team:
- Проверить
ptrace_scope:sysctl kernel.yama.ptrace_scope(если 1 - уязвимо) - Установить kernel-обновления и перезагрузить (RHEL 8/9/10: все фиксы выпущены, Ubuntu:
sudo apt update && sudo apt upgrade) - Если патчинг невозможен - применить
ptrace_scope=2 - На хостах с untrusted users за период экспозиции - ротировать SSH host keys, проверить
/etc/shadow - Добавить auditd-правило:
auditctl -a always,exit -F arch=b64 -S pidfd_getfd -F auid>=1000 -F auid!=-1 -k ptrace_race(добавьте аналогичное правило дляarch=b32; без фильтра поauidожидайте шум от контейнерных runtime и systemd) - Проверить cron, SUID и capabilities на предмет смежных privesc-векторов (LinPEAS, pspy)
ptrace_may_access() - функции, которую ревьювили десятки разработчиков. Ошибка не в сложной математике, а в порядке операций при teardown: exit_mm() вызывается раньше закрытия файловых дескрипторов. Этого достаточно.CVE-2026-46333 меняет отношение к ptrace в production. Значение
ptrace_scope=1 де-факто небезопасно и должно уйти из дефолтных конфигураций. Ubuntu уже двигается в эту сторону, но большинство RHEL-based дистрибутивов всё ещё шипят с единицей. На каждом пентесте GNU/Linux-инфраструктуры с мая 2026 проверяю ptrace_scope первым делом - до sudo, до SUID, до cron. Если единица - считай, полдела сделано. Отдельная история - цепочка с CVE-2026-31431 (CISA KEV, EPSS 96.27%): это уже не теоретический risk, а подтверждённая боевая эксплуатация. Для defensive-команд вывод один: kernel-обновления в окно обслуживания больше ждать не могут. На HackerLab (https://hackerlab.pro) лежит сценарий, где этот primitive нужно собрать в полную цепочку.
Последнее редактирование модератором: