Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-46215-POC — Эксплойт для CVE-2026-46215, локальное повышение привилегий через use-after-free в DRM GEM ядра Linux. Использует гонки, распыление кучи и перезапись файлов в стиле Dirty Pipe, чтобы превратить непривилегированного пользователя render-node в root без пароля. | Kitploit
Инструменты/GitHubGitHub/0xcyberstan/cve-2026-46215-poc
Повышение привилегийКриминалистика памятиАнализ уязвимостейЭксплуатацияCTFОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHub0xcyberstan/cve-2026-46215-poc

CVE-2026-46215-POC

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Эксплойт для CVE-2026-46215, локальное повышение привилегий через use-after-free в DRM GEM ядра Linux. Использует гонки, распыление кучи и перезапись файлов в стиле Dirty Pipe, чтобы превратить непривилегированного пользователя render-node в root без пароля.

Репозиторий
11232 месяцев назадЕщё не проверено

CVE-2026-46215: DRM GEM change_handle Use-After-Free (повышение привилегий без привилегий)

Локальное повышение привилегий через use-after-free в ioctl ядра DRM DRM_IOCTL_GEM_CHANGE_HANDLE (drm_gem_change_handle_ioctl, номер ioctl 0xD2). Доступен любому пользователю, имеющему доступ к render-узлу (/dev/dri/renderD*, предоставляется активной сессии systemd-logind во всех основных дистрибутивах для настольных ПК). Цепочка в этом репозитории приводит UAF к получению root без пароля из-под непривилегированного пользователя.

  • CVE: CVE-2026-46215 (HIGH, 7.8, AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
  • Введён: v6.18-rc1, коммит 53096728b891 ("drm: Add DRM prime interface to reassign GEM handle", David Francis / AMD), добавлен для работы AMD по CRIU
  • Исправлен в: 6.18.32, 7.0.9, 7.1-rc3 (апстрим 5e28b7b94408). Данный ioctl также отключается в апстриме для 7.1 из-за этой и связанных гонок.
  • Затронуты: v6.18-rc1 до указанных исправленных версий

Атрибуция

Эта ошибка впервые была сообщена Путтиметом Таммасенгом (Puttimet Thammasaeng), которому принадлежит апстрим-кредит Reported-by в исправлении. Я обнаружил и сообщил о ней самостоятельно на [email protected] 2026-04-12. Моё сообщение было подтверждено и передано мейнтейнерам, однако более раннее сообщение указано в апстриме. Данный репозиторий содержит мой собственный анализ и эксплоит.

Writeup: https://cyberstan.co.uk

Статус раскрытия

Исправление включено в выпущенные стабильные ядра (6.18.32 и 7.0.9 и новее). Этот репозиторий был опубликован после того, как исправления стали широко доступны.

Ошибка

drm_gem_change_handle_ioctl() перемещает GEM-объект от одного дескриптора к другому, но никогда не корректирует obj->handle_count. Он также пропускает drm_vma_node_allow/revoke и колбэки открытия/закрытия драйвера. Поскольку handle_count остаётся равным 1, параллельный GEM_CLOSE на старом дескрипторе уменьшает его до 0 и освобождает объект, в то время как новый дескриптор всё ещё ссылается на него в IDR. Этот висящий дескриптор и есть use-after-free, который затем разыменовывается в drm_gem_object_release_handle().

Цепочка эксплоита

  1. Гонка GEM_CHANGE_HANDLE против GEM_CLOSE для получения висящего дескриптора.
  2. Захват освобождённого слота slab-объекта с помощью распылённого массива pipe_buffer (msg_msg feng shui для подгонки kmalloc-512, затем трубы, заполненные splice).
  3. Утечка pipe_buf_ops через информационный ioctl драйвера: obj->size (смещение 216) перекрывается с pipe_buf[5].ops, что даёт указатель на ядро и базу KASLR.
  4. FLINK висящего дескриптора, чтобы obj->name (смещение 224) попал на pipe_buf[5].flags и установил PIPE_BUF_FLAG_CAN_MERGE (name = 16 = 0x10).
  5. Запись в трубы для слияния с page cache и перезаписи файла, доступного только для чтения (стиль DirtyPipe). Цель — /etc/passwd, root становится без пароля.

Смещения проверены через pahole и специфичны для разметки в диапазоне 6.18–7.0. Переопределите макросы GEM_* / PIPEBUF_* для других ядер.

Файлы

  • poc.c — эксплоит. Собирайте статически с -lpthread.
  • run_exploit.sh — собирает PoC и минимальную initramfs, загружает его в QEMU.

Необходимые условия на хосте

qemu-system-x86_64, gcc, busybox (статический), fakeroot, cpio, gzip. KVM (/dev/kvm) рекомендуется; гонка работает значительно надёжнее с ним.

Сборка тестового ядра

Эксплоиту требуется уязвимая цель, собранная с определёнными опциями:

  • CONFIG_KASAN должен быть ВЫКЛЮЧЕН. KASAN изолирует освобождённые slab-объекты и блокирует восстановление распылением труб, поэтому эксплоит не будет работать против сборки с KASAN.
  • Драйвер DRM, который выставляет поля size/name по ожидаемым смещениям: virtio_gpu (используется в демо) или nouveau.
  • CONFIG_DRM=y, CONFIG_DRM_VIRTIO_GPU=y, CONFIG_DEVTMPFS=y, CONFIG_BLK_DEV_INITRD=y.

Шаги:

  1. Возьмите дерево исходников от 6.18 до 7.0 (или любое дерево, не проходящее проверку на исправление ниже).
  2. Установите указанные опции конфигурации и убедитесь, что CONFIG_KASAN не задан.
  3. make -j"$(nproc)" bzImage, что создаст arch/x86/boot/bzImage.

Демо загружается с nokaslr, поэтому утёкший указатель детерминирован. Утечка сама по себе обходит KASLR, так что режим с KASLR тоже работает, адрес просто меняется при каждой загрузке.

Проверка, уязвимо дерево или исправлено

Посмотрите на drivers/gpu/drm/drm_gem.c, функцию drm_gem_change_handle_ioctl().

Быстрая проверка:

root@kitploit:~
awk '/^int drm_gem_change_handle_ioctl/,/^}/' \
    drivers/gpu/drm/drm_gem.c | grep -c handle_count
  • 0 означает УЯЗВИМО (нет обработки счётчика ссылок).
  • ненулевое значение означает ИСПРАВЛЕНО.

По структуре:

  • Уязвимо: захватывает file_priv->prime.lock, один idr_alloc(&file_priv->object_idr, obj, ...), затем idr_remove() на старом дескрипторе. Нет drm_gem_object_handle_get.
  • Исправлено: двухфазная вставка (idr_alloc, затем idr_replace(NULL) для отсоединения старого дескриптора), при этом настоящий объект подменяется только после успешного выполнения операций prime.

Запуск эксплоита

root@kitploit:~
./run_exploit.sh /path/to/bzImage

Он собирает poc.c, помещает его в initramfs и загружает QEMU с -device virtio-gpu-pci и nokaslr. PoC запускается как uid 1000 (без привилегий), после чего скрипт выводит /etc/passwd до и после и даёт доступ к оболочке. Выйдите из ВМ командой poweroff -f или Ctrl-A X.

Ожидаемый вывод

root@kitploit:~
[!] Race won (iter 977): handle=132049
[!] KASLR: pipe_buf_ops = 0xffffffff82428400
[!] EXPLOIT SUCCESSFUL
[!] FLINK: 16 = 0x10
[*] /etc/passwd:
    root::0:0:pwned:/root:/bin/sh
[!] LPE CONFIRMED
[!] root account is now passwordless

Файл /etc/passwd, доступный только для чтения (chmod 444) и принадлежащий root, перезаписывается непривилегированным процессом. Строка root: теряет поле пароля.

Надёжность

  • Около 99% на загрузку в тестах (99/100 на 100 свежих загрузок, плюс 53/53 в более ранних прогонах). PoC повторяет попытки внутренне: при плохой утечке он заново участвует в гонке для получения свежего висящего объекта, а не перераспыляет мёртвый слот — до 200 раундов, каждый раунд — несколько десятков миллисекунд. Большинство загрузок выигрывают гонку с первой попытки; худшее наблюдавшееся использовало 11 из 200 раундов.
  • Редкий (около 1%) режим отказа: проигрывающее переплетение гонки портит состояние ядра и завешивает ВМ (безмолвное зависание, вердикт не выводится). Это присуще UAF на гонках ядра. Если запуск не выводит вердикт в течение примерно 30 секунд, выполните перезагрузку и запустите снова.

Подтверждение исправления

Пересоберите против исправленного дерева (6.18.32, 7.0.9, 7.1-rc3 или новее, либо любое дерево, проходящее проверку на исправление выше) и запустите снова:

root@kitploit:~
./run_exploit.sh /path/to/patched-bzImage

На исправленном ядре эксплоит никогда не должен доходить до "EXPLOIT SUCCESSFUL": гонка больше не освобождает объект из-под нового дескриптора, поэтому утечка никогда не возвращает корректный указатель ядра.

Отказ от ответственности

Опубликовано в исследовательских и защитных целях после выхода исправлений в апстриме. Предоставляется как есть. Запускайте только на виртуальных машинах, которыми вы управляете.

Скачать инструмент