Добавить в корзинуПозвонить
Найти в Дзене
The Codeby

732 байта Python-кода — и детерминистический root на любом Linux

Представьте: один скрипт, никаких race condition, никаких per-distro offsets — и через пару секунд ваш www-data превращается в root. Именно так работает CVE-2026-31431, она же Copy Fail — уязвимость, которая пряталась в ядре Linux девять лет. 🔎Суть бага — в пересечении трёх подсистем ядра, которые по отдельности работают корректно: • AF_ALG — сокетный интерфейс к крипто-API ядра, доступный любому непривилегированному процессу • splice() — системный вызов, который передаёт данные через ссылки на страницы page cache без копирования • Page cache — общесистемный кеш, где одна и та же страница памяти обслуживает все процессы, включая setuid-бинари В 2017 году модуль algif_aead получил оптимизацию: destination и reference pages объединили в единый scatterlist. Но код не проверял, можно ли записывать за пределы output-региона. Шаблон authencesn при расшифровке пишет 4 байта scratch-данных по фиксированному смещению. Через splice() атакующий подставляет страницы page cache от setuid-бинаря

732 байта Python-кода — и детерминистический root на любом Linux

Представьте: один скрипт, никаких race condition, никаких per-distro offsets — и через пару секунд ваш www-data превращается в root. Именно так работает CVE-2026-31431, она же Copy Fail — уязвимость, которая пряталась в ядре Linux девять лет.

🔎Суть бага — в пересечении трёх подсистем ядра, которые по отдельности работают корректно:

• AF_ALG — сокетный интерфейс к крипто-API ядра, доступный любому непривилегированному процессу

• splice() — системный вызов, который передаёт данные через ссылки на страницы page cache без копирования

• Page cache — общесистемный кеш, где одна и та же страница памяти обслуживает все процессы, включая setuid-бинари

В 2017 году модуль algif_aead получил оптимизацию: destination и reference pages объединили в единый scatterlist. Но код не проверял, можно ли записывать за пределы output-региона. Шаблон authencesn при расшифровке пишет 4 байта scratch-данных по фиксированному смещению. Через splice() атакующий подставляет страницы page cache от setuid-бинаря — и эти четыре байта записываются прямо в кешированный образ /usr/bin/su. На диске файл не тронут, а в памяти — уже модифицирован.

👉Почему это страшнее Dirty Pipe? Три причины:

1. Детерминизм — нет окна гонки, эксплойт срабатывает со 100% вероятностью

2. Универсальность — работает на каждом крупном дистрибутиве с ядром от 2017 года (Ubuntu, RHEL, Amazon Linux, SUSE, Debian)

3. Container escape — page cache общий для хоста и контейнеров с shared kernel, так что Copy Fail — это ещё и побег из контейнера. PoC для Kubernetes уже валидирован на EKS, GKE и Alibaba Cloud ACK.

🎇Что устояло? МикроВМ (AWS Firecracker, Fargate), gVisor, V8-изоляты Cloudflare Workers — всё, где у каждого tenant своё ядро.

Интересный момент: баг прятался так долго, потому что подсистему crypto/ ревьюили криптографы. Они проверяли IND-CPA, side channels, валидацию параметров. А вопрос «должна ли эта страница памяти вообще быть writeable?» — из другой дисциплины, и он просто выпал из поля зрения. Девять лет.

На практике для пентестера это значит: после получения low-priv shell проверка Copy Fail занимает меньше времени, чем перебор SUID-бинарей или разбор cron jobs. Если модуль algif_aead загружен и ядро не пропатчено — root за секунды.

Полный разбор механики, пошаговую эксплуатацию и рекомендации по защите читайте в полной статье.

https://codeby.net/threads/cve-2026-31431-copy-fail-razbor-linux-privilege-escalation-bez-race-condition.93766/