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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-54107 — Analisi della causa principale di CVE-2026-54107: un use-after-free in Windows win32kfull.sys con debug di race condition, analisi statica, approfondimenti sul triage MSRC e ricerca pratica sullo sfruttamento del kernel. | Kitploit
Strumenti/GitHubGitHub/pravin761/cve-2026-54107
Analisi StaticaAnalisi delle VulnerabilitàExploitReverse EngineeringDebuggerPaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHubpravin761/cve-2026-54107

CVE-2026-54107

Analisi della causa principale di CVE-2026-54107: un use-after-free in Windows win32kfull.sys con debug di race condition, analisi statica, approfondimenti sul triage MSRC e ricerca pratica sullo sfruttamento del kernel.

1112 mesi faNon ancora revisionato
Vedi Repository

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

Quando ValidateHwnd Non È un Cancello: Analisi delle Cause di CVE-2026-54107

Un use-after-free nella gestione del ciclo di vita delle finestre in win32kfull.sys — come l'ho trovato, come mi sono convinto che fosse reale, e come appariva davvero il processo MSRC dal lato del ricercatore.

CVE-2026-54107 CWE-362 CVSS 8.8 MSRC 11xxxxx Bounty $8,000

Erano quasi le 2 di notte quando la VM di test ha smesso di rispondere al heartbeat del debugger ed è caduta in un breakpoint esattamente sull'istruzione che per settimane avevo sostenuto essere raggiungibile. Non un'asserzione, non uno stop per pool corrotto — una semplice violazione di accesso sul percorso di dispatch dei messaggi, nel dereferenziare un oggetto che un altro thread aveva già smantellato.

Quel breakpoint è diventato CVE-2026-54107, caso MSRC 11xxxxx, corretto nell'Aggiornamento di sicurezza di luglio 2026 in 27 prodotti Windows.

Questo post è la metà non soggetta a embargo della storia: causa principale, perché la classe di bug è quella che è, e il ragionamento che mi ha portato fin qui. I dettagli di sfruttamento restano fuori.

Indice

  • 1. Perché win32k, e perché proprio gli oggetti finestra
  • 2. L'odore che mi ha fatto fermare
  • 3. Causa principale
  • 4. Perché il rating di impatto è quello che è
  • 5. La falsificazione è arrivata prima — la maggior parte dei candidati è morta
  • 6. Verifica: la statica dà ipotesi, il debugger dà la verità
  • 7. Sull'uso dell'IA nella ricerca sul kernel
  • 8. La timeline MSRC, onestamente
  • 9. Riepilogo
  • 10. Cosa direi a chi sta iniziando
  • 11. Cosa succede dopo

1. Perché win32k, e perché proprio gli oggetti finestra

Win32k è la metà in modalità kernel del sottosistema grafico di Windows. È vecchio, è enorme e — cosa cruciale — è raggiungibile da contesti che dovrebbero essere non fidati. Quest'ultima proprietà è il motivo per cui rimane un bersaglio di ricerca permanente nonostante vent'anni di lavoro su hardening, filtri e restrizioni sulle syscall.

All'interno di win32k, l'oggetto tagWND (PWND) è insolitamente interessante perché il suo ciclo di vita è gestito da più di un meccanismo contemporaneamente. Una finestra è:

  • referenziata per handle, tramite la tabella degli handle utente e lookup in stile ValidateHwnd,
  • referenziata per puntatore, mantenuta attraverso chiamate annidate e dispatch dei messaggi,
  • referenziata implicitamente dalle relazioni padre/figlio, proprietario/proprietà e thread/desktop,
  • e smantellata tramite un percorso di distruzione che deve dipanare tutto quanto sopra nell'ordine giusto.

Qualsiasi oggetto con diversi percorsi di riferimento indipendenti e un unico percorso di distruzione condiviso merita di essere letto con calma. Non è un'affermazione di vulnerabilità — è un'euristica su dove spendere tempo.

