Un’istruzione x86 che impiega più di un secondo per terminare sembra quasi un errore di progettazione. Eppure proprio un’operazione così lenta può mettere in crisi una delle assunzioni su cui poggia da decenni la sicurezza del firmware dei PC. Il progetto pubblicato su GitHub dal ricercatore Christopher Domas, mostra che mantenendo occupato un core della CPU abbastanza a lungo, è possibile impedirgli temporaneamente di partecipare alla sincronizzazione richiesta dal System Management Mode (SMM).
SMM fa parte dell’architettura x86 da decenni e continua a svolgere funzioni firmware di basso livello sui sistemi moderni: il codice SMM eseguito in questa speciale modalità della CPU lavora in un’area di memoria riservata, chiamata SMRAM, che Windows, Linux e gli altri sistemi operativi non possono normalmente leggere o modificare. Quando il firmware deve svolgere alcune operazioni di basso livello, il processore interrompe per un momento ciò che sta facendo e passa a questo ambiente separato, molto più privilegiato del normale kernel del sistema operativo. Se il codice firmware che gira in questa modalità contiene un errore, un attaccante potrebbe sfruttarlo per intervenire su parti del sistema che il software ordinario non può raggiungere.
La ricerca di Domas non dimostra un metodo universale per compromettere qualsiasi PC x86. Il proof-of-concept pubblicato è calibrato su un chip AMD Ryzen 7 5800H basato su Zen 3, dipende fortemente dalle caratteristiche della piattaforma e richiede accessi privilegiati al sistema.
SMM protegge le operazioni più delicate del firmware
L’uso di SMM può entrare in gioco, per esempio, nella gestione di alcune funzioni hardware, dell’alimentazione, della piattaforma e di servizi firmware che richiedono privilegi molto elevati. Quando arriva un’apposita interruzione, chiamata SMI (System Management Interrupt), la CPU sospende temporaneamente il normale flusso di lavoro ed esegue il codice previsto dal firmware in una regione di memoria protetta.
Sui sistemi multicore c’è però una regola fondamentale: mentre uno dei core lavora in SMM, anche gli altri devono essere portati nella stessa modalità o comunque fermati. Se un core continuasse a eseguire codice ordinario, potrebbe modificare dati in RAM proprio mentre il firmware li sta controllando o utilizzando. Per evitare questa situazione, il firmware attende che tutti i core si sincronizzino.
Nell’implementazione EDK II analizzata da Domas, esiste un timeout nell’ordine di un secondo. Ed è proprio qui che nasce l’idea del ricercatore: tenere intenzionalmente occupato un core abbastanza a lungo da fargli perdere questo “appuntamento”.
Come un’istruzione lentissima può mandare fuori sincronia i core
Per riuscire nell’intento, non basta eseguire un programma molto pesante o un ciclo infinito, perché la CPU continuerebbe a completare singole istruzioni e potrebbe quindi rispondere all’interruzione del firmware. Domas ha cercato invece una singola istruzione eccezionalmente lenta.
Sul Ryzen 7 5800H usato per il test ha ottenuto il risultato leggendo un particolare indirizzo MMIO, cioè un’area attraverso la quale la CPU comunica direttamente con l’hardware. L’accesso risulta talmente lento da mantenere il core impegnato a lungo: a quel punto il proof-of-concept fa partire ripetutamente degli SMI da un altro core.
Se i diversi core che compongono la CPU (in questo caso un chip AMD Ryzen) registrano un numero differente di SMI, significa che per un certo intervallo non hanno partecipato tutti insieme alla stessa esecuzione SMM. Il risultato è esattamente ciò che il meccanismo di sincronizzazione dovrebbe impedire.
Tornano a galla fino a 100 vulnerabilità lato firmware
La conseguenza concreta riguarda soprattutto vecchie vulnerabilità del firmware basate su una condizione di tipo TOCTOU (Time-of-Check to Time-of-Use), cioè sul tempo che passa tra il controllo di un dato e il suo successivo utilizzo. Immaginiamo che il codice SMM legga dalla RAM un indirizzo fornito dal sistema operativo, controlli che punti a una zona lecita e, qualche istante dopo, lo utilizzi.
Se tutti gli altri core sono fermi, nessuno può cambiare quel valore durante l’operazione. Se invece un core resta attivo fuori da SMM, può tentare di modificarlo proprio dopo il controllo ma prima dell’utilizzo. Un bug che in passato appariva poco sfruttabile senza un dispositivo capace di modificare direttamente la memoria potrebbe quindi diventare sfruttabile interamente via software.
Domas cita oltre 100 vulnerabilità SMM di questa famiglia e sottolinea però un limite importante: il suo progetto dimostra che la finestra temporale necessaria all’attacco può realmente aprirsi. Per sfruttarla servono ancora una vulnerabilità SMM adatta, privilegi elevati sul sistema e una tecnica calibrata sulla specifica piattaforma.
Conclusioni: una vecchia assunzione di sicurezza non è più così solida
Il lavoro di Domas è interessante soprattutto perché non introduce una nuova vulnerabilità SMM nel senso classico del termine: mette invece in discussione una condizione che per anni ha contribuito a rendere molti bug firmware difficili da sfruttare. Se il software in SMM presume che tutti gli altri core siano effettivamente fermi, basta dimostrare che questa garanzia può venir meno per cambiare la valutazione di rischio di vulnerabilità già note.
Abbiamo detto che il proof-of-concept resta fortemente dipendente dall’hardware e richiede privilegi elevati, quindi non descrive un attacco immediatamente utilizzabile contro qualsiasi PC. Il fatto è che la tecnica sposta l’attenzione dal singolo bug alla robustezza del meccanismo di sincronizzazione stesso.
Firmware e handler SMM non dovrebbero affidarsi soltanto all’idea che nessun altro core possa modificare la memoria condivisa mentre eseguono controlli sensibili: i dati devono essere validati, copiati e gestiti assumendo che possano cambiare in momenti inattesi. Si apre così, soprattutto in prospettiva, una breccia che non può e non deve essere sottovalutata.