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

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

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

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

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

Категории

Все категории
Loading categories
cve-2026-98260-uaf — Исследование эксплойта CVE-2026-98260 (UAF в posix-cpu-timers при exec): S9280 Android 14 GKI 6.1 — триггер UAF + примитив записи нуля + SELinux Permissive. Документ передачи в HANDOFF.md | Kitploit
Инструменты/GitHubGitHub/nanoturtle1145/cve-2026-98260-uaf
Безопасность AndroidПовышение привилегийКриминалистика памятиАнализ уязвимостейЭксплуатацияСтатьи и ИсследованияЭксплуатация Бинарных Файлов
GitHub

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
nanoturtle1145/cve-2026-98260-uaf

cve-2026-98260-uaf

Исследование эксплойта CVE-2026-98260 (UAF в posix-cpu-timers при exec): S9280 Android 14 GKI 6.1 — триггер UAF + примитив записи нуля + SELinux Permissive. Документ передачи в HANDOFF.md

Репозиторий
3323 дней назадЕщё не проверено

CVE-2026-98260 — PoC только для срабатывания (UAF в posix-cpu-timers)

Уязвимость

exec: Cleanup POSIX timers right after de_thread() (автор Hyunwoo Kim, upstream от 2026-09-11, Fixes: 55e8c8eb2c7b = начиная с 5.7).

На не-leader потоке E установлен таймер CLOCK_THREAD_CPUTIME_ID; в execve() после того, как de_thread() обменивает tid, обратный поиск task по PID для таймера завершается неудачей, и узел остаётся в posix_cputimers потока E. Если mmap_read_lock_killable() в exec_mmap() возвращает -EINTR (exec завершается неудачей, а код очистки находится дальше), то do_exit() → exit_itimers() освобождает k_itimer, но узел не удаляется; при сборе родительским процессом через wait4() вызов cleanup_timerqueue() → timerqueue_del() работает с уже освобождённым объектом → UAF.

Статус патча (проверено 2026-10-27 в fs/exec.c различных стабильных веток)

Веткаposixtimer_execСтатус
linux-6.1.yотсутствуетне исправлено
linux-5.15.yотсутствуетне исправлено
linux-6.6.yприсутствуетисправлено (6.6.158+)
linux-6.12.yприсутствуетисправлено (6.12.112+)

→ Цели этого проекта (линии 5.15 / 6.1, а также 6.6 ниже 6.6.158) все попадают в затронутый диапазон.

Почему это срабатывание «детерминированное», а не игра на таймингах

  1. Длинное окно удержания блокировки записи: fragment_vmas() с помощью memfd + MAP_FIXED разбивает адресное пространство на --vmas (по умолчанию 50000) несмерживаемых VMA (у каждой vm_pgoff равен 0, у соседних адресов pgoff не непрерывен → vma_merge завершается неудачей). Поток locker многократно вызывает mprotect на всём диапазоне, и обход десятков тысяч VMA удерживает блокировку записи mmap на уровне миллисекунд.
  2. Точная точка синхронизации: killer использует возврат ESRCH от tgkill(tgid, старый tid, 0), чтобы определить, что «de_thread() уже завершил обмен tid», и только тогда отправляет SIGKILL.
  3. Поток-жертва в exec_mmap() неизбежно блокируется на mmap_read_lock_killable() (блокировка чтения перекрыта блокировкой записи), а SIGKILL приходит через микросекунды после этого → этот вызов возвращает -EINTR → exec завершается неудачей. Окно (мс) ≫ время реакции (мкс), поэтому удача не требуется.

⚠️ Важно различать: срабатывание детерминировано; путь от UAF до произвольной записи/изменения cred зависит от организации повторного использования slab в posix_timers_cache (order, objects/slab, CPU partial, принадлежность к memcg) и представляет собой измеримую, итеративную работу с кучей, а не гонку.

Сборка

export ANDROID_NDK_HOME=/home/nt/项目/samsung_root_research/06_工具链/android-ndk-r29
make            # 产物 trigger(aarch64 / Android 21+ / 仅依赖 libc、libdl)

Шаги тестирования

adb push trigger /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/trigger"
adb shell "/data/local/tmp/trigger --check"        # 先看环境
adb shell "/data/local/tmp/trigger; echo exit=\$?"

Признаки успеха (достаточно любого одного):

  • После вывода [*] 开始触发 происходит перезагрузка устройства/чёрный экран (наиболее прямолинейно при panic_on_oops=1)
  • Процесс убит сигналом (exit=137/139), и после этого система остаётся работоспособной
  • В dmesg (требуется root) появляется стек вызовов cleanup_timerqueue / timerqueue_del / rb_erase / rb_next

