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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-43499-pmg110-root — Эксплойт Android LPE для CVE-2026-43499, нацеленный на OPPO PMG110 (ядро 6.6). Использует futex PI UAF для получения root-прав и установки su-демона через LD_PRELOAD. | Kitploit
Инструменты/GitHubGitHub/soralis0912/cve-2026-43499-pmg110-root
Безопасность AndroidПовышение привилегийАнализ уязвимостейЭксплуатацияПост-эксплуатацияТестирование на ПроникновениеМобильная безопасностьRed TeamingРазработка Полезной Нагрузки

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
Эксплуатация Бинарных Файлов
GitHubsoralis0912/cve-2026-43499-pmg110-root

CVE-2026-43499-pmg110-root

Эксплойт Android LPE для CVE-2026-43499, нацеленный на OPPO PMG110 (ядро 6.6). Использует futex PI UAF для получения root-прав и установки su-демона через LD_PRELOAD.

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

pmg110-root

Локальное повышение привилегий через CVE-2026-43499 (use-after-free в futex PI rt_mutex_waiter), портированное на OPPO PMG110 / K15 Pro+ — MediaTek MT6991, ColorOS 16.

Загружается один файл, запуск через LD_PRELOAD:

adb push out/preload-pmg110-16.0.9.400.so /data/local/tmp/preload.so
adb shell chmod 644 /data/local/tmp/preload.so
adb shell LD_PRELOAD=/data/local/tmp/preload.so /system/bin/true

В случае успеха на устройстве остаётся постоянный su:

adb shell /data/local/tmp/su -c id      # uid=0(root)

Проверено на устройстве (2026-07-27): uid=0 примерно за 35 секунд при «чистом» запуске без переопределений окружения, и su затем отвечает из обычного непривилегированного adb shell:

$ adb shell "/data/local/tmp/su -c 'echo 0 > /proc/sys/kernel/kptr_restrict'"
$ adb shell "/data/local/tmp/su -c 'grep -w init_task /proc/kallsyms'"
ffffffe89033e780 D init_task

Эксплойт и установка su проверены на этом устройстве. То, что затем считала рутированная оболочка, также подтверждает P0_KERNEL_PHYS_LOAD, смещения символов и KS_MTE_TAGGED=0 независимо от эксплойта — см. targets/pmg110-16.0.9.400/NOTES.md.

УстройствоOPPO PMG110 / K15 Pro+ / OP61E5L1
SoCMediaTek MT6991 (Dimensity 9500s)
Ядро6.6.118-android15-8-g93e223c276e7-abogki500782043-4k (GKI, страницы 4K)
ПрошивкаColorOS 16 / PMG110_16.0.9.400(CN01) — те же байты ядра, что и в 16.0.8.300
ОшибкаCVE-2026-43499, не исправлена в этом образе (показано дизассемблированием, а не версией)

Что делает и чего не делает

Он выполняет Write 1 (SELinux permissive) и Write 2 (cred → init_cred), переводит дочерний процесс в uid=0 и оттуда устанавливает встроенный демон su.

  • по-прежнему загружается один файл. su — не второй артефакт: su_daemon.c собирается как отдельный aarch64 PIE и через .incbin встраивается в .rodata библиотеки, поэтому он находится внутри preload.so и записывается обратно во время выполнения. Путь warhol-root, без изменений.
  • нет root-скрипта, нет ksud, нет KernelSU
  • вызывающий процесс остаётся непривилегированным — он получает root, обращаясь к демону, и то же самое вы будете делать из оболочки потом
  • SELinux остаётся в режиме permissive, как это делает warhol-root: демон должен обслуживать непривилегированных клиентов через свой сокет. Перезагрузка вернёт enforcing.

su устанавливается в трёх местах, потому что одно из них — то, до которого вы действительно доберётесь:

ПутьЗачем
/apex/com.android.virt/bin/suна tmpfs, смонтированной поверх этого каталога; в PATH для root-оболочки
/data/local/tmp/suдоступен из обычного adb shell без игр с PATH
/apex/com.android.virt/bin/su в mount namespace adbdустанавливается через setns, поэтому новый adb shell его видит

Демон слушает /data/local/tmp/temp_su.sock и пишет лог в /data/local/tmp/su_daemon.log. Root не сохраняется после перезагрузки — повторно запускайте команду с LD_PRELOAD после каждой загрузки.

Для установки KernelSU используйте вместо этого маршрут /data/local/tmp/a/e в ghostlock-oneplus.

Связь с warhol-root

