Статья Linux Kernel Privilege Escalation 2026: Fragnesia и Dirty Frag — от PoC до эксплуатации

Обгоревший чип памяти на разобранной плате под лупой в руках в перчатках. Диагностический терминал отображает «CVE-2026-43284 · DIRTY FRAG» зелёным моноширинным шрифтом.


Четыре критических LPE за две недели мая 2026-го. Все - в page cache ядра Linux. Все - без race condition, без kernel panic, с вероятностью успеха близкой к 100%. И все найдены с помощью LLM.

Не какой-то экспериментальный код - боевые эксплойты для получения root shell из-под обычного пользователя. По данным FIRST.org, EPSS-оценка CVE-2026-31431 (CopyFail) составляет 0.9627, а CVE-2026-43284 (Dirty Frag) - 0.9324. Обе в top 1% по вероятности реальной эксплуатации в 30-дневном окне. CopyFail уже в каталоге CISA KEV с пометкой "active exploitation" и дедлайном патчинга 15 мая 2026. Все четыре уязвимости - прямые потомки Dirty Pipe (CVE-2022-0847): тот же примитив записи в page cache через zero-copy пути, только через разные подсистемы ядра.

Зачем атакующему page-cache LPE​

Суть - подмена содержимого setuid-бинарей (/usr/bin/su, /usr/bin/sudo) или системных файлов (/etc/passwd) прямо в оперативной памяти. Файл на диске нетронут, но каждое обращение к нему возвращает отравленную копию из page cache. Root-доступ без записи на диск и без алертов в dmesg. Подробнее - в нашем материале про cve эксплойт разработка.

На внутреннем пентесте цепочка выглядит так:
  1. Initial Access - shell с правами обычного пользователя через SSH, скомпрометированный веб-сервис или контейнер.
  2. Privilege Escalation (T1068) - эксплойт через splice() + ESP/XFRM отравляет page cache setuid-бинаря.
  3. Post-exploitation - root shell. Нет логов в dmesg, нет записи на диск, SELinux в стандартной конфигурации не срабатывает.
Отдельная история для Kubernetes-операторов: на GitHub лежит PoC (Percivalll/Dirty-Frag-Kubernetes-PoC, 13 звёзд), демонстрирующий выход из дефолтного непривилегированного пода на ноду Amazon EKS через CVE-2026-43284. Default Security Context Constraints тут не помогают - page-cache poisoning не требует привилегированных capabilities.

Эволюция page-cache уязвимостей: от Dirty Pipe к Fragnesia​

1784146684300.webp

Все четыре CVE 2026 года и Dirty Pipe эксплуатируют одну и ту же проблему: ядро выполняет in-place запись в page-cache страницу, на которую пользователь имеет только read-доступ, через zero-copy путь без проверки ownership.

CVEИмяПодсистемаCVSSEPSSЯдро (introduced)CWE
CVE-2022-0847Dirty Pipepipe_buffer7.80.895.8 (2020)CWE-665
CVE-2026-31431CopyFailalgif_aead7.80.964.14 (2017)CWE-669, CWE-1288
CVE-2026-43284Dirty Frag (ESP)xfrm-ESP8.80.934.11 (2017)CWE-123
CVE-2026-43500Dirty Frag (RxRPC)rxrpc7.80.935.3 (2019)CWE-787, CWE-123
CVE-2026-46300Fragnesiaskb coalesce7.80.043.9 (2013)CWE-787, CWE-123

Здесь стоит обратить внимание на два момента. CVE-2026-43284 - единственная с CVSS 8.8 и вектором CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H. Компонент S:C (Scope Changed) - уязвимость в сетевом стеке выходит за его пределы и бьёт по page cache всей системы. А Fragnesia (CVE-2026-46300) сидит в ядре с версии 3.9, выпущенной в апреле 2013. Больше 13 лет уязвимого кода в продакшене - и никто не замечал.

По данным Huntress, все уязвимости найдены с использованием LLM-моделей и опубликованы в сжатые сроки: CopyFail - 29 апреля (команда Xint Code), Dirty Frag - 7 мая (исследователь Hyunwoo Kim), Fragnesia - 13 мая (William Bowling, команда V12 Security).

Zero-copy и splice: корень проблемы​

Zero-copy - легитимная оптимизация ядра, существующая с kernel 2.2 (1999). При передаче данных между файловыми дескрипторами CPU не копирует байты между буферами, а передаёт указатели на существующие страницы памяти через DMA. По описанию Huntress: вместо четырёх переключений контекста и четырёх копирований - два переключения и ноль CPU-driven memory copies.

