Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-43499-S26 — Android GKI 6.12 Kernel-Exploit für CVE-2026-43499, der einen rt_mutex-Rollback-Bug mit pselect-Stack-Overwrite verkettet, um Root auf Samsung- und Pixel-Geräten zu erlangen. | Kitploit
Tools/GitHubGitHub/sammyenigma/cve-2026-43499-s26
Android-SicherheitPrivilege EscalationSpeicherforensikPersistenzmechanismenExploitationReverse EngineeringShellcodePost-ExploitationMobile Sicherheit

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Payload-Entwicklung
Binary-Exploitation
GitHubsammyenigma/cve-2026-43499-s26

CVE-2026-43499-S26

Android GKI 6.12 Kernel-Exploit für CVE-2026-43499, der einen rt_mutex-Rollback-Bug mit pselect-Stack-Overwrite verkettet, um Root auf Samsung- und Pixel-Geräten zu erlangen.

Repository anzeigen
1vor 22 TagenNoch nicht geprüft

CVE-2026-43499 — Android GKI 6.12 pselect / configfs Kernel-Exploit

Ein Linux-Kernel-Exploit für die Android-GKI 6.12-Linie (Samsung- und Pixel- Geräte), der auf CVE-2026-43499 abzielt: einen fehlerhaften remove_waiter()-Rollback in rt_mutex_start_proxy_lock(), der current statt waiter::task verwendet und dadurch pi_blocked_on eines Waiters auf seinen (später entfernten) Kernel-Stack rt_mutex_waiter zeigen lässt. In Kombination mit einem pselect()-fd_set-Stack-Overwrite und einem konsumierenden, durch sched_setattr angetriebenen Fake-rb_tree-Durchlauf ergibt sich ein deterministisches Kernel-Schreibprimitiv und vollständiges Root.

Der Exploit läuft als LD_PRELOAD-Shared-Library (preload.so) und installiert einen Root-su-Daemon sowie ein Wallpaper als Post-Root-Artefakte.