2. L'odore che mi ha fatto fermare

Ciò che mi ha fatto soffermare su questo componente è stata la superficie di importazione. win32kfull.sys tira dentro tre primitive distinte di riferimento a oggetti da ntoskrnl:```c NTSTATUS ObReferenceObjectByPointer( void *Object, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode);

NTSTATUS ObReferenceObjectByHandle( HANDLE Handle, uint32_t DesiredAccess, POBJECT_TYPE ObjectType, char AccessMode, void **Object, OBJECT_HANDLE_INFORMATION *HandleInformation);

NTSTATUS ObReferenceObjectByName(/* ... */);

Three vie in ingresso, un solo percorso di uscita `ObfDereferenceObject`.

Ciò non significa che il codice sia sbagliato. Significa che l'**invariante è distribuita** — nessuna singola funzione possiede *"questo oggetto è vivo in questo momento,"* quindi la correttezza dipende dal fatto che ogni chiamante concordi su quale riferimento detiene e per quanto tempo sia valido. Le invarianti distribuite sono il luogo in cui vivono le race condition, perché una race non è mai un bug logico che puoi vedere in una singola funzione. È un bug in un'ipotesi condivisa tra due.

Quindi la domanda che ho iniziato a porre a ogni funzione che toccava un `PWND` non era *"questo codice è corretto?"* ma:

> **Se questo esatto corpo di funzione viene eseguito su due thread a pochi istruzioni di distanza, quale dei due è sbagliato?**



## 3. Causa principale

Il difetto è un **intervallo time-of-check / time-of-use tra il rilascio del riferimento e la distruzione dell'oggetto** nel percorso di distruzione della finestra, senza una sincronizzazione adeguata rispetto a un consumer concorrente che convalida handle.

Ridotto alla sua forma:```c
/* Thread A — teardown */
NtUserDestroyWindow(HWND hwnd)
{
    PWND pWnd = ValidateHwnd(hwnd);
    if (pWnd) {
        ObfDereferenceObject(pWnd);   /* reference released */

        /* <-- race window: object may become reclaimable here */

        FreeWindowObject(pWnd);       /* teardown proceeds on a pointer
                                         no longer guaranteed live      */
    }
}

(Mostra il menu completo con tutti gli argomenti, le loro descrizioni e i valori predefiniti. Questo parametro non richiede un valore, basta inserirlo come '--help')```c /* Thread B — consumer, concurrent / NtUserMessageCall(HWND hwnd, UINT msg, ...) { PWND pWnd = ValidateHwnd(hwnd); / may resolve a handle whose object is mid-teardown */

if (pWnd->fnid == FNID_BUTTON)    /* use-after-free */
    ...

}

Due cose devono essere vere perché questo conti, ed entrambe lo erano:

**(a) La finestra è reale.** `ValidateHwnd` è il gate che dovrebbe rendere sicuro l'accesso basato sugli handle. Se la validazione può avere successo contro un oggetto la cui distruzione è già iniziata, il gate non è un gate — è un suggerimento.

**(b) La memoria liberata è influenzabile dall'attaccante.** I campi letti subito dopo la validazione includono `fnid`, che guida il dispatch dei messaggi. Una decisione di dispatch presa da memoria recuperata è la differenza tra *"crash inaffidabile"* e *"violazione del confine di sicurezza"*. Questa distinzione è l'intera ragione per cui questa è CWE-362 con impatto EoP e non un bug di stabilità.

> La **corruzione** osservata è una use-after-free; la **causa** è CWE-362, esecuzione concorrente che usa una risorsa condivisa con sincronizzazione impropria. Sono due affermazioni diverse e a MSRC interessa la seconda. **Riporta la causa, non solo il sintomo.**

### Perché le race condition in win32k sono strutturalmente più difficili di quanto sembrano

Se hai fatto race in altri sottosistemi, win32k ti frustrerà, perché l'architettura ti combatte in tre modi specifici.
Scarica lo strumento