Системный вызов splice() - ключевой элемент всех атак семейства. Он перемещает данные из pipe в сокет, подставляя ссылку на page-cache страницу вместо копии. Ядро при запросе данных проверяет page cache первым: если страница в памяти - содержимое возвращается напрямую, без обращения к диску.

Проблема появляется, когда подсистема-получатель выполняет in-place криптооперацию (шифрование или дешифрование) поверх полученной страницы. Если страница принадлежит page cache read-only файла - его содержимое в RAM модифицируется. Файл на диске цел, но каждый последующий read() возвращает отравленные данные.

Автор Dirty Frag формулирует это так: "что общего у обеих уязвимостей - на zero-copy send path, где splice() подставляет ссылку на page-cache страницу в frag слот отправляющего skb, принимающая сторона ядра выполняет in-place крипто поверх этого frag-а. В результате page cache файлов, к которым непривилегированный пользователь имеет только read-доступ, модифицируется в RAM".

Dirty Frag: CVE-2026-43284 и XFRM уязвимость​

1784146765975.webp

CVE-2026-43284 (CVSS 8.8, CWE-123 - Write-what-where Condition) - логическая ошибка в подсистеме ESP (Encapsulating Security Payload) при использовании XFRM.

Механика из патча в NVD: MSG_SPLICE_PAGES позволяет прикрепить страницы из pipe напрямую к sk_buff. TCP-стек корректно помечает такие skb флагом SKBFL_SHARED_FRAG после вызова skb_splice_from_iter(), сигнализируя: данные нельзя модифицировать in-place, нужна приватная копия. А вот IPv4/IPv6 datagram append paths для UDP этот флаг при splicing страниц не устанавливали.

Итог: ESP-in-UDP пакет из shared pipe pages выглядит для ядра как пакет с собственными данными. Когда ESP-приёмник выполняет in-place дешифрование - он пишет поверх page-cache страницы, на которую атакующий имел только read-доступ.

По данным OSV.dev, уязвимый код присутствует в ядрах от 4.11.0. Фиксированные версии LTS-веток: 5.10.255, 5.15.205. Red Hat выпустил патч RHSA-2026:16062 (11 мая 2026) для RHEL 10 - пакет kernel-0:6.12.0-124.56.1.el10_1. Debian закрыл в DSA-6258-1 (9 мая, bookworm: linux 6.1.170-3) и DSA-6253-1 (8 мая, trixie: linux 6.12.86-1).

Как замечает автор Dirty Frag: "в отличие от Dirty Pipe, который перезаписывал struct pipe_buffer, Dirty Frag перезаписывает frag в struct sk_buff" - отсюда и название.

CVE-2026-43500 - RxRPC-вектор​

CVE-2026-43500 (CVSS 7.8, CWE-787/CWE-123) - подсистема RxRPC, протокол Andrew File System. Из NVD: обработчик DATA-пакетов в rxrpc_input_call_event() и RESPONSE в rxrpc_verify_response() копируют skb в линейный буфер перед security ops только когда skb_cloned() возвращает true. Но skb, который не клон, но содержит externally-owned paged fragments (с SKBFL_SHARED_FRAG от splice() через UDP), обрабатывается in-place - и привет, запись в page cache.

Уязвимость введена в ядро 5.3 (2019). По данным Red Hat, CVE-2026-43500 не затрагивает продукты Red Hat - модуль rxrpc не включён в конфигурацию RHEL. На ванильных ядрах Ubuntu, Fedora, Arch модуль доступен по умолчанию.

Fragnesia (CVE-2026-46300): эксплуатация через коалесценцию skb​

1784146787975.webp

CVE-2026-46300 (CVSS 7.8, вектор CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H, CWE-787/CWE-123) - третий вариант в серии, но с уникальной механикой. И самый "долгоживущий" баг.

Из патча (NVD): skb_try_coalesce() может прикрепить paged frags из @from к @to. Если @from имеет установленный SKBFL_SHARED_FRAG, результирующий @to skb содержит те же externally-owned frags, но маркер shared-frag теряется. Инвариант сломан: ESP input проверяет skb_has_shared_frag() перед решением о копии данных. Маркера нет - ESP считает frags собственными и выполняет in-place дешифрование, записывая в page cache.

