
Exploit per CVE-2024-21980 che mira al firmware AMD SEV per decrittare la memoria arbitraria di guest SEV-SNP dismessi tramite un bypass dell'applicazione del buffer di comando.
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 dismesso.
Testato sulla versione 1.55.16 (l'ultima al momento della scrittura).
Il firmware SEV ha una tabella chiamata master_handler_table contenente i puntatori a funzione per tutti i comandi, con alcune proprietà aggiuntive rilevanti per i comandi. Due di queste proprietà aggiuntive sono cmd_buf_type e snp_cmd_buf_enforcement. cmd_buf_type determina se il buffer dei comandi deve essere copiato dalla/e verso la memoria dell'host. snp_cmd_buf_enforcement determina se queste operazioni di copia devono essere soggette a controlli che verificano che la memoria che supporta il buffer dei comandi sia nello stato FIRMWARE o DEFAULT. I comandi per cui cmd_buf_type è CMD_BUF_OUTPUT_ONLY, CMD_BUF_INPUT_AND_OUTPUT o CMD_BUF_INPUT_AND_OUTPUT_ERROR dovrebbero tutti avere snp_cmd_buf_enforcement impostato a true. In caso contrario, la riscrittura dell'output del comando potrebbe causare corruzione della memoria all'interno dell'area coperta da RMP. snp_cmd_buf_enforcement è true per tutti questi comandi con un'eccezione - SEV_MCMD_ID_ATTESTATION: questo comando ha cmd_buf_type impostato a CMD_BUF_INPUT_AND_OUTPUT_ERROR, ma ha anche snp_cmd_buf_enforcement impostato a false. Di conseguenza è possibile eseguire SEV_MCMD_ID_ATTESTATION con un buffer dei comandi che punta a memoria coperta da RMP e far sì che quella memoria venga corrotta una volta che l'output viene riscritto.
Non vedo perché SEV_MCMD_ID_ATTESTATION debba essere un'eccezione; mi sembra plausibile che possa essere un errore di battitura/copia-incolla.
SEV_MCMD_ID_ATTESTATION scrive solo un singolo campo length (4 byte) nel buffer dei comandi e quindi questi sono gli unici byte che possiamo usare per corrompere la memoria. SEV_MCMD_ID_ATTESTATION scrive sempre lo stesso valore - 0x000000d0. Fortunatamente non ci sono requisiti di allineamento sul buffer dei comandi e quindi possiamo spostare ripetutamente il buffer dei comandi per corrompere un'area più ampia di memoria contigua. Useremo questo per corrompere i primi 16 byte di una pagina di contesto del guest con un pattern statico. Quei primi 16 byte contengono il seed della chiave UMC e quindi forzandolo a un valore statico, possiamo forzare la chiave di cifratura del guest a un valore statico.
L'exploit qui fornito è fortemente basato su quello che ho fornito per SWPSIRT-2684/CVE-2023-31355.
Per sfruttare la vulnerabilità possiamo eseguire i seguenti passaggi:
SEV_MCMD_ID_ATTESTATION. Tieni questo guest in esecuzione.0x2000 per il guest vittima. Qualsiasi altro indirizzo nell'area coperta da RMP andrebbe bene, anche se un indirizzo fisso è utile per il debug.0x2000 per il guest attaccante. Deve essere lo stesso indirizzo usato nel passaggio 1.SNP_DBG_ENCRYPT per decrittare la memoria del guest vittima usando la pagina di contesto del guest attaccante. Questa operazione avrà successo perché il guest vittima e il guest attaccante condividono un seed della chiave UMC.L'impatto qui dovrebbe essere almeno lo stesso di SWPSIRT-2684. Non mi è chiaro al momento se questo bug possa essere usato per decrittare la memoria di un guest in esecuzione prima che venga dismesso.
snp_cmd_buf_enforcement dovrebbe essere impostato a true per SEV_MCMD_ID_ATTESTATION.
È interessante notare che le patch di supporto host Linux KVM non devono essere aggiornate perché elencano già SEV_CMD_ATTESTATION_REPORT in sev_cmd_buf_writable come un comando che richiede che il suo buffer dei comandi sia nello stato FIRMWARE. Potrebbero essere necessarie o meno modifiche per altri hypervisor.