Status: aktive Entwicklung. Das m1q-Ziel (ZF1) ist der Bring-up-Fokus. Der pipei tmp_page-uname-Bootstrap ist die aktuell aktive Route: Der Walk ist auf dem Gerät als sauber nachgewiesen (Build #33: pro-Kind geseedete rt_mutex-Regionen) und der vollständige 168-Kandidaten-Sweep läuft. Die configfs-CFI-Route ist eine Sackgasse auf m1q (Rust-Ashmem — kein injizierbarer fops-Slot) und bleibt die Route für C-Ashmem-Ziele. Die Offsets pro Ziel variieren je nach Gerät — vor dem Vertrauen gegen das tatsächliche Kernel-Binary verifizieren.

Verwundbares Primitiv (CVE-2026-43499)

Wenn FUTEX_CMP_REQUEUE_PI einen Waiter requeued und der Deadlock-Erkennungs- Kettendurchlauf des Requeues -EDEADLK zurückgibt, rollt __rt_mutex_start_proxy_lock() über remove_waiter() (rtmutex.c:1535) zurück. Der Rollback dequeued den Waiter korrekt aus dem Wait-Tree, löscht aber das pi_blocked_on des Requeue-Aufrufers statt waiter->task->pi_blocked_on. Das pi_blocked_on des WAITERS bleibt baumelnd an seinem Stack-rt_mutex_waiter, der entfernt wird, sobald der Futex timeoutet.

Nach dem Timeout wird die Kernel-Stack-Region des Waiters wiederverwendet: core_sys_select() kopiert die drei fd_sets in diesen Stack-Puffer (der nfds < 344-Stack-Pfad auf ZF1). Ein präpariertes fd_set-Wort-Array materialisiert einen Fake-rt_mutex_waiter / Fake-Task / Fake-rt_mutex (mit einer rb_tree-Wurzel, deren Zeiger kontrolliert werden). Ein Consumer-Thread ruft dann sched_setattr_tid(waiter) auf → rt_mutex_adjust_pi() → rb_erase_cached, was einen beliebigen Adress-Schreibvorgang eines kontrollierten Werts erzeugt.

Das gesamte Primitiv erfordert den PI-Ketten-Zyklus: Der Owner hält f_pi_target und blockiert zugleich auf f_pi_chain (gehalten vom Waiter), sodass der Kettendurchlauf auf owner → chain → waiter → target → owner trifft und mit -EDEADLK fehlschlägt. Wird der Zyklus entfernt, gibt der Requeue Erfolg mit null Kernel-Effekt zurück.

Exploit-Kette

  1. Slide (KASLR) — Kernel-Basis leaken. Zwei Routen:
    • tracefs sched_blocked_reason (m1q primär, auf dem Gerät bewiesen): Der gespeicherte Return-PC eines blockierten kworkers (stack_trace_save_tsk) wird aus dem Ringpuffer gelesen und gegen den einkompilierten worker_thread- Offset verglichen. Läuft, bevor irgendwelche boot_id-Routen-Wörter verwendet werden, damit Data-Alias- Schreibziele (data_addr() = p0-Alias + slide_p0_offset) bei einem von Null verschiedenen Slide korrekt bleiben.
    • boot_id-pselect-Route (Fallback, slide-unabhängig): Ein pselect-Schreibvorgang platziert SLIDE_LOGGERS_0_1 über einen Linear-Map- Alias in die boot_id-sysctl-Daten; der geleakte Wert rekonstruiert stext. Auf m1q geparkt: Sein W1- Ziel (SLIDE_RANDOM_BOOT_ID_DATA_OFF, niedriger physischer RAM) hat seitenabhängige Beschreibbarkeit — der Slide verschiebt das Ziel pro Boot über Seitengrenzen, sodass ~6/7 Läufe fehlschlagen. Nur explizit über SLIDE_FORCE_BOOTID (Mechanismus-Test) ausgeführt, mit tree_pc/tree_left auf die gesprayte Seite umgeleitet.
  2. KernelSnitch — mm_struct-große Objekte sprayen und eine Futex-Hash- Kollision nutzen, um ein auf dem Heap zu lokalisieren, wodurch eine Kernel-Heap-Seiten- Adresse geleakt wird, die als Basis für den Fake-Object-Spray dient. Waiter werden beim Cleanup abgetrennt (nicht gejoint), um den Kernel-Stack-OOM zu vermeiden, der Builds vor #26 zum Absturz brachte.

Walk-Form (m1q, auf dem Gerät bewiesen)

Die pselect-fd_set-Wörter materialisieren einen Fake-rt_mutex_waiter auf dem Kernel-Stack des Waiters; der sched_setattr_tid(waiter) eines Consumer-Threads durchläuft ihn via rt_mutex_adjust_pi(). ZF1-Wortkarte (disasm-verifiziert): PSELECT_WAITER_WORD_SHIFT = 0, Wort 12 = task (@+0x50), Wort 13 = lock (@+0x58), Wort 14 = wake_state (@+0x60 = 3). Mit einem geseedeten Fake-rt_mutex schließt der Walk sauber ab: [7]s rb_erase W1 *(tree_left)=tree_pc / W2 *(tree_pc&~3+8)=tree_left sind die einzigen Kernel-Schreibvorgänge; [11] (setprio / dequeue_pi) und der [9]-Wake werden beide übersprungen (lokaler Fake-Waiter bei Prio 100 hält den Stack-Knoten aus dem Top-Waiter). Jede walk-entered-Vervollständigung seit Build #19 überlebt auf dem Gerät; die deterministischen Abstürze davor waren ein 8-Byte-Payload-Platzierungsfehler (SKB_DATA_DELTA), kein Walk-Body-Fehler.

Stage 3 (pgd-Swap-Brücke, nur statisch/Build)

Optionale STAGE3=1-Phase, die ein Bridge-Kind forkt, dessen mm->pgd auf eine vorbereitete Fake-Page-Table tauscht (3-Ebenen: PGD→L1→L2, RX-Loop-Leaf + RW-Stack-Leaf) und das Kind einen reinen Register-Assembly-Blob ausführen lässt, der seine eigenen Cred durch ein 2MB-physisches Scan-Fenster patcht — all-RAM-Phys-R/W ohne die configfs/pipe- Primitive. Derzeit nur in das m1q-Ziel verdrahtet und nicht auf dem Gerät ausgeführt.

Unterstützte Ziele

41 Ziele in src/targets/<codename>-<build>/, jedes benötigt mindestens eine target.h (Kernel-Symbol-Offsets, KIMAGE_TEXT_BASE, Direct-Map-Basis, Struct- Offsets). Pixel-Ziele (comet, tokay, tegu, caiman, komodo, frankel, mustang, rango, stallion, blazer) überschreiben gemeinsame Quellen; Samsung-Ziele (m1q-*) fügen gerätespezifische Logik hinzu.

root@kitploit:~
make list-projects   # full list

Kernel-Struct-Layouts unterscheiden sich je Gerät — Offsets müssen gegen das tatsächliche Kernel-Binary / kallsyms für jedes Ziel verifiziert werden.

Build

Ausgabe: build/<PROJECT>/bin/preload.so (Shared Lib, geladen via LD_PRELOAD).

root@kitploit:~
# Default project
CC=clang make

# Specific device target (default: blazer-CP2A.260605.012)
CC=clang make PROJECT=m1q-BP4A.251205.006

# Without CC=clang: uses NDK if found ($NDK_ROOT / $ANDROID_NDK_HOME /
# $ANDROID_NDK_ROOT), otherwise host clang + Android sysroot
make PROJECT=m1q-BP4A.251205.006

# Show build configuration
make info

# Clean
make clean

Der Build bettet ein PIE-su_daemon-Binary (src/su_daemon.c, gebaut zu build/embed/su_daemon_aarch64_pie) und assets/wallpaper.webp in preload.so via src/su_blob.S / src/wallpaper_blob.S ein.

Auf dem Gerät ausführen

Die Build-Ausgaben nach /data/local/tmp pushen, dann den Exploit unter LD_PRELOAD ausführen. Auf einem Live-Bring-up-Ziel OHNE tee ausführen — tee puffert sein eigenes stdio und verliert das Ende des Logs bei einem Kernel-Panic (Exploit-stdout ist ungepuffert, daher bewahrt eine direkte Umleitung in eine Datei jede Zeile):

root@kitploit:~
adb push build/m1q-BP4A.251205.006/bin/preload.so /data/local/tmp/preload.so
adb push build/embed/su_daemon_aarch64_pie /data/local/tmp/su_daemon_aarch64_pie
adb shell "chmod 755 /data/local/tmp/preload.so /data/local/tmp/su_daemon_aarch64_pie"

adb shell "LD_PRELOAD=/data/local/tmp/preload.so \
  /data/local/tmp/su_daemon_aarch64_pie \
  > /data/local/tmp/output.log 2>&1"

Bei Erfolg lauscht der Daemon auf /data/local/tmp/temp_su.sock und su ist unter /apex/com.android.virt/bin installiert.

m1q pipei-Sweep (aktuelles Bring-up)

tools/run_pipei.sh pusht das Binary, verifiziert es per sha256 auf dem Gerät (ein veraltetes preload.so erzeugt stillschweigend unlesbare Urteile — die Leiter lief einst einen Build < #22, dessen Log-Format abweicht), und führt dann den vollständigen 168-Kandidaten- Sweep in 3x56-Chunks aus, sodass ein Panic höchstens einen Chunk verliert (~10 min). Der Exploit- stdout streamt direkt durch adb (keine geräteseitige Umleitung — ein geräteseitiges tee verliert das Ende bei Panic); eine hostseitige Kopie jedes Chunks wird unter /tmp/m1q_pipei_chunk{1..3}_stream.log aufbewahrt:

root@kitploit:~
sh tools/run_pipei.sh

PASS = irgendein Chunk zeigt tmp_page uname changed + after uname='CatOS. PIPEI_CHILD_REGIONS muss mindestens auf die Chunk-Größe gesetzt sein, sonst bleiben die pro-Kind- rt_mutex-Regionen ungeseedet und der Sweep panict bei Kandidat 0. Vollständige Abdeckung erfordert außerdem TMP_UNAME_PIPEI_SPLIT_ORDER_PAGES=1 — ohne dies wird nur eine Seite des freigegebenen 8-Seiten-mm-Blocks gesweept. run_pipei_slim.sh ist die Einzelkandidaten-Diagnosevariante; run_m1q_ladder.sh ist die Walk-/Isolations-Batterie (B16-2-Orakel, Slide-Mechanismus, Sweep-Schritte).

Laufzeitkonfiguration (Umgebungsvariablen)

Projekt-Layout

root@kitploit:~
exploit/
  Makefile
  assets/                     # wallpaper.webp (embedded post-root artifact)
  src/
    main.c                    # run_exploit() entry point (shared)
    preload.c                 # LD_PRELOAD constructor, su/wallpaper install
    util.c                    # addr translation, page prep, configfs helpers
    pipe.c                    # pipe-based physical read/write
    root.c                    # cred patching / task walk
    slide.c                   # KASLR slide (tracefs + boot_id routes)
    fops.c                    # pselect corruption + fops manipulation
    faketables.c              # stage-3 fake page-table builders (3-level)
    stage3.c                  # pgd-swap bridge child (no-op unless configured)
    stage3_loop.S, stage3_poll.S  # bridge blob + enter trampoline
    su_daemon.c               # root daemon (compiled as separate PIE)
    su_blob.S, wallpaper_blob.S   # embedded binaries
    offset.h                  # pulls per-target target.h via -DTARGET_CONFIG_H
    kernelsnitch/             # mm_struct futex-hash leak library
    targets/<codename>-<build>/    # per-device target.h + optional overrides
poc/poc.c                     # standalone POC (separate from the exploit)

Ziele überschreiben gemeinsame Quellen über den pick_src-Mechanismus des Makefiles: Wenn src/targets/<PROJECT>/<file>.c existiert, wird es statt der gemeinsamen src/<file>.c verwendet; andernfalls wird die gemeinsame Version verwendet.

Hinweise und Fallstricke

  • Den PI-Ketten-Zyklus niemals entfernen. Das Schreibprimitiv hängt davon ab, dass der Requeue mit -EDEADLK (errno 35) fehlschlägt. Ein fehlender Zyklus zeigt sich als success=1 mit null Kernel-Effekt.
  • Der Waiter muss die PI-Ketten-Sperre über pselect hinweg halten. Wird sie zuerst freigegeben, kann der Owner aufwachen und mit der Fake-rb_tree-Traversierung racen → Panic.
  • m1q: PSELECT_WAITER_WORD_SHIFT muss 0 sein (ZF1-Stack-Tiefen aus ELF verifiziert). Andere Ziele verwenden weiterhin standardmäßig 1 — pro Gerät verifizieren, bevor man ihnen vertraut.
  • p0_data_alias() verwendet DIRECT_MAP_BASE (die lineare Map), die sich von P0_PAGE_OFFSET auf ZF1 unterscheidet. Daten-Aliase für dereferenzierte Kernel-Objekte müssen die lineare Map verwenden.
  • pr_error() ist fatal (exit(-1)), anders als die Warn-/Info-Makros.
  • Die Slide-Rekonstruktion verwendet SLIDE_LOGGERS_0_1, nicht SLIDE_NFULNL_LOGGER; das Wort ist ein nicht-randomisierter Linear-Map-Alias, daher ist die boot_id-Route slide-unabhängig (nur bei slide=0 verwenden — zuerst den tracefs-Leak ausführen).

Haftungsausschluss

Dies ist Exploit-Code für Android-Geräte und ist für Sicherheitsforschung, autorisiertes Schwachstellentesting und Verteidigungsarbeit auf Hardware gedacht, die Sie besitzen oder für die Sie ausdrückliche Testgenehmigung haben. Missbrauch auf Geräten, die Sie nicht besitzen, ist illegal. Der Autor ist nicht verantwortlich für gebrickte Geräte, gebrickte Kernel oder erlöschene Garantien.

Tool herunterladen
mm_struct
  • Hauptroute — pipei tmp_page-Bootstrap (m1q, aktueller Fokus) — die ursprüngliche configfs-CFI-Route ist eine Sackgasse auf m1q: Das Rust-Ashmem hat keinen injizierbaren statischen write_iter-Slot und das ASHMEM_SET_NAME-Heap-Objekt ist ein KVec, dessen Layout nicht mit dem private_data von configfs_bin_write_iter übereinstimmt. m1q wechselt stattdessen zu einem kmalloc-Schreibvorgang: den geleakten mm- Order-3-Block als pipe_inode_info-Objekte zurückgewinnen und den pselect-W1-Schreibvorgang (*(tree_left) = tree_pc) nutzen, um den tmp_page-Slot eines Kandidaten (+0x90) mit der UTS-Namespace-Seite (init_uts_ns) zu überschreiben. Ein Fanout-Schreibvorgang platziert einen Marker-Namen am sysname-Offset und uname() meldet "CatOS" — ein verifizierbarer Kernel-Schreibvorgang ohne Abhängigkeit von statischen Objekten. C-Ashmem-Ziele behalten den configfs-Pfad.
  • Pipe physrw — Pipe-Puffer-Seiten in der gesprayten Kernel-Seite fälschen für physisches Lesen/Schreiben: Cred-Patching, SELinux-Deaktivierung und direkte Kernel- Speichermanipulation.
  • Root — den Cred des Root-Kinds patchen (uid/gid/caps/SELinux-SID), dann installiert preload.c den eingebetteten su-Daemon (tmpfs-gemountet in /apex/com.android.virt/bin, plus adbd-Namespace- und lokale Varianten) und tauscht das Wallpaper aus.
  • VariableStandardZweck
    PSELECT_ROUTE_SHIFTCompile-ZeitA/B-fd_set-Wort-Shift für die Hauptroute (m1q)
    SLIDE_SHIFTCompile-ZeitA/B-fd_set-Wort-Shift für die Slide-Route
    PSELECT_ROUTE_DELAY_USEC50000Consumer-Verzögerung vor sched_setattr (muss > 0 sein)
    SLIDE_CONSUME_USEC, SLIDE_ENTER_DELAY_USEC, SLIDE_CONSUMER_CORE—Slide-Routen-Timing/Pinning
    SKIP_SLIDE0Direct-Map-Fallback verwenden (slide = 0)
    SLIDE_ONLY0Nur den KASLR-Slide ausführen und beenden
    SLIDE_P0_OFFSET, SLIDE_BOOTID_OFF—Slide-p0-Alias / boot_id-Offsets überschreiben
    SLIDE_FORCE_BOOTID0Die boot_id-pselect-Route nach dem tracefs-Slide erzwingen (Mechanismus-Test)
    KSNITCH_COLLISIONS4KernelSnitch-Kollisionsanzahl
    STAGE30Die pgd-Swap-Bridge-Kind-Phase aktivieren (m1q)
    STAGE3_DRYRUN0Tabellen vorbereiten/verifizieren, dann vor dem Swap abbrechen
    PAGE_RECLAIM_SENDS, PSELECT_SIMPLE_LAYOUT—Spray-/fd_set-Layout-Anpassungen
    TMP_PAGE_UNAME0Den m1q pipei tmp_page-uname-Bootstrap ausführen
    TMP_UNAME_PIPEI_SWEEP, TMP_UNAME_PIPEI_ALIGN_ORDER, TMP_UNAME_PIPEI_SPLIT_ORDER_PAGES—Sweep-Modus; split_order sweept alle 8 Seiten des freigegebenen mm-Blocks
    TMP_UNAME_PIPEI_SLOT, TMP_UNAME_PIPEI_SLOT_CANDIDATES—Sweep-Bereich (Chunk-Start / Anzahl)
    PIPEI_CHILD_REGIONS0Pro-Kind geseedete rt_mutex-Regionen; MUSS >= Sweep-Chunk sein, sonst panicen ungeseedete Regionen bei Kandidat 0
    PIPEI_RECLAIM_COUNT, PIPEI_DRAIN_COUNT—Pipe-Paare zurückgewinnen/drainen; bei einem Reclaim-Fehlschlag erhöhen
    PIPEI_SPONGE_MB3072Order-0-Flood-Schwamm, der über den Reclaim gehalten wird (Build #29)
    PSELECT_W0_PRIO_OVERRIDE130Top-Waiter-Prio; inert mit geseedeten Regionen (Legacy-Stale-Tree-Guard, nur A/B)
    PSELECT_SKB_DELTA_OVERRIDE0A/B-Payload-Intra-Page-Offset (nur falls ein Gerät von -0xe78 abweicht)
    TMP_UNAME_NAME, TMP_UNAME_HOLD_SEC"CatOS", 5Marker-Name / Haltezeit nach Erfolg
  • SKB_DATA_DELTA ist -0xe78 (auf dem Gerät gemessen, Build #19) — der echte skb-frag-Head ist 8 Bytes kleiner als der disasm-abgeleitete -0xe80; dieser 8-Byte- Fehler verursachte jeden deterministischen pselect-Absturz von Builds #6-18 (walk-entered → Garbage-Deref). GKI 6.12 gemeinsamer Wert; pro-Ziel-util.c- Kopien tragen einen SKB_DATA_DELTA-Env-A/B-Knopf. PSELECT_SKB_DELTA_OVERRIDE NICHT auf die eingebackene Konstante stapeln.
  • Der Walk-Body ist sauber; die Platzierung war der Bug. Mit dem geseedeten Payload an den modellierten Offsets schließt der Kettendurchlauf auf dem Gerät fehlerfrei ab. Ein walk-entered-Absturz bedeutet, dass der Speicher an den fd-Wort-Adressen NICHT der Payload ist (Reclaim-/Platzierungs-Race), kein Modellfehler.
  • m1q: configfs-CFI-Route ist eine Sackgasse (Rust-Ashmem) — kein injizierbarer statischer fops-Slot und die ASHMEM_SET_NAME-KVec-Hülle passt nicht zu configfs_bin_write_iter. Den pipei tmp_page-Bootstrap verwenden. Die PSELECT_WRITE_RIGHT_SPRAYED / PSELECT_PI_TOP_TASK_SELF-Guards in m1q target.h leiten die [11]-Schreibvorgänge des Walks von den RO-statischen fops weg.
  • Pro-Kind rt_mutex-Regionen (Build #33): Jedes Sweep-Kind leitet fd- Wort w13 auf seine eigene geseedete Region (payload+0x6000 + idx*0x40) innerhalb der zurückgewonnenen Seite um. Shared-fake_lock-Sweeps panicten bei Kandidat ~9-12 (recycelte Stale-Kernel-Stack-Knoten), und die leeren Regionen von Build #32 panicten bei Kandidat 0 ([9] owner==NULL-Wake auf dem mit 0x41 gefüllten fake_task). PIPEI_CHILD_REGIONS muss gesetzt sein, sonst bleiben die Regionen ungeseedet.
  • m1q boot_id-pselect-Slide ist geparkt — sein W1-Ziel ist niedriger RAM, dessen Seiten-Beschreibbarkeit pro Boot variiert; tracefs ist primär und misst den Slide bei jedem Lauf.