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

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

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

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

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

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/sammyenigma/cve-2026-43499-s26
Безопасность AndroidПовышение привилегийКриминалистика памятиМеханизмы персистентностиЭксплуатацияОбратная инженерияШелл-кодПост-эксплуатацияМобильная безопасность

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
Разработка Полезной Нагрузки
Эксплуатация Бинарных Файлов
GitHubsammyenigma/cve-2026-43499-s26

CVE-2026-43499-S26

Эксплойт ядра Android GKI 6.12 для CVE-2026-43499, объединяющий ошибку отката rt_mutex с перезаписью стека pselect для получения root на устройствах Samsung и Pixel.

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

CVE-2026-43499 — эксплойт ядра Android GKI 6.12 pselect / configfs

Эксплойт ядра Linux для линейки Android GKI 6.12 (устройства Samsung и Pixel), нацеленный на CVE-2026-43499: ошибочный откат remove_waiter() в rt_mutex_start_proxy_lock(), который использует current вместо waiter::task, оставляя pi_blocked_on ожидающего указывающим на его (позже извлечённый из стека) rt_mutex_waiter в стеке ядра. В сочетании с перезаписью стека fd_set через pselect() и обходом поддельного rb_tree, управляемым потребителем через sched_setattr, это даёт детерминированный примитив записи в ядро и полный root.

Эксплойт работает как разделяемая библиотека LD_PRELOAD (preload.so) и устанавливает root-демон su плюс обои как пост-root артефакты.