Всё, кроме ядра эксплойта, принадлежит warhol-root — взято, а не изобретено заново:

  • структура — заголовки для каждого устройства в targets/<device>/, размещаемые в source/src/ во время сборки, так что переключение DEVICE никогда не оставит позади заголовки предыдущего устройства
  • сборка — выбор тулчейна в source/Makefile (NDK, если он есть, иначе хост-clang против sysroot NDK) и двухэтапное правило встраивания, которое создаёт build/embed/su_daemon_aarch64_pie перед линковкой .so
  • путь su — su_daemon.c и su_blob.S побайтно идентичны warhol-root, а su_install.c — это его установщик из preload.c

Ядро эксплойта — не warhol-root. warhol-root — это popsicle, привязанный к GKI 6.12 / android16, и его generate_target.py отвергает любой другой баннер. У PMG110 — 6.6 / android15, поэтому ядро здесь — это дерево ghostlock 6.6, само являющееся потомком того же кода (kernelsnitch/utils.h и timeutils.h побайтно идентичны между двумя репозиториями) и получившее дальнейшее развитие.

ФайлПроисхождение
util.c slide.c fops.c pipe.c root.c miniadb.c common.h offset.h kernelsnitch/*ghostlock, побайтно идентично
su_daemon.c su_blob.Swarhol-root, побайтно идентично (su_blob.S добавляет две строки .hidden — см. «Сборка»)
su_install.cустановщик warhol-root из preload.c, вынесен в отдельный файл, потому что preload.c в этом дереве уже выполняет другую работу
main.cghostlock, плюс вызов su в рутированном дочернем процессе и отчёт о результате
preload.cтолько здесь — конструктор и лог с двумя приёмниками
offsets.hтолько определение структуры; запись размещается из targets/<device>/device_offsets.h

Каждая строка собственно эксплойта — Write 1, Write 2, KernelSnitch, маршрут pselect — это один и тот же код в обоих деревьях.

Откуда вызывается установка su

Это единственное структурное различие, и оно обусловлено тем, что два дерева получают root по-разному.

warhol-root рутит сам процесс эксплойта и потому вызывает install_embedded_su() напрямую из run_direct_root(). Здесь Write 2 подменяет указатель cred у форкнутого дочернего процесса, а родитель остаётся непривилегированным вызывающим, поэтому дочерний процесс в child_main() — единственный контекст, который может выполнить установку, — именно там он и запускается.

Оба дерева несут одну и ту же слабую заглушку install_embedded_su() в util.c, возвращающую ENOSYS; именно сильное определение включает этот маршрут. Это стоит знать, потому что сборка, в которой по какой-то причине теряется su_install.c, по-прежнему линкуется и запускается — просто сообщает su=0/38 и ничего не устанавливает.

Сборка

make                      # = make preload -> out/preload-<DEVICE>.so
make DEVICE=<name>        # use targets/<name>/
make devices              # list available DEVICE values
make info                 # show the selected target and the resolved toolchain

Тулчейн находится автоматически: сначала ANDROID_NDK_HOME / ANDROID_NDK_ROOT, затем обычные места установки NDK для Linux и macOS, а если ничего из этого не нашлось — хост-clang, нацеленный на sysroot NDK. Устанавливайте ANDROID_NDK_HOME только для переопределения поиска. make info выводит, что было выбрано.

Сборка двухэтапная — вот что стоит знать:

  1. su_daemon.c → build/embed/su_daemon_aarch64_pie — отдельный aarch64 PIE
  2. su_blob.S через .incbin встраивает этот бинарник в .rodata, и всё это линкуется в единый preload.so

Поэтому make clean и пересборка — единственный способ изменить встроенный su: достаточно отредактировать один su_daemon.c, зависимость объявлена, но блоб — артефакт сборки и не отслеживается.

targets/<device>/{target.h,device_offsets.h} заново размещаются в source/src/ при каждой сборке, так что устаревший заголовок от другого устройства не может быть молча подхвачен.

out/*.so не отслеживается (та же договорённость, что и в warhol-root) — клонируйте и запускайте make.

.so собирается с флагом -fvisibility=hidden и экспортирует ноль символов. Библиотека LD_PRELOAD выигрывает поиск символов для всего процесса, поэтому всё, что она экспортирует, может затенять одноимённый символ в хост-бинарнике или в libc. Этот флаг управляет только генерацией кода C, поэтому su_blob.S помечает свои два символа .hidden вручную — без этих строк границы блоба были бы единственным, что библиотека по-прежнему экспортировала.

Переменные окружения

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