Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/longwasu/cve-2025-38352-poc
Memory ForensicsAnalisi delle VulnerabilitàExploitReverse EngineeringDebuggerPaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHublongwasu/cve-2025-38352-poc

CVE-2025-38352-PoC

PoC e script GDB che assistono nell'attivazione di CVE-2025-38352

Vedi Repository
7h 7m faNon ancora revisionato

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-2025-38352: Race Condition TOCTOU e UAF nel sottosistema POSIX CPU Timer del kernel Linux

Un Proof-of-Concept (PoC) riproducibile e uno script di orchestrazione GDB automatizzato per CVE-2025-38352, una race condition Time-of-Check to Time-of-Use (TOCTOU) nel sottosistema POSIX CPU timer del kernel Linux (kernel/time/posix-cpu-timers.c) che porta a una Use-After-Free (UAF).

Disclaimer: Questo progetto è destinato esclusivamente a scopi educativi, difensivi e di ricerca sulla sicurezza. Tutti i test e la riproduzione sono stati condotti in una macchina virtuale ARM64 QEMU isolata.


🧠 Come funziona il bug

  1. Il processo A crea il processo figlio B.

  2. Il processo B crea un CPU timer e inizia a terminare, entrando nello stato zombie. Proprio mentre B sta terminando, arriva un interrupt del timer sul suo core CPU. Il kernel entra nel contesto di interrupt per elaborare il timer, ma rilascia temporaneamente il suo lock (unlock_task_sighand) per evitare deadlock.

  3. Esattamente nello stesso momento su un altro core, il processo A raccoglie (reap) il processo B in uscita, ripulendo il suo signal handler (sighand = NULL) e rimuovendo il suo PID dalla hash table.

  4. Un altro thread in B chiama la cancellazione del timer (posix_cpu_timer_del). Tenta di cercare il task tramite il suo PID e controllare il suo signal handler, ma li trova già ripuliti / NULL. Interpretando erroneamente che il task sia completamente morto e che nessun timer possa essere in esecuzione, assume che sia sicuro e libera il timer dalla memoria.

  5. Nel frattempo, l'handler dell'interrupt del timer sul primo core riprende per far scattare il timer scaduto. Poiché il timer è appena stato liberato nello Step 4, accedervi provoca una Use-After-Free e manda in crash il kernel.


🔬 Strategia di sincronizzazione (poc_gdb_script.py)

Poiché lo stub GDB di QEMU non supporta set non-stop on (fermare una vCPU ferma tutte le vCPU), la sincronizzazione multi-thread standard non può essere ottenuta tramite semplici breakpoint.

Questo repository risolve il problema tramite il Patching delle Istruzioni in Memoria:

  1. Stage 1 (Barriera CPU):

    • I breakpoint sono posizionati sulle 4 funzioni critiche del kernel:
      • exit_notify (CPU 2)
      • kernel_wait4 (CPU 0)
      • __arm64_sys_timer_delete (CPU 1)
      • handle_posix_cpu_timers (CPU 2)
    • Man mano che ogni vCPU raggiunge il suo punto di rendezvous, GDB patcha il suo $pc con l'opcode ARM64 di self-branch 0x14000000 (b . ciclo infinito) e riprende l'esecuzione.
    • Una volta che tutte e 4 le vCPU sono bloccate nelle loro posizioni esatte, GDB ripristina le istruzioni originali e passa l'esecuzione allo Stage 2.
  2. Stage 2 (Orchestrazione Sequenziale):

    • GDB blocca lo scheduler (set scheduler-locking on) e avanza ogni vCPU in sequenza:
      • Step 1 (CPU 2): Avanza handle_posix_cpu_timers oltre unlock_task_sighand().
      • Avanza oltre .

🚀 Come riprodurre

1. Scaricare il sorgente del kernel target

Scarica o clona l'albero dei sorgenti dell'Android Common Kernel al commit 1bf1aa362e6b9573a310fcd14f35bc875b42ba83:

root@kitploit:~
# Option A: Download tarball directly
curl -LO https://android.googlesource.com/kernel/common/+archive/1bf1aa362e6b9573a310fcd14f35bc875b42ba83.tar.gz
mkdir -p kernel-cve && tar -xzf 1bf1aa362e6b9573a310fcd14f35bc875b42ba83.tar.gz -C kernel-cve
cd kernel-cve

# Option B: Clone repository
git clone https://android.googlesource.com/kernel/common
cd common
git checkout 1bf1aa362e6b9573a310fcd14f35bc875b42ba83

2. Annullare la patch in run_posix_cpu_timers()

Apri kernel/time/posix-cpu-timers.c, individua la funzione run_posix_cpu_timers() (intorno alle righe 1435–1448) e commenta le righe della patch:

root@kitploit:~
void run_posix_cpu_timers(void)
{
    struct task_struct *tsk = current;

    lockdep_assert_irqs_disabled();

    /*
     * Ensure that release_task(tsk) can't happen while
     * handle_posix_cpu_timers() is running. Otherwise, a concurrent
     * posix_cpu_timer_del() may fail to lock_task_sighand(tsk) and
     * miss timer->it.cpu.firing != 0.
     */
//  if (tsk->exit_state)
//      return;

3. Disabilitare CONFIG_POSIX_CPU_TIMERS_TASK_WORK

Nota: Quando CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y, i CPU timer vengono eseguiti dal contesto task_work invece che dall'IRQ del timer, aggirando questa race condition. Pertanto, deve essere disabilitato per riprodurre la vulnerabilità.

Poiché CONFIG_POSIX_CPU_TIMERS_TASK_WORK non ha una stringa di prompt nel Kconfig upstream, il suo valore predefinito è y e non può essere modificato direttamente in menuconfig. Puoi esporlo come segue:

  1. In kernel/time/Kconfig (intorno alla riga 56), aggiungi una stringa di prompt e cambia il default:
    root@kitploit:~
    config POSIX_CPU_TIMERS_TASK_WORK
        bool "POSIX CPU timers task work"
        default n
    
  2. Genera la configurazione predefinita e disabilita l'opzione:
    root@kitploit:~
    ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make defconfig
    scripts/config --disable POSIX_CPU_TIMERS_TASK_WORK
    ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make olddefconfig
    
  3. Verifica che sia disabilitato in .config:
    root@kitploit:~
    grep POSIX_CPU_TIMERS_TASK_WORK .config
    # Expected output: # CONFIG_POSIX_CPU_TIMERS_TASK_WORK is not set
    

4. Compilare il kernel

Compila l'immagine del kernel ARM64:

root@kitploit:~
time ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j$(nproc) Image

5. Compilare il PoC userspace

Cross-compila poc.c:

root@kitploit:~
aarch64-linux-gnu-gcc -ggdb3 ./poc.c -o poc

6. Avviare QEMU con GDB Stub

Avvia la tua macchina virtuale QEMU con 4 vCPU (-smp 4) e abilita lo stub GDB (flag -s, porta 1234):

root@kitploit:~
qemu-system-aarch64 \
    -M virt \
    -cpu cortex-a57 \
    -smp 4 \
    -m 2G \
    -kernel arch/arm64/boot/Image \
    -append "console=ttyAMA0 root=/dev/vda oops=panic panic_on_warn=1" \
    ... \
    -s

7. Collegare GDB ed eseguire lo script

Dal terminale host, collega GDB a QEMU e carica lo script di orchestrazione:

root@kitploit:~
gdb-multiarch vmlinux
pwndbg> target remote :1234
pwndbg> source poc_gdb_script.py
pwndbg> continue

8. Attivare la vulnerabilità

All'interno della shell guest di QEMU, esegui il binario compilato:

root@kitploit:~
./poc

[!TIP] Timing e risoluzione dei problemi:
Se il timer scatta prematuramente prima che il thread target abbia raggiunto lo stato zombie, GDB registrerà:

root@kitploit:~
[!] ERROR: handle_posix_cpu_timers fired before exit_state == EXIT_ZOMBIE
  • Opzione 1: Esegui semplicemente di nuovo ./poc e ricarica lo script GDB alcune volte.
  • Opzione 2: Aumenta TIMER_FIRE_MS in poc.c (ad esempio, da #define TIMER_FIRE_MS 10 a 20), ricompila poc.c ed esegui di nuovo. Questo concede al thread tempo extra per raggiungere exit_notify() e passare a EXIT_ZOMBIE prima che il timer scada.

9. Demo

https://github.com/user-attachments/assets/11481b5c-25f8-46c3-be3a-7b79a06a4948


📚 Riferimenti

  • Race Against Time in the Kernel Clockwork di StreyPaws
  • CVE-2025-38352 Root Cause Analysis di Faith
Scarica lo strumento
Step 2 (CPU 0):
kernel_wait4
tsk->sighand = NULL
  • Step 3 (CPU 1): Avanza timer_delete per chiamare release_posix_timer() (liberando sigq).
  • Step 4 (CPU 2): Rilascia il scheduler locking per permettere alla CPU 2 di far scattare il timer liberato $\rightarrow$ Crash!