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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-43499-warhol-root — Локальный эксплойт повышения привилегий, нацеленный на CVE-2026-43499, для устройства Xiaomi 17T Pro (warhol) под управлением Android 16 с SoC MediaTek MT6993. | Kitploit
Инструменты/GitHubGitHub/soralis0912/cve-2026-43499-warhol-root
Безопасность AndroidПовышение привилегийАнализ уязвимостейЭксплуатацияЭксплуатация Бинарных Файлов
GitHubsoralis0912/cve-2026-43499-warhol-root

CVE-2026-43499-warhol-root

Локальный эксплойт повышения привилегий, нацеленный на CVE-2026-43499, для устройства Xiaomi 17T Pro (warhol) под управлением Android 16 с SoC MediaTek MT6993.

Репозиторий

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
1125 дней назадЕщё не проверено

warhol-root

CVE-2026-43499 (IonStack) локальное повышение привилегий, портированный на Xiaomi 17T Pro (warhol) — MediaTek MT6993, Android 16.

Только GKI 6.12 / android16. Оверлей ожидания (waiter overlay), раскладка стека pselect и все смещения структур привязаны к этой ветке, поэтому ничего из этого не переносится на 6.6, 6.1 или 5.10 — для них нужна база, собранная отдельно. generate_target.py отказывается от любого другого баннера, а не генерирует заголовок, который вызвал бы отказ на устройстве.

Статус: работает. Проверено на устройстве 2026-07-26 с чистой загрузки, в обоих вариантах прелоадера — uid=0(root) context=u:r:kernel:s0, SELinux permissive, su установлен. Root не постоянный: повторно выполняйте строку LD_PRELOAD после каждой загрузки. Гонка pselect не даёт 100% результата: неудачный запуск может вызвать панику телефона, а повторная попытка после перезагрузки — это нормально. Полный журнал см. в WARHOL_PORT.md.

Этому устройству требуется исправление kernel-MTE. Стоковый апстрим-попсикл не может получить на нём root — он вечно крутится в kernel page retry N/12. См. Kernel MTE.

Сборки выпускаются в двух вариантах прелоадера: PRELOADER=retail (по умолчанию) и PRELOADER=eng. Они выбирают разные целевые каталоги, чтобы ни один не мог перезаписать адреса другого — см. Вариант прелоадера.


Целевое устройство

Приведённые ниже факты считаны из розничного полного OTA-пакета — метаданных, манифеста A/B-нагрузки и образов boot/vendor_boot/dtbo, извлечённых из payload.bin.

Здесь ядро важнее SoC: warhol находится в той же ветке GKI, что и апстрим-попсикл (android16-5, страницы 4K), на расстоянии в один patchlevel — 6.12.38 против проверенного 6.12.23 у попсикла. Смещения структур всё равно должны перегенерироваться для каждой сборки; переносится только форма эксплойта. Для другой сборки OS3.0.x нужен свой target.h.


Почему эта база

Цепочка эксплойта жёстко привязана к ветке GKI, а не к SoC. Раскладка ожидания rt_mutex, оверлей стека pselect и смещения структуры pipe_buffer отслеживают ядро, поэтому база 6.12/android16 лучше, чем база того же вендора на более старой ветке.

x-spy/CVE-2026-43499-popsicle — единственная публичная реализация, проверенная на линии GKI 6.12/android16 (Xiaomi 17 / Pro / Ultra, ядро 6.12.23-android16-5), поэтому source/ взят из неё и максимально приближен к апстриму — за исключением двух строк (см. Kernel MTE, который этому устройству нужен вообще для работы).

Бо́льшая часть отличий MediaTek сосредоточена в генерации целевых данных на этапе сборки, в двух частях:

  • апстрим читает p0_phys_offset и p0_kernel_phys_load из раздела Qualcomm xbl_config, которого у warhol нет. Вместо этого generate_target.py --dtb читает базовый адрес DRAM из узла /memory FDT из vendor_boot, округляя его вниз так же, как это делает arm64_memblock_init. Физический адрес загрузки ядра считывается из резерва mb_kernel прелоадера через --preloader; для этого устройства дельта получается 0, и lk отказывается загружать ядро, размещённое где-либо ещё.
  • MediaTek поставляет ядро в boot.img, сжатое в LZ4-legacy, а не в виде голого arm64 Image, поэтому генератор распаковывает его перед анализом.

