ssh-keysign-pwn: чтение root-файлов через логическую ошибку в ptrace
ssh-keysign-pwn: шестилетняя логическая ошибка в функции ядра
__ptrace_may_access(), сообщенная Qualys и исправленная Linus Torvalds 14 мая 2026. Непривилегированные пользователи могут читать root-файлы, включая приватные ключи SSH и/etc/shadow. Затронуты все ядра до31e62c2ebbfd.
Еще одна
Май 2026 не был добр к ядру Linux. Dirty Frag, Fragnesia, и теперь — ssh-keysign-pwn — раскрыта Qualys 14 мая и исправлена Linus Torvalds в тот же день.
Эта отличается от семейства «скопировать что-то в page cache». Это чистая логическая ошибка в __ptrace_may_access(), функции ядра, решающей, может ли один процесс инспектировать другой.
| Метрика | Значение |
|---|---|
| Сообщено | Qualys Security Advisory |
| Исправлено | Linus Torvalds |
| Коммит фикса | 31e62c2ebbfd |
| Существовала | ~6 лет |
| Впервые замечена | Jann Horn (Google), октябрь 2020 |
| PoC опубликован | _SiCk |
| Влияние | Чтение root-файлов непривилегированным пользователем |
| Сложность эксплойта | 100–2000 попыток на успешное воровство |
Как это работает
Ошибка живет в __ptrace_may_access(). Эта функция — привратник для интроспекции процессов: она проверяет, разрешено ли процессу копаться в состоянии другого процесса.
Есть особый случай: когда task->mm == NULL (у целевого процесса нет дескриптора памяти — бывает, когда поток завершается, или для потоков ядра), функция пропускает проверку dumpable целиком.
Вот путь кода, делающий это эксплуатируемым:
- Процесс вызывает
do_exit()для завершения do_exit()выполняетexit_mm()сначала — уничтожается дескриптор памяти (mm)- Затем выполняется
exit_files()— но файловые дескрипторы все еще живы на этом этапе - С
task->mm == NULLно открытыми файловыми дескрипторами,pidfd_getfd(2)может украсть эти fd, если uid вызывающего совпадает
Обычно проверки ptrace-доступа заблокировали бы менее привилегированный процесс от доступа к открытым файловым хендлам root-процесса. Но обход через mm == NULL выбивает проверку dumpable, и pidfd_getfd(2) делает остальное.
Это классическая гонка TOCTOU, но окно достаточно широкое — PoC срабатывает за 100–2000 попыток.
Цели эксплойта
Опубликовано два инструмента:
sshkeysign_pwn — целится в ssh-keysign, вспомогательный бинарник, подписывающий вызовы аутентификации хоста. Бинарник открывает файлы ключей SSH хоста (/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key, режим 0600) перед вызовом permanently_set_uid() для сброса привилегий. Затем он проверяет, установлен ли EnableSSHKeysign в sshd_config — если нет, выходит, оставляя fd ключей открытыми. Эта конструкция существует в OpenSSH с 2002 года.
chage_pwn — целится в chage -l <user>. Бинарник открывает /etc/shadow через spw_open(O_RDONLY), затем вызывает setreuid(ruid, ruid) — сбрасывая все привилегии. В окне гонки между сбросом привилегий и закрытием файла fd можно украсть.
Таймлайн
| Дата | Событие |
|---|---|
| ~2020 | Jann Horn идентифицирует паттерн кражи fd и предлагает патч (не смержен) |
| 2026-05-14 | Qualys сообщает уязвимость; Linus Torvalds коммитит фикс (31e62c2ebbfd) |
| 2026-05-14 | Brad Spengler публикует анализ |
| 2026-05-14 | _SiCk публикует PoC на GitHub |
| 2026-05-15 | Qualys отправляет раскрытие в oss-security |
Разрыв между предложением патча Jann Horn в 2020 и отчетом Qualys в 2026 примечателен. Фикс был составлен пять лет назад, но так и не попал в upstream.
Фикс
Linus закоммитил фикс как коммит 31e62c2ebbfd. Патч корректирует поведение ptrace для правильной обработки случая mm == NULL.
Проверьте ваше ядро
uname -r# Исправленные ядра содержат коммит 31e62c2ebbfd# Все ядра до 2026-05-14 уязвимыЧто делает эту уязвимость интересной
- Исправлено в день сообщения. Linus развернулся за часы. Необычно быстро для исправления ядра.
- Jann Horn нашел это в 2020. У сообщества было предложение патча в архивах рассылки пять лет.
- Цели древние. Паттерн
ssh-keysignс оставлением открытых fd датируется 2002 годом.
Это третья крупная уязвимость ядра Linux в мае 2026, после Copy Fail и Dirty Frag. Темп раскрытия ускоряется — частично из-за AI-инструментов аудита, находящих старые баги быстрее, частично из-за фрагментации экосистемы раскрытия (нарушение эмбарго, PoC до патчей).