При неудаче (срабатывание не произошло) программа сама повторит попытку --attempts раз и выведет результат wait4 каждого раунда, в конце подскажет параметры настройки: --vmas 120000 --lockers 4 --cpu 0.

Известные ограничения

  • Успешное срабатывание почти неизбежно приводит к перезагрузке устройства (это и есть доказательство «успеха»); перед тестом убедитесь, что нет несохранённой работы.
  • У Samsung panic_on_oops может быть равен 0: в этом случае задача будет убита, а ядро продолжит работу с повреждённым rbtree; рекомендуется запустить 2–3 раза подряд и понаблюдать, не возникнет ли последующий panic.
  • Данный PoC не содержит кода повышения привилегий (не выполняет reclaim, не трогает cred), используется только для проверки достижимости и детерминированности.

Ссылки

  • Восходящий патч https://github.com/torvalds/linux/commit/acb03d3881818581052924a9bbbe92b8741ed448
  • Полная цепочка Honor MagicPad3 Pro (6.12.38, включая uid-0 и загрузку KSU) https://github.com/woshigenm/CVE-2026-98260
  • Заметки о портировании на vivo/iQOO 6.6.127 (оркестрация reclaim, параметры SLUB) https://github.com/janewas/cve-2026-98260-vivo-gki-research

Запись фактических испытаний (SM-S9280 / e3q / 6.1.162 / Android 17 / патч безопасности 2026-09-05)

Тестовая среда: S9280ZHU6EZIF, ядро 6.1.162-android14-11-34343818-abS9280ZHU6EZIF (сборка 2026-09-20), без root, домен shell (uid 2000), SELinux Enforcing.

Вывод: срабатывание детерминировано (без ставки на тайминг)

РаундНаблюдениеЗначение
Каждый раундРодительский процесс tgkill(child_tgid, etid, 0) возвращает ESRCHde_thread() уже завершил обмен tid
Каждый раундЗатем kill(child_tgid, SIGKILL), дочерний процесс rc=-9exec прерван (а не rc=0 при успешном exec)
Контроль --no-killerexec от armed до завершения занимает 277 мс (с killer — 287 мс)Блокировка записи mmap действительно блокирует mmap_read_lock_killable() в exec_mmap()

Во всех 5/5 раундах зафиксировано «ESRCH → SIGKILL → сбой exec», ни разу exec не завершился успешно. Это доказывает, что окно прерывания exec после de_thread управляемо и стабильно; окно создаётся mprotect locker'а (60 тыс. VMA, однократно 200–700 мс), а реакция родительского процесса — на уровне µs.

Две ключевые ловушки, встреченные на практике (обе уже исправлены в коде)

  1. killer должен находиться в родительском процессе: de_thread() вызывает zap_other_threads() и убивает все остальные потоки того же процесса; killer, размещённый в дочернем процессе, погибнет сам в момент de_thread и никогда не увидит ESRCH (проявляется в том, что exec каждый раз успешен).
  2. Момент reclaim: немедленный spray после SIGKILL неэффективен — в этот момент дочерний процесс ещё не умер, k_itimer ещё не освобождён через RCU. Правильный порядок: waitid(WNOWAIT) дождаться зомби → дождаться освобождения через RCU-колбэк → захватить страницу → в конце wait4 запустить путь reclaim.

Ещё не сделано: сделать UAF видимым

Сейчас шаг «после освобождения узел всё ещё в очереди» стабильно достигнут, но rb_erase в момент wait4 не даёт oops — это означает, что страница slab-жертвы ещё не захвачена нашим spray (partial slab posix_timers_cache всё ещё кэшируется, страница не вернулась в buddy). Это относится к оркестрации reclaim эксплойта, а не к проблеме гонки; нужно действовать по подходу из заметок vivo: сначала самим k_itimer заполнить/опустошить slab, чтобы заставить целую страницу вернуться, затем носителем order-0 (AIO ring и т. п.) точно подхватить разделённую половинку страницы.

Рекомендация на следующий шаг: использовать эту машину как эталон и выполнить направленный reclaim по идее из docs/08-reclaim-choreography.md (заметки vivo); либо проверить на самосборном ядре с KASAN, действительно ли происходит UAF.


Осуществимость портирования полной цепочки (порог фактических испытаний SM-S9280 / 6.1.162)

Публичная цепочка (Honor uid0.c) полагается на kmem-события tracefs для двух ключевых вещей:

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