
CVE-2026-31431 (Copy Fail) — новая эксплуатация: повреждение живого кода через page cache. Перезаписывает код libc exit() через совместное использование страниц MAP_PRIVATE — затрагивает ВСЕ запущенные процессы.
Новая техника эксплуатации CVE-2026-31431 («Copy Fail»), которая повреждает исполняемый код запущенных процессов через page cache ядра Linux, обеспечивая повышение привилегий до root.
Все опубликованные эксплойты для этой CVE повреждают файлы данных — изменяя /etc/passwd для смены UID root или патча setuid-бинарников на диске. Этот эксплойт делает принципиально иное: он повреждает живой исполняемый код в памяти через механизм page cache ядра.
| Опубликованные эксплойты | Этот эксплойт | |
|---|---|---|
| Цель | Файлы данных (/etc/passwd, /usr/bin/su) | Исполняемый код (секция .text libc) |
| Механизм | Содержимое файла, разбираемое программами | Кодовые страницы, исполняемые напрямую CPU |
| Охват | Один файл | ВСЕ процессы, отображающие libc |
| Изменение на диске | Да (изменяется содержимое файла) | Нет (только page cache в памяти) |
| Обнаружение | Мониторинг целостности файлов | Невидимо для проверок файловой системы |
Когда Linux отображает общую библиотеку с MAP_PRIVATE, он не копирует страницы файла немедленно. Вместо этого записи таблицы страниц процесса указывают напрямую на физические страницы page cache. Копирование происходит только при записи (copy-on-write). Для кодовых страниц (.text) процессы никогда не пишут в них — поэтому они остаются общими с page cache навсегда.
Process A (bash) Process B (su) Page Cache (libc)
┌──────┐ ┌──────┐ ┌──────────┐
│ PTE │───────────>│ │ │ exit(): │
│ │ │ PTE │───────────>│ endbr64 │
└──────┘ └──────┘ │ push rax │
MAP_PRIVATE MAP_PRIVATE │ ... │
(clean page) (clean page) └──────────┘
↑
Copy Fail пишет сюда!
CVE-2026-31431 даёт нам контролируемую запись 4 байт в page cache любого читаемого файла. Повреждая кодовые страницы libc, мы изменяем инструкции, которые исполняет каждый процесс.
on_exit() в page cache libc — 10 записей по 4 байтаexit() для перехода на наш шеллкод — 1 запись в 4 байтаexit() (практически любая программа), исполняет наш шеллкодШеллкод выполняет setuid(0) → setgid(0) → execve("/bin/sh"), давая root-оболочку.
crypto/algif_aead.c — оптимизация на месте 2017 года (72548b093ee3) позволяет splice() подавать страницы page cache в дешифрование AEAD. Перестановка ESN в алгоритме authencesn записывает 4 служебных байта обратно в исходный scatterlist, повреждая page cache сцеплённого файла.# Компиляция
gcc -o exploit exploit.c
# Запуск от непривилегированного пользователя
./exploit /lib/x86_64-linux-gnu/libc-2.31.so
# Триггер — запустите любую программу (она вызовет exit())
su -c id
# uid=0(root) gid=0(root) groups=0(root)
process 'id' launched '/bin/sh'exploit.c — Полный эксплойт с инъекцией шеллкодаcopyfail_test.c — Проверка примитива (тест записи 4 байт)72548b093ee3)Этот инструмент предоставлен только для авторизованных исследований в области безопасности и образовательных целей. Не используйте его против систем, которыми вы не владеете или на тестирование которых у вас нет явного разрешения.
Dirty Frag раскрыл ещё два варианта записи в page cache в том же классе ошибок:
esp4/esp6): Тот же приёмник authencesn, что и в Copy Fail, достигается через IPsec ESP-in-UDP. Требует пользовательских пространств имён. Запись 4 байт.rxrpc/rxkad): Дешифрование на месте pcbc(fcrypt) на странице, закреплённой через splice. Пространства имён не требуются. Запись 8 байт.Техника повреждения живого кода из этого репозитория работает с любым из этих примитивов записи в page cache — просто замените функцию write4() на триггер ESP или RxRPC. Техника не зависит от конкретного примитива.