Статус: активная разработка. Цель m1q (ZF1) — основной фокус bring-up. pipei tmp_page-uname bootstrap — текущий активный маршрут: обход доказанно чист на устройстве (сборка #33: посеянные rt_mutex-регионы для каждого потомка), и полный перебор 168 кандидатов в процессе. Маршрут configfs CFI — тупик на m1q (Rust ashmem — нет инжектируемого слота fops) и остаётся маршрутом для целей C-ashmem. Смещения для каждой цели различаются по устройству — проверяйте их по фактическому бинарнику ядра, прежде чем доверять им.

Уязвимый примитив (CVE-2026-43499)

Когда FUTEX_CMP_REQUEUE_PI переставляет ожидающего в очередь и обход цепочки обнаружения взаимоблокировок при перестановке возвращает -EDEADLK, __rt_mutex_start_proxy_lock() выполняет откат через remove_waiter() (rtmutex.c:1535). Откат корректно удаляет ожидающего из дерева ожидания, но очищает pi_blocked_on вызывающего перестановку, а не waiter->task->pi_blocked_on. pi_blocked_on ОЖИДАЮЩЕГО остаётся висящим на его стековом rt_mutex_waiter, который извлекается из стека, как только futex истекает по таймауту.

После таймаута область стека ядра ожидающего переиспользуется: core_sys_select() копирует три fd_set в этот стековый буфер (путь стека nfds < 344 на ZF1). Специально сформированный массив слов fd_set воссоздаёт поддельный rt_mutex_waiter / поддельную задачу / поддельный rt_mutex (с корнем rb_tree, указатели которого контролируются). Затем поток-потребитель вызывает sched_setattr_tid(waiter) → rt_mutex_adjust_pi() → rb_erase_cached, что производит запись контролируемого значения по произвольному адресу.

Весь примитив требует цикла в PI-цепочке: владелец удерживает f_pi_target и также блокируется на f_pi_chain (удерживаемом ожидающим), поэтому обход цепочки попадает в owner → chain → waiter → target → owner и завершается ошибкой -EDEADLK. Удаление цикла заставляет перестановку вернуть успех с нулевым эффектом в ядре.

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

  1. Slide (KASLR) — утечка базы ядра. Два маршрута:
    • tracefs sched_blocked_reason (основной на m1q, доказан на устройстве): сохранённый PC возврата заблокированного kworker (stack_trace_save_tsk) читается из кольцевого буфера и сравнивается со вкомпилированным смещением worker_thread. Выполняется до использования любых слов маршрута boot_id, чтобы цели записи через data-alias (data_addr() = p0 alias + slide_p0_offset) оставались корректными при ненулевом slide.
    • маршрут boot_id pselect (запасной, не зависит от slide): запись pselect помещает SLIDE_LOGGERS_0_1 в данные sysctl boot_id через alias линейного отображения; утёкшее значение восстанавливает stext. Отложен на m1q: его цель W1 (SLIDE_RANDOM_BOOT_ID_DATA_OFF, младшая физическая RAM) имеет зависящую от страницы записываемость — slide перемещает цель через границы страниц при каждой загрузке, поэтому ~6/7 запусков дают сбой. Используется только явно через SLIDE_FORCE_BOOTID (тест механизма) с перенаправлением tree_pc/tree_left на заспреенную страницу.
  2. KernelSnitch — спрей объектов размером с mm_struct и использование коллизии futex-хэша для обнаружения mm_struct в куче, что утекает адрес страницы кучи ядра, используемый как база спрея поддельных объектов. Ожидающие отсоединяются (не присоединяются) при очистке, чтобы избежать OOM стека ядра, который приводил к краху сборок до #26.
  3. Основной маршрут — pipei tmp_page bootstrap (m1q, текущий фокус) — исходный маршрут configfs CFI — тупик на m1q: у Rust ashmem нет инжектируемого статического слота write_iter, а кучевый объект ASHMEM_SET_NAME — это KVec, чья раскладка не совпадает с private_data configfs_bin_write_iter. m1q переключается на запись в kmalloc: возвращает утёкший mm-блок порядка 3 как объекты pipe_inode_info и использует запись pselect W1 (*(tree_left) = tree_pc) для перезаписи слота tmp_page кандидата (+0x90) страницей пространства имён UTS (init_uts_ns). Веерная запись помещает маркерное имя по смещению sysname, и uname() сообщает "CatOS" — проверяемая запись в ядро без зависимости от статических объектов. Цели C-ashmem сохраняют путь configfs.
  4. Pipe physrw — подделка страниц буфера pipe в заспреенной странице ядра для физического чтения/записи: патчинг cred, отключение SELinux и прямая манипуляция памятью ядра.
  5. Root — патчинг cred корневого потомка (uid/gid/caps/SELinux SID), затем preload.c устанавливает встроенный демон su (смонтированный через tmpfs в /apex/com.android.virt/bin, плюс варианты в пространстве имён adbd и локальные) и меняет обои.

Форма обхода (m1q, доказано на устройстве)

Слова fd_set pselect воссоздают поддельный rt_mutex_waiter в стеке ядра ожидающего; sched_setattr_tid(waiter) потока-потребителя обходит его через rt_mutex_adjust_pi(). Карта слов ZF1 (проверено по дизассемблеру): PSELECT_WAITER_WORD_SHIFT = 0, слово 12 = task (@+0x50), слово 13 = lock (@+0x58), слово 14 = wake_state (@+0x60 = 3). С посеянным поддельным rt_mutex обход завершается чисто: rb_erase W1 *(tree_left)=tree_pc / W2 *(tree_pc&~3+8)=tree_left из [7] — единственные записи в ядро; [11] (setprio / dequeue_pi) и пробуждение [9] оба пропускаются (локальный поддельный ожидающий с приоритетом 100 удерживает стековый узел вне top-waiter). Каждое завершение обхода, входившее в него, начиная со сборки #19 выживает на устройстве; детерминированные крахи до этого были ошибкой размещения 8-байтовой полезной нагрузки (SKB_DATA_DELTA), а не сбоем тела обхода.

Стадия 3 (мост pgd-swap, только статика/сборка)

Опциональная фаза STAGE3=1, которая форкает дочерний мост, подменяет его mm->pgd на подготовленную поддельную таблицу страниц (3 уровня: PGD→L1→L2, RX-лист цикла + RW-лист стека) и позволяет потомку выполнить ассемблерный блоб только из регистров, который патчит его собственный cred через окно физического сканирования 2MB — физическое чтение/запись всей RAM без примитивов configfs/pipe. В настоящее время подключено только в цель m1q и не запускалось на устройстве.

Поддерживаемые цели

41 цель в src/targets/<codename>-<build>/, каждая требует как минимум target.h (смещения символов ядра, KIMAGE_TEXT_BASE, база прямого отображения, смещения структур). Цели Pixel (comet, tokay, tegu, caiman, komodo, frankel, mustang, rango, stallion, blazer) переопределяют общие исходники; цели Samsung (m1q-*) добавляют специфичную для устройства логику.

make list-projects   # полный список

Раскладки структур ядра различаются по устройству — смещения должны быть проверены по фактическому бинарнику ядра / kallsyms для каждой цели.

Сборка

Выход: build/<PROJECT>/bin/preload.so (разделяемая библиотека, загружаемая через LD_PRELOAD).

# Проект по умолчанию
CC=clang make

# Конкретная цель устройства (по умолчанию: blazer-CP2A.260605.012)
CC=clang make PROJECT=m1q-BP4A.251205.006

# Без CC=clang: использует NDK, если найден ($NDK_ROOT / $ANDROID_NDK_HOME /
# $ANDROID_NDK_ROOT), иначе host clang + Android sysroot
make PROJECT=m1q-BP4A.251205.006
Скачать инструмент