В WARHOL_PORT.md §2 приведён полный вывод.


Вариант прелоадера

MediaTek lk не загружает ядро по константе времени компиляции — он ищет резерв DRAM с именем mb_kernel и проверяет, что ядро приземлилось точно на него. Этот резерв создаёт прелоадер, именно поэтому сборка прелоадера, установленная на телефоне, здесь вообще является входным параметром сборки: это единственное, что вне boot.img может сдвинуть P0_KERNEL_PHYS_LOAD, а неверное значение означает неверный псевдоним линейной карты и мёртвый телефон, а не неудачный эксплойт.

Отсюда два варианта, хранящиеся в отдельных целевых каталогах:

root@kitploit:~
make preload                  # PRELOADER=retail -> out/preload-<device>.so
make PRELOADER=eng preload    #                  -> out/preload-<device>-eng.so
make both                     # оба примера выше, а также вывод их sha256

Оба артефакта хранятся рядом под разными именами. На этой прошивке они получаются побайтно идентичными — это результат приведённого ниже анализа, а не обходной путь, поэтому обе сборки всё равно выполняются и именуются раздельно.

Прочитайте таблицы раскладки памяти обоих прелоадеров самостоятельно:

root@kitploit:~
python3 tools/preloader_memlayout.py <preloader.bin> --diff <preloader_eng.bin>

Для этой прошивки обе таблицы идентичны, mb_kernel.start = 0x80000000 в обеих, поэтому eng-вариант target.h получается побайтно идентичным retail-варианту, и обе сборки дают один и тот же preload.so.

До эксплойта доходит разность P0_KERNEL_PHYS_LOAD − P0_PHYS_OFFSET, и два её слагаемых опираются на неодинаково надёжные данные:

  • P0_KERNEL_PHYS_LOAD — измерено по eng-образу, как указанный выше mb_kernel.start.
  • P0_PHYS_OFFSET — обосновано, а не измерено, поскольку это memstart_addr, который ядро берёт из узла /memory, который lk формирует во время выполнения из данных, сообщаемых прелоадером после инициализации DRAM, а не из статичного FDT, который читает генератор. Аргументация была такой: обе сборки разделяют весь путь DRAM — те же исходники dramc/emi/mblock/memory_layout, и среди eng-only строк нет кода раскладки памяти — а единственный дополнительный резерв eng-прелоадера, динамический security_fe_rsv объёмом 3 МиБ с mapping=1, не может ни сдвинуть запись с фиксированным адресом, ни вырезать дыру внизу DRAM. Запуск на устройстве решил вопрос: псевдонимы линейной карты приземлились под eng, значит, слагаемое верно.

Полный вывод в targets/warhol-OS3.0.304.0.WPSJPXM-eng/NOTES.md.

Заметки с запуска на устройстве:

  • BootROM принимает этот eng-прелоадер — он нормально загрузился в Android, с ro.boot.verifiedbootstate=green и неизменным flash.locked=1. Это оставалось открытым вопросом, пока не было проверено на практике; решает его efuse-хэш корневого ключа, а эта сборка подписана теми же ключами, что и retail.
  • Eng-прелоадер сохраняет живым режим META / заводской загрузки: %s META DIS — строка только retail, тогда как eng несёт целую реализацию META, которой у retail нет (Enable fastmeta., FAST META GPIO: %d, META_COM PORT: %d, read_meta_proinfo, …). Здесь он загрузился сразу в Android, но если телефон с eng-прошивкой когда-нибудь окажется в другом состоянии, вероятная причина именно в этом, и ни одно значение target.h здесь ни при чём.
  • Если более поздняя прошивка сдвинет mb_kernel, две цели разойдутся — хранение их в отдельных каталогах как раз не даёт этому произойти молча.

