Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2026-98260-uaf — Ricerca sull'exploit di CVE-2026-98260 (UAF exec di posix-cpu-timers): S9280 Android 14 GKI 6.1 — trigger UAF + primitiva di scrittura zero + SELinux Permissive. Documento di handoff in HANDOFF.md | Kitploit
Strumenti/GitHubGitHub/nanoturtle1145/cve-2026-98260-uaf
Sicurezza AndroidEscalation di PrivilegiMemory ForensicsAnalisi delle VulnerabilitàExploitPaper e RicercaBinary Exploitation
GitHubnanoturtle1145/cve-2026-98260-uaf

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

cve-2026-98260-uaf

Ricerca sull'exploit di CVE-2026-98260 (UAF exec di posix-cpu-timers): S9280 Android 14 GKI 6.1 — trigger UAF + primitiva di scrittura zero + SELinux Permissive. Documento di handoff in HANDOFF.md

Vedi Repository
3323 giorni faNon ancora revisionato

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

Vulnerabilità

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

Sul thread non leader E è agganciato un timer CLOCK_THREAD_CPUTIME_ID; in execve(), dopo che de_thread() scambia il tid, la ricerca inversa del task tramite PID del timer fallisce e il nodo rimane nei posix_cputimers di E. Se mmap_read_lock_killable() di exec_mmap() restituisce -EINTR (exec fallisce e il codice di pulizia è più avanti), do_exit() → exit_itimers() libera il k_itimer ma il nodo non viene rimosso; quando il processo padre lo recupera con wait4(), cleanup_timerqueue() → timerqueue_del() opera su un oggetto già liberato → UAF.

Stato della patch (verifica effettiva del 2026-10-27 su fs/exec.c nei vari rami stabili)

Ramoposixtimer_execStato
linux-6.1.yassentenon corretta
linux-5.15.yassentenon corretta
linux-6.6.ypresentecorretta (6.6.158+)
linux-6.12.ypresentecorretta (6.12.112+)

→ Gli obiettivi di questo progetto (linee 5.15 / 6.1, e 6.6 precedenti alla 6.6.158) rientrano tutti nell'ambito interessato.

Perché questo trigger è "deterministico" e non un azzardo sui tempi

  1. Lunga finestra di write lock: fragment_vmas() usa memfd + MAP_FIXED per suddividere lo spazio di indirizzi in --vmas (default 50000) VMA non unibili (il vm_pgoff di ciascuna è 0, i pgoff di indirizzi adiacenti non sono contigui → vma_merge fallisce). Il thread locker esegue ripetutamente mprotect sull'intero intervallo, e l'attraversamento di decine di migliaia di VMA mantiene il write lock di mmap per millisecondi.
  2. Punto di sincronizzazione preciso: il killer usa tgkill(tgid, vecchio tid, 0) che restituisce ESRCH per stabilire che "de_thread() ha completato lo scambio di tid", e solo in quel momento invia SIGKILL.
  3. Il thread vittima si blocca necessariamente in exec_mmap() su mmap_read_lock_killable() (il read lock è bloccato dal write lock), e il SIGKILL arriva microsecondi dopo → quella chiamata restituisce -EINTR → exec fallisce. La finestra (ms) ≫ tempo di reazione (µs), quindi non dipende dalla fortuna.

⚠️ Nota bene la distinzione: il trigger è deterministico; il passaggio da UAF a arbitrary write / modifica delle cred dipende dall'orchestrazione del riuso dello slab di posix_timers_cache (order, objects/slab, CPU partial, appartenenza memcg), che è heap engineering misurabile e iterabile, non una race.

Build

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

Passaggi di test

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=\$?"

Indicatori di successo (ne basta uno dei tre):

  • Dopo la stampa di [*] 开始触发 il dispositivo si riavvia/schermo nero (il caso più diretto con panic_on_oops=1)
  • Il processo viene terminato da un segnale (exit=137/139) e il sistema resta vivo
  • In dmesg (serve root) compaiono le stack di chiamata di cleanup_timerqueue / timerqueue_del / rb_erase / rb_next

In caso di fallimento (mancata attivazione) il programma ritenta da solo --attempts volte e stampa il risultato di wait4 per ogni ciclo, infine suggerisce la regolazione dei parametri: --vmas 120000 --lockers 4 --cpu 0.

