Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
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.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
cve-2026-98260-uaf — CVE-2026-98260 (posix-cpu-timers exec UAF) Exploit-Forschung: S9280 Android 14 GKI 6.1 — UAF-Trigger + Zero-Write-Primitive + SELinux Permissive. Übergabedokument in HANDOFF.md | Kitploit
Tools/GitHubGitHub/nanoturtle1145/cve-2026-98260-uaf
Android-SicherheitPrivilege EscalationSpeicherforensikSchwachstellenanalyseExploitationPapers & ForschungBinary-Exploitation
GitHubnanoturtle1145/cve-2026-98260-uaf

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

cve-2026-98260-uaf

CVE-2026-98260 (posix-cpu-timers exec UAF) Exploit-Forschung: S9280 Android 14 GKI 6.1 — UAF-Trigger + Zero-Write-Primitive + SELinux Permissive. Übergabedokument in HANDOFF.md

Repository anzeigen
33vor 2 TagenNoch nicht geprüft

CVE-2026-98260 — Trigger-only PoC (posix-cpu-timers UAF)

Schwachstelle

exec: Cleanup POSIX timers right after de_thread() (Autor Hyunwoo Kim, 2026-09-11 upstream, Fixes: 55e8c8eb2c7b = ab 5.7).

Am Nicht-Leader-Thread E hängt ein CLOCK_THREAD_CPUTIME_ID-Timer; in execve() schlägt nach dem tid-Austausch durch de_thread() die Rückwärtssuche des Timers nach dem Task per PID fehl, und der Knoten bleibt in den posix_cputimers von E zurück. Wenn mmap_read_lock_killable() in exec_mmap() -EINTR zurückgibt (exec schlägt fehl und der Bereinigungscode steht weiter hinten), gibt do_exit() → exit_itimers() den k_itimer frei, aber der Knoten wird nicht entfernt; wenn der Elternprozess per wait4() aufräumt, führt cleanup_timerqueue() → timerqueue_del() eine Operation auf einem bereits freigegebenen Objekt aus → UAF.

Patch-Status (Stand 2026-10-27, geprüft in fs/exec.c der einzelnen Stable-Branches)

Branchposixtimer_execStatus
linux-6.1.ynicht vorhandennicht behoben
linux-5.15.ynicht vorhandennicht behoben
linux-6.6.yvorhandenbehoben (6.6.158+)
linux-6.12.yvorhandenbehoben (6.12.112+)

→ Die Ziele dieses Projekts (5.15-/6.1-Linie sowie 6.6 unterhalb von 6.6.158) liegen alle im betroffenen Bereich.

Warum dieser Trigger „deterministisch" ist und nicht auf Timing setzt

  1. Langes Write-Lock-Fenster: fragment_vmas() zerlegt den Adressraum mit memfd + MAP_FIXED in --vmas (Standard 50000) nicht zusammenführbare VMAs (jede hat vm_pgoff = 0, benachbarte Adressen haben kein fortlaufendes pgoff → vma_merge schlägt fehl). Der Locker-Thread ruft wiederholt mprotect über den gesamten Bereich auf; das Durchlaufen von Zehntausenden VMAs hält den mmap-Write-Lock millisekundenlang.
  2. Präziser Synchronisationspunkt: Der Killer erkennt am Rückgabewert ESRCH von tgkill(tgid, alte tid, 0), dass „de_thread() den tid-Austausch abgeschlossen hat", und sendet erst dann SIGKILL.
  3. Der Opfer-Thread blockiert zwangsläufig in exec_mmap() bei mmap_read_lock_killable() (der Read-Lock wird vom Write-Lock blockiert), und SIGKILL trifft Mikrosekunden später ein → dieser Aufruf gibt -EINTR zurück → exec schlägt fehl. Das Fenster (ms) ≫ Reaktionszeit (µs), daher ist kein Glück nötig.

⚠️ Zu unterscheiden: Der Trigger ist deterministisch; vom UAF zu beliebigem Schreiben/Ändern der cred hängt es von der Slab-Wiederverwendungs-Orchestrierung des posix_timers_cache ab (Order, Objects/Slab, CPU-Partial, memcg-Zugehörigkeit) — das ist messbares, iterierbares Heap-Engineering, kein Race.

Build

export ANDROID_NDK_HOME=/home/nt/项目/samsung_root_research/06_工具链/android-ndk-r29
make            # 产物 trigger(aarch64 / Android 21+ / 仅依赖 libc、libdl)

Testschritte

adb push trigger /data/local/tmp/
adb shell "chmod 755 /data/local/tmp/trigger"
adb shell "/data/local/tmp/trigger --check"        # 先看环境
adb shell "/data/local/tmp/trigger; echo exit=\$?"

Erfolgsindikatoren (einer von drei reicht):

  • Nach dem Ausdrucken von [*] 开始触发 startet das Gerät neu / Bildschirm wird schwarz (am direktesten bei panic_on_oops=1)
  • Der Prozess wird durch ein Signal beendet (exit=137/139), und das System lebt danach noch
  • In dmesg (root erforderlich) erscheint ein Aufrufstack mit cleanup_timerqueue / timerqueue_del / rb_erase / rb_next