William Bowling (V12 Security) описывает: "уязвимость позволяет произвольную побайтовую запись в page cache read-only файлов через подсистему XFRM ESP-in-TCP без race condition".

Fragnesia покрывает самый широкий диапазон уязвимых версий: от ядра 3.9.0 (апрель 2013) до фикса. Патчированные LTS-версии: 5.10.257, 5.15.208. Debian: DSA-6306-1 (28 мая, bookworm: linux 6.1.174-1), DSA-6295-1 (23 мая, trixie: linux 6.12.90-1). Red Hat: RHSA-2026:19540 (20 мая).

Отдельно: на Rocky Linux 8 патч Dirty Frag не закрывает Fragnesia - подтверждено на форуме Rocky Linux, требуется отдельное обновление. Я бы проверил это в первую очередь, если вы на Rocky.

От PoC до root shell: цепочка эксплуатации Dirty Frag​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

в cmdline), CONFIG_XFRM=y. Хватит дефолтного конфига любого мейнстрим-дистрибутива. На GitHub есть готовые QEMU-скрипты: KaraZajac/DIRTYFAIL (22 звезды) содержит детектор и PoC для воспроизведения в изолированной среде.

Предусловия и ограничения kernel LPE техники​

Работает если:
  • Локальный доступ к системе (непривилегированный пользователь)
  • Модули esp4/esp6 доступны для загрузки или загружены
  • Ядро в уязвимом диапазоне версий
  • Целевой setuid-бинарь кэширован в page cache (хватит одного read())
Не работает если:
  • Ядро пропатчено (основной вариант защиты)
  • Модули esp4/esp6 заблокированы через /etc/modprobe.d/
  • user.max_user_namespaces=0 (побочный эффект: ломает rootless-контейнеры, Chromium sandbox, Flatpak)
  • Seccomp-профиль блокирует splice() + XFRM-сокеты (контейнерные среды)
  • Нет доступа к целевому файлу на чтение (экзотический случай)
Принципиальное отличие от классического kernel heap exploitation: нет corruption кучи, нет use-after-free, нет необходимости в heap spray. Атака работает на уровне логической ошибки в обработке флагов - стабильно и без kernel panic при неудачной попытке. На практике это значит: можно применять на продакшен-системах без риска уронить хост. Для пентестера - мечта.

SELinux в enforcing mode не блокирует запись в page cache - она происходит внутри ядра, вне контроля MAC-политик. SELinux может ограничить действия из root shell, но сам privilege escalation проходит.

Место в kill chain и контекст применения​

В MITRE ATT&CK уязвимости маппятся на T1068 (Exploitation for Privilege Escalation). Подготовительные вызовы splice() и создание ESP-сокетов - T1106 (Native API, тактика Execution).

Типичная цепочка на внутреннем пентесте:
  1. Initial Access - скомпрометированный веб-сервис, утёкшие SSH-credentials, RCE в приложении
  2. Execution (T1106) - вызов splice(), создание XFRM-сокетов через Native API
  3. Privilege Escalation (T1068) - page-cache poisoning через Dirty Frag/Fragnesia, root shell
  4. Persistence - backdoor с root-правами, implant в systemd
  5. Lateral Movement - доступ к SSH-ключам, чтение credentials из конфигов и баз данных
Для контейнерных сред: container escape через page-cache poisoning дефолтного setuid -> node-level root -> доступ к kubelet credentials -> lateral movement по кластеру. Не нужен привилегированный контейнер или host PID namespace - хватит дефолтного пода.

Какую CVE применять - decision tree:

УсловиеCVEПодсистема
Ядро pre-5.3, модули ESP доступныCVE-2026-46300 (Fragnesia)skb coalesce
Ядро 4.11+, нужна максимальная надёжностьCVE-2026-43284 (Dirty Frag ESP)xfrm-ESP
RxRPC доступен, RHEL не используетсяCVE-2026-43500 (Dirty Frag RxRPC)rxrpc
algif_aead доступен, нужен запасной вариантCVE-2026-31431 (CopyFail)algif_aead
Все модули доступны, нужен максимум надёжностиKukurigu chain (все три)комбинированный

Митигация и детекция Dirty Frag и Fragnesia​

Блокировка IPsec-модулей​