Kernel MTE

Это ядро работает с KASAN_HW_TAGS — в /proc/cmdline есть kasan.stack_ring_size=524288 — поэтому указатели slab несут тег выделения в битах 59:56. Апстрим-попсикл предполагает указатели без тегов и потому вообще не может получить root на этом устройстве: он бесконечно крутится в [-] kernel page retry N/12 mode=1, и в логе нет ни слова о причине.

Две строки в source/ исправляют это, и обе находятся в warhol-mte-fix.patch:

Снимают тег только проверки. Сами указатели остаются тегированными, потому что тег корректен для памяти, на которую они указывают, — а именно это и нужно при разыменовании их ядром.

Не полагайтесь на arm64.memtag.bootctl: это свойство управляет MTE в userspace и ничего не говорит о том, тегирует ли ядро собственные выделения.


Апстрим / ссылки

Этот репозиторий — порт. Авторство цепочки эксплойта принадлежит апстриму.


Структура

root@kitploit:~
source/          ядро эксплойта (апстрим-попсикл + исправление kernel-MTE; см. warhol-mte-fix.patch)
  src/           main.c slide.c fops.c pipe.c util.c preload.c su_daemon.c + kernelsnitch/
targets/         сгенерированный target.h для каждой сборки, по одному каталогу на fingerprint x вариант прелоадера
  warhol-OS3.0.304.0.WPSJPXM/       PRELOADER=retail
  warhol-OS3.0.304.0.WPSJPXM-eng/   PRELOADER=eng
tools/
  payload_dump.py          извлечение разделов из A/B payload.bin (проверяет размер и sha256)
  kernel_banner.py         чтение баннера Linux из boot.img
  bootinfo.py              вывод полей заголовков boot / vendor_boot
  generate_target.py       генератор target.h; апстримный, только для MediaTek, плюс распаковка ядра
  preloader_memlayout.py   вывод/сравнение таблицы статических резервов DRAM прелоадера MediaTek
  lz4legacy.py             декомпрессор кадров LZ4 legacy (образы ядра)
out/             артефакты сборки (в gitignore)

Сборка

Ничего не собирается, пока не существует target.h — Makefile громко падает, а не выдаёт бинарник под неверное ядро.

root@kitploit:~
# 1. извлеките boot.img прямо из OTA-зипа (payload.bin хранится без сжатия,
#    поэтому --base ищет внутри зипа; распаковывать 7.6 ГБ заранее не нужно)
python3 tools/payload_dump.py <ota.zip> --base 5081 -p boot,vendor_boot,dtbo -o <dir>

# 2. подтвердите баннер ядра — на него завязано каждое смещение ниже
python3 tools/kernel_banner.py <dir>/boot.img
python3 tools/bootinfo.py <dir>/boot.img

# 3. сгенерируйте заголовок цели. --preloader читает физический адрес загрузки ядра
#    из резерва mb_kernel прелоадера; передавайте прелоадер, который запущен на телефоне.
python3 tools/generate_target.py \
  --boot <dir>/boot.img --dtb <dir>/vendor_boot.img --preloader <preloader.bin> \
  -o targets/warhol-OS3.0.304.0.WPSJPXM/target.h

# 4. сборка
make preload            # DEVICE=warhol-OS3.0.304.0.WPSJPXM, PRELOADER=retail по умолчанию

Если образа прелоадера под рукой нет, --kernel-phys-delta 0 — более старая форма и для этой прошивки даёт тот же заголовок, — но это утверждение, а не считывание, поэтому предпочтителен --preloader. Передача обоих заставляет генератор выполнить перекрёстную проверку и упасть при расхождении.

--base 5081 — это смещение локального заголовка payload.bin для этого конкретного OTA; для любого другого пакета возьмите его из ota-property-files в META-INF/com/android/metadata.