Bei Fehlschlag (keine Auslösung) versucht das Programm selbst --attempts Mal erneut und gibt für jede Runde das wait4-Ergebnis aus, zuletzt folgt ein Hinweis zum Parameter-Tuning: --vmas 120000 --lockers 4 --cpu 0.

Bekannte Einschränkungen

  • Eine erfolgreiche Auslösung führt fast zwangsläufig zu einem Neustart des Geräts (das ist der Beweis für den "Erfolg"); vor dem Test bitte sicherstellen, dass keine ungespeicherte Arbeit verloren geht.
  • Samsungs panic_on_oops ist möglicherweise 0: Dann wird die Aufgabe beendet, und der Kernel läuft mit einem beschädigten rbtree weiter; es wird empfohlen, 2–3 Mal hintereinander zu laufen und zu beobachten, ob ein nachfolgender Panic auftritt.
  • Dieser PoC enthält keinen Privilegieneskalationscode (kein reclaim, kein Zugriff auf cred), er dient nur zur Verifikation von Erreichbarkeit und Determinismus.

Referenzen

  • Upstream-Patch https://github.com/torvalds/linux/commit/acb03d3881818581052924a9bbbe92b8741ed448
  • Vollständige Kette für Honor MagicPad3 Pro (6.12.38, inkl. uid-0 und KSU-Boot) https://github.com/woshigenm/CVE-2026-98260
  • Portierungsnotizen für vivo/iQOO 6.6.127 (Reclaim-Orchestrierung, SLUB-Parameter) https://github.com/janewas/cve-2026-98260-vivo-gki-research

Messprotokoll (SM-S9280 / e3q / 6.1.162 / Android 17 / Sicherheitspatch 2026-09-05)

Testumgebung: S9280ZHU6EZIF, Kernel 6.1.162-android14-11-34343818-abS9280ZHU6EZIF (Build 2026-09-20), nicht gerootet, shell-Domäne (uid 2000), SELinux Enforcing.

Fazit: Die Auslösung ist deterministisch (kein Timing-Glücksspiel)

RundeBeobachtungBedeutung
Jede RundeElternprozess tgkill(child_tgid, etid, 0) gibt ESRCH zurückde_thread() hat den tid-Austausch abgeschlossen
Jede RundeDanach kill(child_tgid, SIGKILL), Kindprozess rc=-9exec wurde abgebrochen (nicht rc=0 eines erfolgreichen exec)
--no-killer-Kontrolleexec von armed bis Ende dauert 277 ms (mit killer 287 ms)Der mmap-Schreib-Lock blockiert tatsächlich mmap_read_lock_killable() von exec_mmap()

5/5 Runden trafen alle "ESRCH → SIGKILL → exec fehlgeschlagen", kein einziges Mal war exec erfolgreich. Das beweist, dass das Fenster zum Abbruch von exec nach de_thread kontrollierbar und stabil ist; das Fenster stammt vom mprotect des lockers (60.000 VMAs, einzeln 200–700 ms), die Reaktion des Elternprozesses liegt im µs-Bereich.

Zwei entscheidende Stolperfallen (beide bereits im Code behoben)

  1. Der killer muss im Elternprozess sein: de_thread() ruft zap_other_threads() auf und tötet alle anderen Threads desselben Prozesses; ein im Kindprozess platzierter killer stirbt im Moment von de_thread selbst und sieht ESRCH nie (äußert sich darin, dass exec jedes Mal erfolgreich ist).
  2. Reclaim-Zeitpunkt: Direkt nach SIGKILL zu sprayen ist wirkungslos – zu diesem Zeitpunkt ist der Kindprozess noch nicht tot, und k_itimer wurde noch nicht per RCU freigegeben. Die richtige Reihenfolge ist waitid(WNOWAIT) auf den Zombie warten → auf RCU-Callback-Freigabe warten → Seiten schnappen → zuletzt wait4 zum Auslösen des Reclaim-Pfads.

Noch nicht abgeschlossen: den UAF sichtbar machen

Derzeit ist der Schritt "nach der Freigabe ist der Knoten noch in der Queue" stabil erreicht, aber das rb_erase zum Zeitpunkt von wait4 erzeugt kein oops – das bedeutet, die betroffene Slab-Seite wurde noch nicht von unserem Spray geschnappt (der partial slab von posix_timers_cache ist noch gecacht, die Seite ist nicht zum Buddy zurückgekehrt). Das gehört zur Reclaim-Orchestrierung des Exploits, kein Race-Problem; man muss nach der Methode aus den vivo-Notizen vorgehen: zuerst mit k_itimer selbst den Slab füllen/leeren, um die ganze Seite zurückzugeben, dann mit einem order-0-Träger (AIO ring usw.) die gesplittete halbe Seite präzise abfangen.

Nächster Schritt: Diese Maschine als Basis nehmen und gemäß docs/08-reclaim-choreography.md (vivo-Notizen) gezieltes Reclaim durchführen; oder mit einem selbstgebauten Kernel mit KASAN verifizieren, ob der UAF tatsächlich auftritt.


Machbarkeit der vollständigen Kettenportierung (SM-S9280 / 6.1.162 Messschwelle)

Die öffentliche Kette (Honor uid0.c) nutzt kmem-Events von tracefs für zwei entscheidende Dinge:

Tool herunterladen