Сергей Попов
Администратор
- 30.12.2015
- 6 165
- 6 946
- Специализация
- OSINT
- Веб-безопасность
- Статус верификации
- ✓ Verified
7 мая 2026 года исследователь Hyunwoo Kim выложил Dirty Frag - класс kernel local privilege escalation уязвимостей page cache write в ядре Linux, дающий root на Debian bookworm/trixie, RHEL 10.1, Ubuntu Noble и ещё нескольких дистрибутивах. Патчей не было. Совсем. Неизвестный сторонний исследователь слил детали одной из двух уязвимостей - xfrm-ESP Page-Cache Write - раньше согласованного срока, сломав эмбарго. Автору ничего не оставалось, кроме как опубликовать полный отчёт с работающим PoC.
По данным Microsoft, зафиксированы подозрительные цепочки действий, совпадающие с паттерном эксплуатации, хотя CISA SSVC классифицирует exploitation status как poc/none. Для тех, кто занимается vulnerability research или ведёт red team engagement, разница между координированным раскрытием и premature third-party disclosure - это разница между «патч вышел за месяц до PoC» и «рабочий эксплойт в открытом доступе, а вендор ещё собирает пакет». Разберём, как disclosure timeline создаёт или уничтожает окно эксплуатации kernel LPE, на верифицированных данных реальных CVE.
CVE disclosure timeline и его влияние на окно эксплуатации
Coordinated vulnerability disclosure работает так: исследователь уведомляет вендора, даёт время на патч (90 дней по политике Google Project Zero, 45 дней по ZDI), публикует детали только после выхода исправления. В идеальном мире окно эксплуатации - промежуток между появлением публичного PoC и установкой патча конечными пользователями - минимально.На практике процесс ломается в нескольких точках:
Сценарий 1: PoC после патча, но до его распространения. Патч лежит в mainline ядра, но дистрибутивы (RHEL, Ubuntu LTS, Debian Stable) ещё не собрали пакеты. Окно: от нескольких дней до нескольких недель. Стандартный n-day vulnerability window.
Сценарий 2: третья сторона раскрывает детали до готовности патча. Другой исследователь, CERT или автор grsecurity-поста публикует анализ или PoC до завершения coordinated disclosure. Вендор вынужден реагировать экстренно. Окно: от нуля (патча нет) до неопределённости. Именно это случилось с Dirty Frag.
Сценарий 3: full disclosure без координации. Исследователь сознательно публикует всё сразу. Встречается реже, удар максимальный.
В терминах MITRE ATT&CK второй сценарий - момент, когда T1588.006 (Vulnerabilities) мгновенно переходит в T1068 (Exploitation for Privilege Escalation): атакующий получает готовый PoC из публичного источника и применяет его при уже полученном initial access.
Место kernel LPE в цепочке атаки
Зачем атакующему local privilege escalation Linux? Типичная цепочка на engagement:- Initial access - SSH с украденными credentials, RCE через веб-приложение, скомпрометированный CI/CD
- Ограниченный shell - непривилегированный пользователь без root
- Kernel LPE (T1068, Privilege Escalation) - эксплуатация уязвимости ядра → root
- Persistence (T1547.006, Kernel Modules and Extensions) - загрузка kernel module, модификация initramfs
- Credential access, lateral movement, exfiltration - с root-правами доступно всё
[Применимо: внутренний пентест, любая Linux-инфраструктура. Внешний пентест - только после получения shell через RCE или compromised credentials.]
CVE-2024-1086: эталон n-day window через Linux kernel privilege escalation PoC
CVE-2024-1086 - use-after-free в компоненте netfilter (nf_tables) ядра Linux (CWE-416). CVSS 7.8 HIGH, вектор AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - local access, low complexity, low privileges, no user interaction. Уязвимы ядра от 3.15 до 6.6.15, от 6.2 до 6.7.3, а также 6.8-rc1. В зоне поражения - Debian, Ubuntu, Red Hat, Fedora, Amazon Linux, Oracle Linux, Rocky Linux.Механика:
nft_verdict_init() допускает положительные значения drop error в verdict. Из-за reverted commit в netfilter nf_hook_slow() (core.c) предполагает, что верхние 16 бит NF_DROP-verdict содержат валидный errno. Когда verdict интерпретируется как NF_DROP, пакет деаллоцируется в nf_hook_slow(), но затем verdict совпадает с NF_ACCEPT, что приводит к дальнейшей обработке уже освобождённого пакета - double-free, классический вариант CWE-416.Timeline: от responsible disclosure до массовой эксплуатации
| Дата | Событие | Влияние на 0-day window |
|---|---|---|
| 31 января 2024 | Координированное раскрытие, CVE присвоен, CVSS 7.8 | Патч в mainline, дистрибутивы начинают сборку |
| 12-14 марта 2024 | Red Hat выпускает RHSA-2024:1249 и RHSA-2024:1332 | RHEL 7 закрыт |
| 26 марта 2024 | Исследователь публикует блог + PoC на GitHub | n-day window открыто |
| 3 апреля 2024 | CrowdStrike ExPRT.AI повышает severity до Critical | Автоматическая переприоритизация |
| 30 мая 2024 | Эксплуатация in the wild подтверждена (inthewild.io, CISA KEV) | n-day переходит в active exploitation |
| 30 мая 2024 | CISA добавляет в KEV, дедлайн - 20 июня (21 день) | Формальное требование к федеральным системам |
Критическая точка - 26 марта. До этого момента уязвимость была запатчена в mainline, Red Hat выпустил обновления. Окно между mainline-патчем и PoC - ~55 дней; RHEL закрыт 12–14 марта, Ubuntu - позже. Кто обновился за это время - тот в безопасности.
Эксплойт работает через unprivileged user namespaces (включены по умолчанию на Debian, Ubuntu). Цепочка: double-free → сканирование физической памяти → обход KASLR → запись в
modprobe_path → root shell.Нюанс, который стоит держать в голове: после выхода из root shell система становится нестабильной и может упасть. На production это катастрофа. На engagement с согласованным scope - допустимо, но обязательно обсудить с заказчиком до запуска. Я видел, как после эксплуатации CVE-2024-1086 на тестовом стенде ядро уходило в панику через 5-10 минут - времени хватает, чтобы закрепиться, но не для вдумчивой пост-эксплуатации.
EPSS: 0.2806, percentile 0.9790 - top-5% всех CVE. Вероятность эксплуатации за 30 дней - почти 28%.
Предусловия и ограничения CVE-2024-1086
Работает если:- Ядро Linux от 3.15 до 6.6.15, от 6.2 до 6.7.3, или 6.8-rc1
- Unprivileged user namespaces включены (Debian, Ubuntu, KernelCTF-дистрибутивы по умолчанию)
- Доступ к nf_tables через user namespace
- Ядро обновлено до 6.6.15+, 6.7.3+, 6.9+
- Unprivileged user namespaces отключены (
unprivileged_userns_clone= 0 на Debian/Ubuntu,user.max_user_namespaces= 0 на RHEL/Fedora) - AppArmor ограничивает создание namespace (Ubuntu 24.04+ с дефолтным профилем)
- В CrowdStrike Falcon для Linux включена политика «suspicious processes» - поведенческая детекция срабатывает на syscall-паттерны double-free и записи в
modprobe_path
Dirty Frag: преждевременное раскрытие уязвимости и класс page-cache write
Dirty Frag - не изолированная уязвимость, а развитие целого класса. Ключевое отличие от предшественников: это детерминированный логический баг, не зависящий от timing window. Race condition не нужен, ядро не паникует при неудачной эксплуатации, success rate высокий. Для пентестера это подарок - предсказуемый, надёжный примитив.EPSS Copy Fail: 0.9627, percentile 0.9987 - top-1%.
S:C (Scope Changed) означает выход за пределы контекста безопасности - возможен container escape. CWE-123 (Write-what-where Condition). Корневая причина связана с обработкой данных в подсистеме IPsec (xfrm). Та же подсистема xfrm/ESP была root cause для CVE-2022-27666 (heap buffer overflow в esp4.c/esp6.c, CVSS 7.8, CWE-787, EPSS 0.0552), хотя корневые причины различны. Подсистема xfrm/ESP - рецидивист: раз за разом порождает kernel LPE уязвимости.
При использовании
splice(2) / MSG_SPLICE_PAGES страницы из pipe прикрепляются к skb. Путь расшифровки ESP выполняет decrypt in-place на externally-backed страницах, позволяя непривилегированному процессу перезаписывать page cache. Это store primitive - аналогичный Copy Fail, но через другую подсистему.CVE-2026-43500 (RxRPC Page-Cache Write): CVSS 7.8 HIGH, вектор AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H. Обработчик DATA-пакетов в
rxrpc_input_call_event() копирует skb в линейный только при skb_cloned() == true, но пропускает случай externally-owned paged fragments с флагом SKBFL_SHARED_FRAG.| Характеристика | xfrm-ESP (CVE-2026-43284) | RxRPC (CVE-2026-43500) |
|---|---|---|
| Требует user namespace | Да | Нет |
| Блокируется AppArmor (Ubuntu) | Да | Нет |
| Модуль в default build | Да (esp4/esp6) | Зависит от дистрибутива |
| Доступен на Ubuntu | Да | Да (rxrpc.ko загружен) |
| Доступен на RHEL 10.1 | Да | Нет (не включён) |
| EPSS | 0.9324 (top-1%) | 0.9277 (top-1%) |
Chaining закрывает слепые зоны обоих вариантов: на Ubuntu, где AppArmor блокирует namespace, срабатывает RxRPC. На RHEL, где rxrpc.ko отсутствует, работает xfrm-ESP через user namespace. Красивая комбинация - один вектор всегда доступен.
Хронология срыва эмбарго
- 30 апреля 2026 - исследователь сообщает о Dirty Frag мейнтейнерам ядра
- 7 мая 2026 - Hyunwoo Kim вынужден опубликовать полный отчёт с PoC обеих уязвимостей
- 8-9 мая 2026 - Debian выпускает DSA-6253-1 (trixie, linux 6.12.86-1) и DSA-6258-1 (bookworm, linux 6.1.170-3)
- 11 мая 2026 - RHEL выпускает RHSA-2026:16062 (kernel-0:6.12.0-124.56.1.el10_1)
- После 11 мая - CVE идентификаторы присвоены, патчи в mainline (f4c50a4034e6 и aa54b1d27fe0)
CISA оценивает CVE-2026-43284 по SSVC как Track* (следить, готовить патч, exploitation: poc), а CVE-2026-43500 - как Track (мониторить, exploitation: none). Публичных подтверждений эксплуатации in the wild на момент анализа не было, но расхождение между формальной классификацией и реальностью - отдельная история.
Принципиальный момент: Dirty Frag эксплуатируется независимо от наличия модуля
algif_aead. Mitigation для Copy Fail через blocklist algif_aead НЕ защищает от Dirty Frag. Каждый новый представитель класса page-cache write обходит mitigation предыдущего. Это не баг - это свойство класса.Ubuntu прямо указывает: «в контейнерных развёртываниях с произвольными third-party workloads уязвимость может обеспечить container escape». Репозиторий Percivalll/Dirty-Frag-Kubernetes-PoC (14 звёзд) демонстрирует node-level code execution из дефолтного непривилегированного Pod на Amazon EKS.
Ptrace race condition: иллюстрация third-party disclosure
В качестве иллюстрации паттерна third-party disclosure рассмотрим характерный (гипотетический, но типичный) сценарий: уязвимость вptrace_may_access(), где функция слишком мягко (fail open) обрабатывает процессы в стадии завершения. При выигрыше race condition атакующий мог бы читать файлы, ранее открытые завершающимся процессом - /etc/shadow, /etc/ssh/ssh_host_key - без соответствующих прав.Типичная динамика: исследователь находит баг, предлагает патч, но без публичного давления исправление не приходит. Публикация анализа и PoC третьей стороной ускоряет реакцию мейнтейнеров. Workaround для ptrace-based уязвимостей:
echo 3 > /proc/sys/kernel/yama/ptrace_scope - полностью отключает ptrace для непривилегированных процессов.[Применимо: внутренний пентест, grey box. Legacy-инфраструктура с ядрами без свежих патчей - максимальный риск.]
Практическая оценка эксплуатируемости kernel LPE в окне n-day
Когда появляется новая kernel local privilege escalation уязвимость с публичным PoC, на engagement нужно быстро ответить на три вопроса: (1) уязвимо ли ядро, (2) доступны ли необходимые примитивы, (3) какие mitigation активны.Требования к окружению
- Доступ: shell непривилегированного пользователя на целевой Linux-системе
- Инструменты:
uname,lsmod,cat,sysctl- предустановлены на любом дистрибутиве - Сценарий: внутренний пентест, grey box / white box (shell уже получен)
Preflight-проверка
Bash:
# Версия ядра - сопоставить с affected versions конкретной CVE
uname -r
# Загруженные модули - что торчит из attack surface
lsmod | grep -E 'nf_tables|esp4|esp6|rxrpc|af_packet'
# Unprivileged user namespaces - без них большинство LPE не взлетит
# Debian/Ubuntu:
sysctl kernel.unprivileged_userns_clone 2>/dev/null
# RHEL/Fedora:
sysctl user.max_user_namespaces 2>/dev/null
# Универсальная проверка (просто пробуем):
unshare -Urn id 2>&1 | head -1
# Ptrace scope - для ptrace-based race conditions
cat /proc/sys/kernel/yama/ptrace_scope
# AppArmor / SELinux - определяют доступность namespace
aa-status 2>/dev/null; getenforce 2>/dev/null
Decision tree для Dirty Frag
uname -r- ядро до 6.12.86 (Debian bookworm) или до 6.12.0-124.56.1 (RHEL 10) → версия уязвимаlsmod | grep esp4возвращает результат → xfrm-ESP вектор доступенsysctl kernel.unprivileged_userns_clone= 1 (Debian/Ubuntu) илиsysctl user.max_user_namespaces> 0 (RHEL/Fedora), либоunshare -Urn idуспешно → namespace доступен → xfrm-ESP exploit применим- Если namespace заблокирован AppArmor →
lsmod | grep rxrpc→ если rxrpc загружен → RxRPC вектор - Оба вектора заблокированы → Dirty Frag не эксплуатируем на этой системе
Перед kernel LPE - проверить простые пути
Kernel exploit - тяжёлая артиллерия. На production эксплуатация ядерной уязвимости может уронить систему (CVE-2024-1086 делает её нестабильной после закрытия root shell). Перед запуском стоит проверить:- SUID/SGID-бинари:
find / -perm -4000 -type f 2>/dev/null - Sudo misconfigurations:
sudo -l - Cron-задачи с world-writable скриптами
- Capabilities на бинарях:
getcap -r / 2>/dev/null
Ограничения kernel exploit LPE техник в современных средах
Namespace и MAC-системы
Ubuntu 24.04+ по умолчанию использует AppArmor-профиль, блокирующий unprivileged user namespaces. Это убивает значительную часть kernel LPE PoC - CVE-2024-1086, xfrm-ESP вектор Dirty Frag, CVE-2017-7308 (af_packet, CWE-681/CWE-787) - все зависят от namespace для доступа к целевой подсистеме.RHEL/CentOS с SELinux в enforcing-режиме ограничивают syscall-паттерны через политики. На hardened-системах это может предотвратить trigger уязвимости даже при уязвимом ядре. Ключевое слово - «может»: конфигурация SELinux на каждой системе своя.
Контейнерная изоляция
В Kubernetes с дефолтным seccomp-профилем Dirty Frag ограничен: xfrm user netlink interface требует CAP_NET_ADMIN. Но CVE-2026-43284 имеет S:C (Scope Changed) в CVSS-векторе - container escape возможен в средах без hardened seccomp profile.CVE-2017-7308 в контейнере работает иначе, чем на голом хосте: как демонстрирует исследование Snyk, exploit через af_packet даёт root UID и все capabilities, но остаётся в namespace «клетке» - файловая система хоста недоступна, процессы не видны, сетевые интерфейсы изолированы. Для полного escape нужно дополнительно перезаписать
struct nsproxy текущего контекста указателем на init_nsproxy хоста. То есть root есть, а толку - половина.Module blocklisting как emergency mitigation
Когда патч недоступен, а система уязвима:
Bash:
sudo sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\n\
install rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf; \
rmmod esp4 esp6 rxrpc 2>/dev/null; true"
sysctl -w kernel.yama.ptrace_scope=3 - полный запрет ptrace для непривилегированных процессов, что сломает strace и отладчики.Mitigation Copy Fail (blocklist algif_aead) НЕ защищает от Dirty Frag - каждый следующий представитель класса page-cache write обходит mitigation предыдущего. Patch gap exploitation остаётся актуальным, и это не изменится, пока класс уязвимостей существует.
Обнаружение эксплуатации
CrowdStrike Falcon, согласно публикациям вендора, детектирует CVE-2024-1086 через IOA (Indicators of Attack) при включённой политике «suspicious processes» для Linux. Поведенческая детекция срабатывает на характерные syscall-паттерны и попытки записи вmodprobe_path. Для Dirty Frag на момент появления advisories вендор-специфичных сигнатур не было - ни у CrowdStrike, ни у SentinelOne, ни у Elastic.Из open-source: KaraZajac/DIRTYFAIL (23 звезды, обновлён июль 2026) - детектор + PoC для Copy Fail и Dirty Frag; 0xlane/pagecache-guard (5 звёзд) - runtime integrity guard через O_DIRECT + fanotify для обнаружения page cache tampering. Оба проекта молодые, но рабочие.
LLM и расширение поверхности обнаружения kernel уязвимостей
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Координированное раскрытие в классической форме - 90-дневное окно, тихий патч, публикация после обновления - для kernel LPE работает всё хуже. Не потому, что исследователи безответственны, а потому, что хозяйство Linux-дистрибутивов распространяет патчи неравномерно. Debian trixie получил патч через 1 день, bookworm - через 2 дня, RHEL 10.1 - через 4 дня. А тысячи production-серверов с ядром из LTS-ветки, которое не обновляют принципиально, остаются уязвимыми месяцами.
Third-party disclosure ускоряет не только атакующих, но и защитников - и это не апология безответственного раскрытия, а констатация. На практике без публичного давления известные баги могут оставаться неисправленными годами, а third-party disclosure нередко становится катализатором для выпуска патча.
Для тех, кто занимается vulnerability research, мониторинг disclosure events - не формальность, а operational advantage. Kernel mailing list, grsecurity-посты, EPSS через API FIRST.org, CISA KEV RSS - инструменты, определяющие, на чьей стороне окажется время. EPSS в top-1% - сигнал к немедленному действию: либо вы используете patch gap exploitation на engagement, либо ваш клиент закрывает дыру до того, как это сделает кто-то другой. Если хочется потрогать kernel exploitation руками - pwn-категория на HackerLab.pro даёт стенд, где примитив нужно собрать в рабочую цепочку от trigger до root shell.