Limitazioni note

  • Un'attivazione riuscita comporta quasi inevitabilmente il riavvio del dispositivo (questa è la prova del "successo"); prima del test verificare che non ci siano lavori non salvati.
  • Su Samsung panic_on_oops potrebbe essere 0: in tal caso il task viene terminato e il kernel continua a funzionare con un rbtree corrotto; si consiglia di eseguire 2~3 volte di seguito per osservare se compare un panic successivo.
  • Questo PoC non contiene codice di privilege escalation (non esegue reclaim, non tocca cred), serve solo a verificare raggiungibilità e determinismo.

Riferimenti

  • Patch upstream https://github.com/torvalds/linux/commit/acb03d3881818581052924a9bbbe92b8741ed448
  • Catena completa Honor MagicPad3 Pro (6.12.38, con uid-0 e boot KSU) https://github.com/woshigenm/CVE-2026-98260
  • Note di porting vivo/iQOO 6.6.127 (orchestrazione del reclaim, parametri SLUB) https://github.com/janewas/cve-2026-98260-vivo-gki-research

Registro delle prove sul campo (SM-S9280 / e3q / 6.1.162 / Android 17 / patch di sicurezza 2026-09-05)

Ambiente di test: S9280ZHU6EZIF, kernel 6.1.162-android14-11-34343818-abS9280ZHU6EZIF (build 2026-09-20), non root, dominio shell (uid 2000), SELinux Enforcing.

Conclusione: l'attivazione è deterministica (non si scommette sul timing)

CicloOsservazioneSignificato
Ogni cicloIl processo padre tgkill(child_tgid, etid, 0) restituisce ESRCHde_thread() ha completato lo scambio dei tid
Ogni cicloSubito dopo kill(child_tgid, SIGKILL), il processo figlio ha rc=-9exec è stato interrotto (non rc=0 di un exec riuscito)
Controllo --no-killerexec da armed a fine impiega 277 ms (287 ms con il killer)il write lock di mmap ha effettivamente bloccato mmap_read_lock_killable() di exec_mmap()

5/5 cicli hanno tutti centrato "ESRCH → SIGKILL → exec fallito", nessuna volta exec è riuscito. Ciò dimostra che la finestra di interruzione di exec dopo de_thread è controllabile e stabile; la finestra deriva dal mprotect del locker (60.000 VMA, 200–700 ms per singola chiamata), mentre la reazione del processo padre è a livello di µs.

Due insidie chiave incontrate (entrambe già corrette nel codice)

  1. Il killer deve stare nel processo padre: de_thread() esegue zap_other_threads() e uccide tutti gli altri thread dello stesso processo; un killer scritto nel processo figlio morirebbe da solo al momento di de_thread, senza mai vedere ESRCH (il che si manifesta come exec riuscito ogni volta).
  2. Tempistica del reclaim: eseguire lo spray subito dopo SIGKILL è inefficace — a quel punto il processo figlio non è ancora morto e k_itimer non è ancora stato liberato da RCU. L'ordine corretto è waitid(WNOWAIT) attendere lo zombie → attendere che il callback RCU liberi → conquistare la pagina → infine wait4 per attivare il percorso di reclaim.

Ancora da completare: rendere visibile la UAF

Al momento il passo "nodo ancora in coda dopo il rilascio" è stabilmente raggiunto, ma l'rb_erase al momento di wait4 non ha prodotto oops — il che indica che la pagina slab vittima non è ancora stata conquistata dal nostro spray (la partial slab di posix_timers_cache è ancora in cache, la pagina non è tornata al buddy). Questo riguarda l'orchestrazione del reclaim dell'exploit, non è un problema di race; occorre procedere come nelle note vivo: prima saturare/svuotare la slab con k_itimer stesso per favorire la restituzione dell'intera pagina, poi intercettare con precisione la metà di pagina splittata usando un carrier order-0 (AIO ring, ecc.).

Suggerimento per il passo successivo: usare questa macchina come riferimento e fare un reclaim mirato seguendo l'approccio di docs/08-reclaim-choreography.md (note vivo); oppure verificare con un kernel compilato da sé con KASAN se la UAF si verifica davvero.


Fattibilità del porting della catena completa (soglia misurata su SM-S9280 / 6.1.162)

La catena pubblica (uid0.c di Honor) si basa sugli eventi kmem di tracefs per due cose cruciali:

Scarica lo strumento