Spectre non muore mai: la nuova variante BTR torna a colpire Linux e le CPU moderne

Pensavamo di esserci lasciati #Spectre alle spalle. E invece no: una nuova tecnica chiamata #BranchTargetReuse dimostra che le #CPU possono continuare a “ricordare” vecchie previsioni anche dopo che il codice è stato sostituito, fino a permettere a un processo senza privilegi di leggere la memoria del #Kernel e arrivare, in pochi minuti, all’hash della password…

Vi ricordate Spectre? La vulnerabilità, uscita insieme a Meltdown, nel 2018 ha messo in discussione il modo in cui le CPU moderne cercano di andare più veloci “indovinando” il futuro. Nel 2024 poi, la stessa si era evoluta in una V2 che a sua volta aveva richiesto interventi.

La storia sembrava chiusa dopo fix al microcode, mitigazioni e Kernel più “lenti”, e invece torna con una nuova variante chiamata Branch Target Reuse (BTR).

I ricercatori di VUSec della Vrije Universiteit Amsterdam e della Scuola Superiore Sant’Anna di Pisa hanno dimostrato che è possibile leggere memoria arbitraria del Kernel Linux partendo da codice non privilegiato, arrivando a recuperare l’hash della password di root dalla memoria di un processo su. La ricerca, intitolata Branch Target Reuse: Practical Spectre-v2 Attacks in JIT Engines via Stale Branch Prediction Entries, è stata accettata alla conferenza ACM CCS 2026 e insieme al paper è stato pubblicato anche il codice dell’attacco.

Ma cosa si “riusa” esattamente?

Per capirlo bisogna tornare al funzionamento di Spectre-v2. Le CPU moderne cercano di prevedere dove porterà un salto prima ancora di conoscerne realmente la destinazione, così da iniziare a eseguire in anticipo le istruzioni che probabilmente serviranno. Se la previsione è sbagliata, il risultato viene scartato, ma alcune tracce dell’esecuzione speculativa possono comunque rimanere nella cache ed essere misurate attraverso un side-channel. BTR sfrutta questo comportamento in maniera particolare: invece di convincere il processore a saltare verso un indirizzo diverso, lascia invariato l’indirizzo e cambia ciò che si trova al suo interno.

Qui entrano in gioco i motori JIT, che durante il normale funzionamento generano, eliminano e sostituiscono continuamente codice macchina. Una regione utilizzata pochi istanti prima può quindi essere liberata e successivamente occupata da nuove istruzioni. Quando questo succede, la CPU vede correttamente il nuovo codice, ma alcune informazioni utilizzate per prevedere i salti possono sopravvivere alla sostituzione. Il processore può quindi effettuare una previsione basata sul vecchio utilizzo di quell’indirizzo ed eseguire speculativamente il nuovo codice che nel frattempo ha preso il suo posto.

Gli autori lo definiscono speculative execute-after-free, un nome che richiama le classiche use-after-free, che sono alla base di moltissimi attacchi odierni: in questo caso non viene riutilizzato un oggetto dopo la sua liberazione, ma una previsione relativa a codice che nel frattempo non esiste più. In pratica, per il programma quella regione contiene ormai istruzioni completamente nuove, mentre una parte dello stato interno della CPU continua a conservare informazioni relative a ciò che si trovava lì prima.

Da una previsione sbagliata alla password di root

La parte interessante è che i ricercatori non si sono fermati a dimostrare il comportamento della CPU, ma hanno costruito un exploit funzionante contro Linux. Per farlo hanno preso di mira il JIT di classic BPF (cBPF). Mentre il più potente eBPF è ormai fortemente limitato per gli utenti non privilegiati, classic BPF rimane raggiungibile attraverso funzionalità del Kernel come socket filtering e seccomp ed è utilizzato anche da software come Docker e Chrome. Di conseguenza, disabilitare unprivileged eBPF non basta a rimuovere il vettore utilizzato dalla ricerca. Attraverso BTR l’attaccante riesce a sfruttare il codice generato dal JIT per far eseguire speculativamente alla CPU determinate operazioni e dedurre successivamente il contenuto della memoria osservando gli effetti lasciati nella cache. Gli autori hanno inoltre dimostrato che l’attacco può funzionare anche con bpf_jit_harden, l’opzione del Kernel che utilizza la constant blinding per rendere più difficile controllare il codice prodotto dal JIT.