Требуются Android NDK (NDK_ROOT / ANDROID_NDK_HOME) и llvm-objdump.

Запуск

root@kitploit:~
# <device> — имя цели: <fingerprint> для PRELOADER=retail, <fingerprint>-eng для eng
adb push out/preload-<device>.so /data/local/tmp/preload.so
adb shell chmod 0644 /data/local/tmp/preload.so
adb shell "LD_PRELOAD=/data/local/tmp/preload.so /system/bin/true"
adb shell "/data/local/tmp/su -c id"

cred и состояние SELinux пропатчиваются в памяти, поэтому это нужно повторять после каждой перезагрузки. Разблокировка загрузчика не требуется.


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

Для исследований на оборудовании, которым вы владеете. Запуск может привести к циклу загрузки или «кирпичу» и аннулирует гарантию. Никаких гарантий любого рода.

Апстрим-проекты лицензированы их авторами; этот порт несёт их условия.

Скачать инструмент
ЭлементЗначениеИсточник
Кодовое имяwarholpre-device=warhol
СборкаXiaomi/warhol_global/warhol:16/BP2A.250605.031.A3/OS3.0.304.0.WPSJPXM:user/release-keyspost-build
ИнкрементальнаяOS3.0.304.0.WPSJPXM (глобальная JP)post-build-incremental
Android16, SDK 36post-sdk-level=36
Патч безопасности2026-05-01post-security-patch-level
Тип OTAA/B (payload.bin, CrAU, 39 разделов)ota-type=AB
SoCMediaTek MT6993 (Dimensity 9500)совместимые mediatek,mt6993-* в DTB из vendor_boot; cmdline bootopt=64S3,32N2,64N2
Ядро6.12.38-android16-5-g1d46253471dd-ab15048002-4k, clang 19.0.1баннер, считанный из извлечённого boot.img
boot-образзаголовок v4, ядро 18 898 125 Б, сжатие LZ4-legacy, без ramdisktools/bootinfo.py
PRELOADER=Прелоадер на телефонеЦелевой каталогСтатус
retail (по умолчанию)штатный preloader_<device>.bin, побайтно идентичный preloader_raw.img из fastboot-прошивкиtargets/warhol-OS3.0.304.0.WPSJPXM/✅ проверено на устройстве 2026-07-26
engинженерная сборка, preloader_<device>_eng.bintargets/warhol-OS3.0.304.0.WPSJPXM-eng/✅ проверено на устройстве 2026-07-26
ФайлИзменениеПочему
src/util.ckernelsnitch_setup(..., mte_enabled=1)при 0 поиск mm_struct пробует только кандидатов без тегов и никогда не достигает тегированного указателя — это структурный промах, а не невезение
src/util.cis_kernel_ptr() / is_direct_ptr() снимают тег перед проверкой диапазонаиначе тегированный указатель, считанный из памяти ядра, отклоняется как не находящийся в линейной карте (direct-entry-fatal reason=bad-task-or-cpu)
src/kernelsnitch/kernelsnitch.hпроход по тегам < 15 → < 16тег 0xf и есть указатель без тега / match-all, поэтому проход теперь покрывает и ядро без MTE — mte_enabled=1 безопасен в любом случае
РепозиторийРоль здесь
https://github.com/MobiusM/CVE-2026-43499Оригинальный PoC / триггер краха CVE-2026-43499
https://github.com/x-spy/CVE-2026-43499-popsicleОснова этого порта. Xiaomi 17 Pro Max (popsicle), ядро 6.12.23-android16-5; source/ и tools/generate_target.py взяты отсюда
https://github.com/Kananosa/CVE-2026-43499-For-Xiaomi-17T-chagallБлижайшее родственное устройство (Xiaomi 17T, chagall, тоже MediaTek). Происходит от попсикла, поставляет готовый preload.so — его вкомпилированные константы подтвердили физическое смещение загрузки
https://github.com/MiCode/Xiaomi_Kernel_OpenSourceИсходники ядра Xiaomi для перекрёстной проверки раскладки структур