
Exploit per la vulnerabilità del firmware AMD SEV-SNP (CVE-2023-31355) che decifra la memoria arbitraria di guest dismessi corrompendo il seed della chiave UMC tramite una scrittura di voce RMP non inizializzata all'indirizzo zero.
Questo repository contiene un exploit per una vulnerabilità nel firmware SEV. L'exploit consente di decrittare memoria arbitraria di un guest SEV-SNP dopo che è stato decommissionato.
Testato sulla versione 1.55.16 (la più recente al momento della stesura).
snp_reclaim_buffer tenta incondizionatamente di riscrivere le modifiche all'RMP anche quando l'indirizzo non è coperto dall'RMP. Se address non è coperto dall'RMP, l'indirizzo della voce RMP page_rmp_paddr non viene mai inizializzato correttamente e rimane al suo valore iniziale di 0. Di conseguenza, il firmware tenta di riscrivere le modifiche della voce RMP all'indirizzo 0. Questo è un problema perché l'indirizzo 0 è coperto dall'RMP e non dovrebbe essere scritto senza ulteriori controlli. Se address è al di fuori dell'area coperta dall'RMP, page_rmp_entry non viene mai inizializzato correttamente e contiene memoria spazzatura proveniente dallo stack. In pratica, questa memoria spazzatura è sempre la stessa.
C'è un commento che mette in guardia esattamente su questo pattern di codice, motivo per cui non sarei sorpreso se non fossi il primo a segnalarlo.
snp_reclaim_buffer viene chiamato con l'indirizzo della pagina di stato dei ring buffer SEV quando l'hypervisor richiede l'uscita dalla modalità ring buffer. Questo indirizzo è controllato dall'attaccante. Ci sono alcuni controlli per questo indirizzo, ma le pagine di default (cioè le pagine al di fuori dell'area coperta dall'RMP) sono esplicitamente consentite.
Possiamo sfruttare questa scrittura all'indirizzo 0 posizionando lì una pagina di contesto del guest. Opportunamente, il primo campo della pagina di contesto del guest è l'UMC key seed, che ha esattamente la stessa dimensione di una voce RMP (entrambi sono di 16 byte). Inducendo il firmware a riscrivere le modifiche all'indirizzo 0, possiamo corrompere l'UMC key seed. La voce RMP non inizializzata che viene scritta è sempre la stessa, quindi anche l'UMC key seed corrotto sarà sempre quasi identico: il conteggio delle sottopagine (9 bit) nella voce RMP non viene scritto, ma tutti gli altri campi sì. Creando ripetutamente nuove pagine di contesto del guest, che avranno ogni volta conteggi iniziali delle sottopagine casuali diversi, possiamo alla fine creare più guest con lo stesso UMC key seed.
Per sfruttare la vulnerabilità possiamo eseguire i seguenti passaggi:
0 per il guest vittima.0 per il guest attaccante.SNP_DBG_ENCRYPT per decrittare la memoria del guest vittima utilizzando la pagina di contesto del guest attaccante. L'operazione riuscirà perché il guest vittima e il guest attaccante condividono lo stesso UMC key seed.Poiché possiamo decrittare la memoria solo dopo che il guest è stato decommissionato, non è possibile creare report di attestazione contraffatti, anche se abbiamo accesso ai segreti del guest. Possiamo creare report di attestazione contraffatti solo se il guest è stato migrato su un altro host prima di essere decommissionato: in questo caso, i segreti (cioè i VMPCK) del guest decommissionato funzioneranno anche sulla nuova istanza migrata.
In pratica, però, molte applicazioni memorizzano altre informazioni sensibili (ad esempio chiavi private, chiavi di crittografia del disco) che possono essere esfiltrate utilizzando questo exploit.
La voce RMP dovrebbe essere riscritta solo se la pagina non era nello stato di default.