Il risultato è una lettura della memoria del Kernel di circa 8 byte al secondo sulle CPU Intel utilizzate nei test. Una velocità ridicola se pensiamo a un normale dump della RAM, ma più che sufficiente quando sappiamo cosa cercare. Nella dimostrazione l’exploit individua infatti i processi presenti nel sistema, attraversa le relative page table e arriva alla memoria di un processo su. Da lì i ricercatori sono riusciti a recuperare l’hash della password di root in circa 3 minuti su Raptor Cove e 5 minuti su Lion Cove. Ovviamente avere l’hash non significa conoscere automaticamente la password: per arrivare alla password in chiaro serve ancora un attacco offline, ad esempio con John the Ripper o hashcat, e il risultato dipende dall’algoritmo utilizzato e soprattutto dalla robustezza della password.

L’aspetto più importante, però, è un altro: codice eseguito senza privilegi è riuscito a recuperare informazioni dalla memoria del Kernel, ed è questo che trasforma BTR da un comportamento microarchitetturale interessante a un attacco concreto.

Linux è stato corretto, ma BTR rimane interessante

BTR richiede già la possibilità di eseguire codice sulla macchina bersaglio, quindi non stiamo parlando di una vulnerabilità sfruttabile direttamente da remoto. Inoltre, l’exploit Linux completo presentato dai ricercatori è stato realizzato sulle CPU Intel e non sono stati dimostrati attacchi BTR tra macchine virtuali. Il comportamento microarchitetturale alla base della ricerca non sembra però essere una particolarità di una singola CPU: durante gli esperimenti è stato osservato anche sui processori AMD e Arm testati dagli autori. Gli stessi principi sono stati sperimentati anche fuori dal Kernel Linux utilizzando motori JIT come SpiderMonkey di Firefox e GraalVM, senza però arrivare allo stesso livello di exploit ottenuto con cBPF.

Sul Kernel Linux il problema è stato affrontato modificando proprio il momento in cui viene riutilizzata la memoria destinata al codice BPF. Le correzioni sono associate principalmente a CVE-2026-64507 e CVE-2026-64508 e introducono, tra le altre cose, l’utilizzo di IBPB, Indirect Branch Predictor Barrier, nel percorso interessato. In parole molto semplici, quando quella memoria viene riutilizzata il Kernel può chiedere alla CPU di invalidare lo stato del branch predictor che BTR potrebbe sfruttare, evitando che una vecchia previsione sopravviva abbastanza a lungo da diventare utile all’attaccante. La seconda correzione introduce inoltre ulteriori protezioni contro tecniche di JIT spraying.

Le patch sono state riportate anche sui Kernel stabili supportati, quindi per chi utilizza Linux la soluzione non è particolarmente esotica: installare gli aggiornamenti di sicurezza della propria distribuzione e riavviare il sistema per assicurarsi di stare effettivamente utilizzando il Kernel aggiornato. Ed è forse proprio questo il risultato più interessante di BTR. Spectre ci ha abituati all’idea che l’esecuzione speculativa possa lasciare dietro di sé informazioni che, dal punto di vista del programma, non dovrebbero esistere. Questa volta il problema fa un passo ulteriore dato che sostituire correttamente il codice non significa necessariamente cancellare tutto quello che la CPU aveva “imparato” su quel codice.

Red Team & Offensive Security Engineer
Parlo di sicurezza informatica offensive, Linux e Open Source

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *