
# GhostLock (CVE-2026-43499) Kernel-Exploit für Android-Geräte mit gesperrtem Bootloader
Kernel-Exploit für Android-Geräte mit gesperrtem Bootloader. Erreicht temporären Root + KernelSU-Installation, ohne den Bootloader zu entsperren oder das Boot-Image zu modifizieren. Laufzeit-Auto-Erkennung der Kernel-Version mit Multi-Geräte-Offset-Tabelle.
CVE-2026-43499 — Futex PI (Priority Inheritance) Use-After-Free
Betrifft Linux-Kernel 5.7 ~ 7.1. Behoben in Stable 6.1.175, 6.6.140, 6.12.86. Die meisten Android-Geräte sind Stand September 2026 weiterhin ungepatcht.
Der pselect6-Syscall kopiert fd_set-Daten auf den Kernel-Stack. In Kombination mit dem Futex-PI-Waiter-Mechanismus kann ein freigegebener Stack-Frame als rt_mutex_waiter-Struktur zurückgewonnen werden. Das rb-tree-Rebalancing während des PI-Chain-Walks schreibt dann kontrollierte Werte an beliebige Kernel-Adressen.
Das pselect-Stack-Overlay erfordert, dass der freigegebene rt_mutex_waiter innerhalb des benutzerkontrollierten stack_fds-Bereichs (Wörter 0–14) landet. Wo er landet, wird durch Compiler-PGO/LTO-Profile bestimmt, nicht durch die Kernel-Version. Siehe Stack-Layout.
Hinweis zur 6.1-Durchführbarkeit: OPLUS-6.1-Kernel sind durchgängig nicht durchführbar, da PGO
do_futexinlined. Einige Nicht-OPLUS-6.1-Kernel (vivo) behalten jedoch die Standard-Call-Chain bei und sind durchführbar (vivo T4, X Fold3 Pro). Die Durchführbarkeit muss pro Gerät geprüft werden.
Zwei Root-Pfade, automatisch basierend auf den Gerätefähigkeiten ausgewählt:
Erfordert off_ashmem_misc_fops != 0 (C-ashmem mit statischem miscdevice in BSS).
PI-Write (mode=4) → miscdevice-fops auf Fake-fops umleiten
→ configfs r/w → pipe physrw (1-Byte-präzises Kernel-r/w)
→ SELinux enforcing = 0 (einzelnes Byte, keine policycap-Korruption)
→ UMH: work_struct in system_unbound_wq injizieren
→ Root-Skript → ksud late-load → KSU installiert
Verfügbar auf: OnePlus 13, OPPO Pad 4 Pro, 5.10/6.1 C-ashmem-Geräten. Nicht verfügbar auf Rust-ashmem (6.12 GKI) — Heap-alloziertes miscdevice.
Write 1 (mode=1) → SELinux enforcing = 0 (8-Byte-Write, korrumpiert angrenzende Bytes)
Write 2 (mode=2) → task->cred = init_cred (uid=0, alle Capabilities)
Root-Shell → ksud late-load → KSU → SELinux-Policy-Fix
Nach W1+W2 patcht der Exploit das Config-Feld der SELinux-Policy-Binärdatei (|= 0xC0000000 für ANDROID_NETLINK_ROUTE + GETNEIGH) und lädt es über /sys/fs/selinux/load neu, um die Netzwerkkonnektivität wiederherzustellen.
App (seccomp) → Write 1 → Mini-ADB-TCP → adb shell: vollständiger Exploit → Root
Der Bootzeit-Launcher wird von der separaten GhostLock Anchor App bereitgestellt.
Mit NFDS=320 alloziert core_sys_select einen 256-Byte-stack_fds-Puffer auf dem Kernel-Stack:
stack_fds: 0 5 10 14 | 15 20 25 29
├─in─┤─out─┤─ex──┤ ├res_in┤res_out┤res_ex┤
◄── BENUTZERKONTROLLIERT ──►│◄── KERNEL GENULLT ──►
Der Exploit platziert Fake-Waiter-Felder (task, lock) in den fd_set-Eingabe-Bitmaps. Für 6.12 Nested-Waiter (14 Wörter): maximal durchführbares Waiter-Wort = 3. Für 5.10/6.1 Compact-Waiter (10 Wörter): maximal durchführbares Waiter-Wort = 7.
Die Waiter-Position hängt von der Call-Chain-Tiefe ab:
Alle Kernel-Writes verwenden den Linear-Map-Alias. Der Bootloader wählt kernel_phys_load, das je nach SoC variiert:
| SoC | kernel_phys_load |
|---|---|
| SM8845 (Ace 6T, 15T) | 0xa8000000 |
| SM8750 (OnePlus 13, OPPO Pad 4 Pro) | 0xa8000000 |
Ein falscher Wert schlägt still fehl. Auf einem gerooteten Gerät auslesen:
su -c 'grep -i "Kernel code" /proc/iomem' # c7810000-... → 0xc7800000
Zur Laufzeit überschreiben: KPHYS=0xc7800000 /data/local/tmp/a/e
/data/local/tmp/a/e # Standard (shift=0)
PSELECT_SHIFT=-2 /data/local/tmp/a/e # OnePlus 13 (6.6)
5.10-Kernel verwenden 0xffffffc008000000 (VA_BITS=39, abweichend vom 6.x-Standard 0xffffffc080000000). Dies wird automatisch über das Feld kimage_text_base im Geräte-Offset-Eintrag behandelt.
make NDK_ROOT=/pfad/zu/android-ndk
Oder direkt:
NDK=/pfad/zu/android-ndk
"$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang" \
-O2 -Wall -Isrc/core -Isrc/devices -DTARGET_CONFIG_H=\"target.h\" \
src/core/main.c src/core/util.c src/core/slide.c \
src/core/fops.c src/core/pipe_physrw.c src/core/root.c \
src/core/miniadb.c src/core/umh_root.c \
-o ./ghostlock -fPIE -pie -pthread
GhostLock stellt temporären Root bereit. Die KernelSU-Installation erfordert ksud, das kernelsu.ko für jede KMI-Version bündelt.
| Methode | Schritte |
|---|---|
| ReSukiSU-APK (empfohlen) | ReSukiSU oder diesen installieren. Bündelt . |
adb shell mkdir -p /data/local/tmp/a
adb push ./ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
adb shell /data/local/tmp/a/e
Nach Abschluss des Bootvorgangs ausführen, sobald ADB bereit ist.
Nur boot.img wird benötigt — kein Root, kein Gerätezugriff erforderlich.
Siehe kallsyms-Tools-Anleitung für den vollständigen Workflow, oder:
python tools/extract_target.py --kallsyms kallsyms.txt
python tools/extract_btf.py kernel
Prüfen, ob do_futex PGO-inlined ist, indem die Kernel-Binärdatei nach allen Branch-Instruktionen durchsucht wird, die auf futex_wait_requeue_pi abzielen. Wenn __arm64_sys_futex es direkt aufruft (unter Umgehung von do_futex), ist das Gerät wahrscheinlich nicht durchführbar.
src/devices/<name>/offsets.h mit den extrahierten Offsets hinzufügen und in src/devices/offsets.h einbinden. Das passende Struct-Offsets-Makro verwenden:
Für 5.10/6.1-Compact-Waiter-Geräte zusätzlich .kimage_text_base=0xffffffc008000000ULL setzen.
Nur für autorisierte Sicherheitsforschung und Bildungszwecke.
| Gerät | SoC | Kernel | GKI-Branch | SHIFT |
|---|
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38 | android16-5 | 0 |
| OnePlus 15 (CPH2745/2747/2749) | SM8850 | 6.12.23 | android16-5 | 0 |
| Xiaomi 17 (pudding) | SM8850 | 6.12.23 / 6.12.69 | android16-5 / android16-6 | 0 |
| OnePlus 13 (IN2060) | SM8750 | 6.6.89 | android15-8 | -2 |
| OPPO Pad 4 Pro | SM8750 | 6.6.89 | android15-8 | -2 |
| Gerät | SoC | Kernel | Hinweise |
|---|
| OnePlus 15T (PLZ110) | SM8845 | 6.12.38 | Gleicher Kernel wie Ace 6T |
| OPPO Reno10 Pro+ (CPH2521) | SM8475 | 5.10.236 | 5.10 Compact-Waiter, Waiter-Wort=0 |
| Vivo X Fold3 Pro (PD2337) | SM8650 | 6.1.124 | 6.1 Compact-Waiter, Waiter-Wort=3 |
| Vivo T4 | SM8650 | 6.1.145 | 6.1 Compact-Waiter, Waiter-Wort=3 |
| Gerät | SoC | Kernel | Ursache |
|---|
| OPPO Find X9 Ultra | SM8750 | 6.12.58 | PGO eliminiert do_futex → Waiter-Wort=14 |
| OnePlus 12 | SM8650 | 6.1.141 | PGO inlined do_futex → Waiter-Wort=13/19 |
| OnePlus 13R / Ace 5 | SM8650 | 6.1.x | OPLUS 6.1: Waiter-Wort=13 |
| realme RMX5070 | SM6650 | 6.1.141 | OPLUS 6.1: Waiter-Wort=13 |
| OPPO Pad 5 (OPD2502) | MT6878 | 6.1.134 | OPLUS 6.1: Waiter-Wort=13 |
| Motorola Edge 60 Fusion | MT6878 | 6.1.145 | Nicht-OPLUS 6.1: gleiches Ergebnis |
| iQOO Neo 10 CN | SM8650 | 6.1.84 | do_futex-Frame 0xD0 → Waiter-Wort=-11 |
| OPPO PKW110 | — | 5.15.180 | do_futex-Frame 0x140 → Waiter-Wort=-29 |
| iQOO Z9 5G | — | 5.15.178 | do_futex-Frame zu groß |
| CPH2763 (OPPO) | — | 6.1.115 | OPLUS 6.1: PGO inlined, Waiter-Wort=24 |
| Muster | Call-Chain | Durchführbar |
|---|
| android16-5 (6.12) | sys_futex → do_futex → fwrpi | ✅ Waiter-Wort=2 |
| android15-8 (6.6) | sys_futex → do_futex → fwrpi | ✅ Waiter-Wort=2 (SHIFT=-2) |
| vivo 6.1 | sys_futex → do_futex → fwrpi | ✅ Waiter-Wort=3 |
| OPLUS 6.1 | sys_futex → fwrpi (PGO inlined) | ❌ Waiter-Wort=13+ |
| android16-6 (X9 Ultra) | sys_futex → fwrpi (PGO inlined) | ❌ Waiter-Wort=14 |
| 5.10 OPLUS | sys_futex → do_futex → fwrpi | ✅ Waiter-Wort=0 |
| SM8650 (vivo T4, X Fold3 Pro) |
0xa8000000 |
| SM8850 (OnePlus 15, Xiaomi 17) | 0xc7800000 |
libksud.so| CI-Release | Von ReSukiSU CI herunterladen |
| Kernel | Waiter-Layout | Makro |
|---|
| 6.12.x | Nested (14 Wörter) | STRUCT_OFFSETS_6_12 |
| 6.6.x | Nested (14 Wörter) | STRUCT_OFFSETS_6_6 |
| 6.1.x (vivo) | Compact (10 Wörter) | STRUCT_OFFSETS_6_1 |
| 5.10.x | Compact (10 Wörter) | STRUCT_OFFSETS_5_10 |
| Datei | Beschreibung |
|---|
src/core/main.c | Exploit-Einstieg, W1/W2, UMH-Pfad, Bootstrap, Root-Skript, SELinux-Policy-Fix |
src/core/fops.c | pselect-Route, PI-Write, CFI-Stufe, Compact-Waiter-Unterstützung |
src/core/util.c | Heap-Spray, KernelSnitch, Slab-Drain, Payload-Setup |
src/core/pipe_physrw.c | Pipe-Puffer-Physikalischer-Speicher-r/w |
src/core/umh_root.c | UMH-Root über Workqueue-Injektion |
src/core/miniadb.c | Mini-ADB-Client (TCP + RSA-Auth) |
src/core/target.h | Speicherlayout, Struct-Feld-Standardwerte (6.12) |
src/core/runtime_struct_offsets.h | Gerätespezifische Struct-Feld-Überschreibung |
src/devices/offsets.h | Geräte-Offset-Tabellen + STRUCT_OFFSETS_*-Makros |
tools/extract_target.py | Offset-Extraktion aus kallsyms |
tools/extract_btf.py | Struct-Offset-Extraktion aus BTF |
tools/kallsyms/ | End-to-End-kallsyms-Wiederherstellungs-Workflow |