
CVE-2026-43499 Exploit-Adapter für MT6985 MediaTek Dimensity 9300 (vivo PD2241)
Fazit: 68M Tokens investiert, kein Root erhalten.
Ursache: KernelSnitch-Timing-Angriff auf MTK Dimensity 9200 unzuverlässig,CONFIG_PANIC_ON_OOPS=ylässt keinen Raum für Trial-and-Error.
Dieser Artikel dokumentiert den vollständigen Fehlschlag-Prozess als Referenz für Nachfolger.
| Projekt | Wert |
|---|
| Gerät | vivo PD2241 (Dimensity 9200 / MT6985), Android 15 |
| Firmware | PD2241_A_15.2.10.2.W10.V000L1 |
| Kernel | 5.15.178-android13-8-gfb31f5bdd612-dirty |
| Bootloader | Gesperrt (ro.boot.flash.locked=1) |
| SELinux | Enforcing |
| panic_on_oops | Aktiv → jeder Kernel-OOPS = sofortiger Neustart |
| Exploit | CyberMeowfia — CVE-2026-43499 (IonStack) |
| Quellbaum | android_15.0_kernel_MT6985 (5.15.178) — nicht passend zur Geräteversion (Quelle ist android15 GKI, Gerät läuft android13 GKI) |
Extrahiert aus arch/arm64/include/asm/memory.h + include/linux/fs.h + android/abi_gki_aarch64.xml:
KIMAGE_TEXT_BASE = 0xffffffc008000000, VA_BITS=39, DIRECT_MAP=256GBlayout-offset-in-bits)iopoll (android13 GKI), IOCTL=0x48, open=0x68atomic_t usage = 4 Bytes, uid=0x04slab_cache=0x18Wichtige Erkenntnis: Quelle ist android15 GKI, Gerät ist android13 GKI — task_struct-Offsets weichen um 0x40~0x88 Bytes ab, können nicht direkt aus der Quelle übernommen werden.
OTA zip (8.3GB)
→ payload.bin (8.2GB)
→ payload_dumper → boot.img (96MB, v4 header)
→ LZ4 entpacken → Image (50MB ARM64)
→ kallsyms-finder → 187810 Symbole
Symbole aus zwei Firmware-Versionen (15.2.7.6 / 15.2.10.2) extrahiert — dasselbe Symbol weicht zwischen den Versionen um 10KB~200KB ab, die richtige Version muss verwendet werden.
# In rt_mutex_adjust_pi:
LDR x21, [x19, #0x8b0] → pi_blocked_on = 0x8b0 (android15-Wert, nicht frankel)
Dies bestätigt, dass das task_struct-Layout dem android15-Zweig entspricht, nicht frankels android13.
NDK r29, make PROJECT=android_15.0_kernel_MT6985 → preload.so (150KB).
[+] preload starting pid=25414
[+] p0 profile ... alle Symbole korrekt geladen
[-] KernelSnitch mm_struct leak failed ← manchmal fehlt diese Zeile (gelegentlich erfolgreich)
[+] slide child context route=pselect ← slide KASLR-Leak-Subprozess gestartet
[Kernel-Panic] ← rt_mutex_adjust_prio_chain+0x1b0
Absturz-Instruktion (capstone):
ldar w8, [x27] ; x27 = waiter->lock (geladen aus [x28, #0x38])
; x27-Wert ist Müll → keine Seitentabellen-Zuordnung → Translation Fault
; → die() → panic → Neustart
KernelSnitch ist der Einstiegspunkt des gesamten Exploits — es leakt die mm_struct-Adresse über Timing-Unterschiede im futex-Hash-Bucket:
MT6985 hat CONFIG_KASAN_HW_TAGS=y → Kernel markiert Slab-Allokationen mit MTE-Tags
mm_struct-Zeiger tragen KASAN-Tag → futex_hash basiert auf getaggtem Pointer
Aber Bruteforce scannt direct map (untagged Adressen) → berechneter Hash stimmt nicht überein
Selbst mit MTE-Tag-Durchlauf (0-14, insgesamt 15 Varianten), auf Systemen mit VA_BITS=39
überlappen Tag-Bits (bit56-59) mit Vorzeichenerweiterungs-Bits → einige Tag-Kombinationen
erzeugen ungültige Adressen → werden übersehen
Pixel-Geräte haben kein KASAN_HW_TAGS, dort funktioniert dieser Mechanismus. MTK nicht.
CONFIG_PANIC_ON_OOPS ist der KillerPixel: Kernel-OOPS → dump_stack → weiterlaufen → Exploit kann es erneut versuchen
MT6985: Kernel-OOPS → die() → panic() → sofortiger Neustart → kein Raum für Trial-and-Error
Eine kleine Abweichung in der π-Kette bringt alles zum Absturz; auf Pixel wäre eine Abweichung
nur "diesmal nicht erfolgreich, andere Adressgruppe erneut versuchen".
Zudem ist der Bootloader gesperrt (flash.locked=1) → kein Flashen eines benutzerdefinierten Kernels möglich, um diese Option zu entfernen.
Quellbaum: 5.15.178 android15 GKI
Gerät: 5.15.178-android13 (vivo vendor)
Obwohl die Hauptversionsnummern beide 5.15.178 sind, unterscheiden sich die GKI-Zweige (android13 vs android15), wodurch die Layouts kritischer Strukturen wie task_struct/cred inkonsistent sind. Nach wiederholtem Wechsel zwischen frankel/android15-Offset-Sätzen wurde die korrekte Version letztlich per Disassemblierung bestimmt.
| Änderung | Zweck | Ergebnis |
|---|---|---|
THRESHOLD_MULT 10→5→3 | Kollisionserkennungsschwelle senken | <5 zu viele False Positives |
APPENDED_FUTEXES 4096→8192 | Hash-Ketten-Differenz vergrößern | Keine Wirkung |
REPEAT_MEASUREMENT/AVERAGE | Messgenauigkeit erhöhen | Keine Wirkung |
MTE=1 | Bruteforce Tags durchlaufen lassen | Langsamer, Abstürze sogar reduziert |
MM_STRUCT_SZ 0x500→0x400 | mm_struct-Schrittweite korrigieren | Notwendig, ABI tatsächlich 992 Bytes |
IDENTITY_END 64GB→256GB | Scan-Bereich erweitern | Zu langsam (MTE-Durchlauf), stimmt weiterhin nicht überein |
| TASK-Offsets: android15↔frankel | Korrekte Offsets ermitteln | Disassemblierung bestätigt android15 |
| FOPS-Offsets: android15↔frankel | android13 hat kein iopoll | frankel verwendet |
In exploit/targets/android_15.0_kernel_MT6985/target.h:
| Kategorie | Vertrauensgrad | Verifikationsmethode |
|---|---|---|
| Speicherlayout | Korrekt | memory.h-Berechnung + kallsyms _text-Verifikation |
| Symbol-Offsets (22) | Korrekt | Aus 15.2.10.2 boot.img extrahiert |
| task_struct-Offsets | Korrekt | ABI XML + capstone-Disassemblierung (pi_blocked_on=0x8b0) |
| FOPS-Offsets | Fehlerhaft (am 2026-07-31 korrigiert) | Ursprünglich von frankel übernommen (android13 ohne iopoll); Quellbaum-ABI hat tatsächlich iopoll@0x30, ioctl=0x50, open=0x70 — siehe VERIFICATION.md |
| CRED-Offsets | Korrekt (verifiziert) | ABI XML: uid=0x04, securebits=0x24, caps=0x28, security=0x78 |
Assemblierung erfolgreich, läuft, scheitert auf der letzten Meile.
CONFIG_PANIC_ON_OOPS entfernen — entweder benutzerdefinierten Kernel flashen (Bootloader-Entsperrung erforderlich) oder ein MT6985-Gerät finden, bei dem diese Option standardmäßig deaktiviert ist/proc/self/pagemap — auf diesem Gerät eingeschränkt (gibt nur Nullen zurück)/proc/mtk_*) — vorhanden, aber weitere Analyse erforderlichsymbols/kallsyms_PD2241_15.2.10.2.txt — vollständige 15.2.10.2-Symboltabelle, direkt für Nachfolger nutzbardevice_config.txt — tatsächliche Kernel-Konfiguration des Geräts, zeigt Vendor-Änderungenexploit/targets/android_15.0_kernel_MT6985/target.h — Struktur-Offsets verifiziertscripts/server_compile.py — automatisierte Kompilierung, schnelle Neukompilierung nach Parameteränderungentar -xf kann bei großen ZIPs fehlschlagen, Python zipfile verwenden oder manuell zuerst entpackenupdate_metadata_pb2.py erfordert protobuf 5.x, die runtime_version-Importzeile muss manuell entfernt werden./preload.so führt zu Segfault: /system/bin/linker64 /data/local/tmp/preload.so muss verwendet werdenlayout-offset-in-bits wird vom Compiler berechnet, 100× genauer als manuelles Zählen über 5000 BytesCONFIG_ANDROID_VENDOR_OEM_DATA=y, CONFIG_SCHED_INFO=y, CONFIG_RSC_* → Abweichung vom Standard-GKIboot.img → kernel.bin → LZ4 entpacken → Image → kallsyms-finder → Symboltabelle07/28 CyberMeowfia-Repo + MT6985-Quellcode heruntergeladen
07/29 Quellcode-Analyse (memory.h, fs.h, ABI XML, diverse structs)
Firmware-Entpackung (payload.bin → boot.img → Image)
Symbol-Extraktion (kallsyms-finder → 187810 Symbole)
Mehrere Kompilierungsrunden + mehrere Abstürze + Disassemblierungs-Verifikation
5 automatische Wiederholungen → alle fehlgeschlagen
Dieser Artikel geschrieben
-------------------------------------------
Gesamt: ~68M Tokens, 0 Root-Shells
2026-07-29, lived to tell the tale
Nach Erhalt von android_15.0_kernel_MT6985.tar.gz (5.15.178-Quellbaum + ABI XML) wurde eine
vollständige Kreuzvalidierung durchgeführt, Details in VERIFICATION.md. Zusammenfassung:
target.h korrigiert, zusätzlich mit der im Exploit
enthaltenen leak_kernel_base()-Selbstverifikation auf dem echten Gerät als Absicherung.KSNITCH_MTE_ENABLED=1 tatsächlich
wirksam gemacht (original util.c hatte mte=0 hartkodiert);rt_mutex_adjust_prio_chain+0x1b0 liegt in der pselect/pi-Kettenphase, vor der
FOPS-Selbstverifikation; nach den obigen Korrekturen ist eine erneute Verifikation auf dem Gerät sinnvoll.Gerät (PD2241, compiler251203103903) mit 8+ Testrunden auf echter Hardware:
MM_STRUCT_SZ=0x400 (ursprünglich 0x500 führte zu
versetztem Scan-Raster und nur False Positives) + MTE-Tag-Durchlauf 0..15 (Geräte-mm-Pointer-Tags
ändern sich) + Untagging gefälschter Adressen. Findet jetzt stabil echte mm_struct.rt_mutex_adjust_prio_chain+0x1b0 ab: pselect/pi-Ketten-
Timing-Race (gefälschter waiter landet nicht am korrekten Offset im Kernel-Stack). Der vivo-RSC-
Scheduler hat den futex/pi-Pfad verändert, was dieses Race grundlegend zerstören könnte. Die
Slide-Stack-Ausrichtung wurde als Umgebungsvariable SLIDE_SHIFT parametrisiert, Scan noch nicht abgeschlossen.Endgültige Entscheidung: kostenpflichtige Bootloader-Entsperrung (nicht mehr von diesem Pfad abhängig).