По рекомендации Red Hat (RHSB-2026-003), если IPsec не используется - самый быстрый путь. Сначала проверяем, загружены ли модули: lsmod | grep -E 'esp4|esp6'. Если нет - блокируем:
Bash:
printf 'install esp4 /bin/false\ninstall esp6 /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf
rmmod esp4 esp6 2>/dev/null; true
Это закрывает CVE-2026-43284 и CVE-2026-46300. Для CVE-2026-43500 на дистрибутивах с RxRPC: install rxrpc /bin/false. На RHEL CVE-2026-43500 не актуален.

Но учтите: блокировка esp4/esp6 полностью ломает IPsec - VPN-туннели, site-to-site соединения. Для сред с активным IPsec этот вариант не подходит, нужен патч.

Отключение unprivileged user namespaces​

Bash:
echo "user.max_user_namespaces=0" > /etc/sysctl.d/dirtyfrag.conf
sysctl --system
Побочные эффекты ощутимые: rootless-контейнеры (Podman без root), sandboxed-браузеры (Chromium sandbox), Flatpak-приложения перестанут работать. Лечение хуже болезни, если у вас на хосте Podman и Chrome.

Контейнерная митигация​

Для Kubernetes и Docker (по рекомендации CERT-EU): блокировка создания AF_ALG сокетов через seccomp-политики на уровне пода. Эксплойт начинается с открытия AF_ALG или XFRM-сокета - seccomp-фильтр рубит цепочку на старте, даже на непатченных ядрах.

Детекция​

  • Auditd: мониторинг splice() в связке с созданием XFRM-сокетов непривилегированными пользователями
  • Runtime-мониторинг page cache: проект pagecache-guard (0xlane/pagecache-guard, 5 звёзд) - проверка целостности через O_DIRECT + fanotify, сравнение содержимого page cache с данными напрямую с диска
  • Falco / Tetragon: правила на создание XFRM-сокетов из непривилегированных процессов

Чеклист для администраторов​

  1. Проверить версию ядра: uname -r - сверить с фиксами (5.10.255+ для CVE-2026-43284, 5.10.257+ для Fragnesia, 6.1.170+ для Debian bookworm, 6.12.86+ для trixie)
  2. Установить патчированное ядро из security-репозитория дистрибутива. Для RHEL/Rocky: dnf --enablerepo=security update kernel, затем перезагрузка
  3. Если немедленный патч невозможен - заблокировать esp4/esp6 через modprobe.d (при отсутствии IPsec) или отключить unprivileged user namespaces
  4. Для Kubernetes: применить seccomp-профиль, блокирующий splice() + XFRM-сокеты на уровне пода; проверить SCC
  5. Для Docker/Podman: --security-opt no-new-privileges, ограниченный seccomp-профиль
  6. После патчинга перезагрузить систему - page cache сбрасывается при reboot
  7. Убедиться, что фикс Fragnesia (CVE-2026-46300) установлен отдельно от Dirty Frag - патчи разные. На Rocky Linux 8 фикс Dirty Frag не закрывает Fragnesia
  8. Настроить мониторинг: pagecache-guard или аналог для детекции page-cache tampering
Четыре page-cache LPE за две недели - и все обнаружены с помощью LLM. Классические подсистемы ядра (ESP, RxRPC, algif_aead), которые десятилетиями считались "скучными" и проверенными, оказались минным полем. Код skb_try_coalesce() с потерей SKBFL_SHARED_FRAG жил с 2013 года - 13 лет ни один аудитор, ни один fuzzer не нашёл проблему, пока за неё не взялся LLM с контекстным окном, способным одновременно видеть семантику флагов и все пути вызова.

Для пентестера два практических вывода. Первый: page-cache LPE - стабильный и бесшумный примитив. Нет race condition, нет heap spray, нет kernel panic. Эксплойт работает в один проход, не оставляет следов в dmesg. На внутреннем пентесте - повышение привилегий за секунды с нулевым риском уронить хост. Второй вывод жёстче: митигация через отключение ESP-модулей или user namespaces ломает инфраструктуру VPN и контейнеров. Между появлением PoC и раскаткой патча проходит от недели до месяца - а Kukurigu уже на Exploit-DB. Следующий класс page-cache уязвимостей найдут не через четыре года, как от Dirty Pipe до CopyFail, а через месяцы - LLM-аудит ядра становится доступнее, и каждая неразмеченная zero-copy подсистема теперь потенциальный вектор. Вопрос не в том, будут ли новые CVE - вопрос в том, успеет ли ваш пайплайн управления обновлениями среагировать быстрее атакующего.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

Похожие темы

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab