
AMD SEV-SNP 펌웨어 취약점(CVE-2023-31355)에 대한 익스플로잇으로, 초기화되지 않은 RMP 항목을 주소 0에 기록하여 UMC 키 시드를 손상시켜 폐기된 게스트의 임의 메모리를 복호화합니다.
이 저장소는 SEV 펌웨어의 취약점에 대한 익스플로잇을 포함합니다. 이 익스플로잇은 SEV-SNP 게스트가 해제(decommission)된 후 임의의 메모리를 복호화할 수 있게 합니다.
버전 1.55.16(작성 시점 기준 최신 버전)에서 테스트되었습니다.
snp_reclaim_buffer는 주소가 RMP에 포함되지 않은 경우에도 무조건 RMP 변경 사항을 다시 쓰려고 시도합니다. address가 RMP에 포함되지 않은 경우, RMP 항목의 주소인 page_rmp_paddr는 제대로 초기화되지 않고 초기값인 0으로 유지됩니다. 그 결과 펌웨어는 RMP 항목의 변경 사항을 주소 0에 다시 쓰려고 시도합니다. 주소 0은 RMP에 포함되어 있으며 추가 검사 없이 쓰여져서는 안 되기 때문에 이는 문제입니다. address가 RMP 적용 영역 밖에 있는 경우 page_rmp_entry는 제대로 초기화되지 않고 스택의 쓰레기 메모리를 포함합니다. 이 쓰레기 메모리는 실제로는 일정(constant)합니다.
정확히 이 코드 패턴에 대해 경고하는 주석이 있는데, 이것이 제가 이 문제를 처음 보고한 사람이 아닐 수도 있다는 것에 놀라지 않는 이유이기도 합니다.
snp_reclaim_buffer는 하이퍼바이저가 링 버퍼 모드 종료를 요청할 때 SEV 링 버퍼의 상태 페이지 주소와 함께 호출됩니다. 이 주소는 공격자가 제어할 수 있습니다. 이 주소에 대한 일부 검사가 있지만 기본(default) 페이지(즉, RMP 적용 영역 밖의 페이지)는 명시적으로 허용됩니다.
주소 0에 게스트 컨텍스트 페이지를 배치함으로써 이 주소 0에 대한 쓰기를 악용할 수 있습니다. 편리하게도 게스트 컨텍스트 페이지의 첫 번째 필드는 UMC 키 시드로, RMP 항목과 정확히 같은 크기입니다(둘 다 16바이트). 펌웨어가 변경 사항을 주소 0에 다시 쓰도록 속임으로써 UMC 키 시드를 손상시킬 수 있습니다. 쓰여지는 초기화되지 않은 RMP 항목은 항상 동일하므로, 손상된 UMC 키 시드도 항상 거의 동일하게 됩니다. RMP 항목의 하위 페이지 개수(subpage count, 9비트)는 쓰이지 않지만 다른 모든 필드는 쓰입니다. 매번 다른 무작위 초기 하위 페이지 개수를 가지는 새 게스트 컨텍스트 페이지를 반복적으로 생성함으로써, 결국 동일한 UMC 키 시드를 가진 여러 게스트를 만들 수 있습니다.
취약점을 악용하기 위해 다음 단계를 실행할 수 있습니다:
0에 피해자 게스트용 게스트 컨텍스트 페이지를 생성합니다.0에 공격자 게스트용 게스트 컨텍스트 페이지를 생성합니다.SNP_DBG_ENCRYPT 명령을 사용하여 공격자 게스트의 컨텍스트 페이지로 피해자 게스트의 메모리를 복호화합니다. 피해자 게스트와 공격자 게스트가 UMC 키 시드를 공유하기 때문에 이 작업은 성공합니다.게스트가 해제된 후에만 메모리를 복호화할 수 있다는 사실 때문에, 게스트의 비밀값에 접근할 수 있음에도 불구하고 위조 증명(attestation) 보고서를 생성하는 것은 불가능합니다. 게스트가 해제되기 전에 다른 호스트로 마이그레이션된 경우에만 위조 증명 보고서를 생성할 수 있습니다. 이 경우 해제된 게스트의 비밀값(예: VMPCK)이 새로 마이그레이션된 인스턴스에서도 작동합니다.
하지만 실제로 많은 애플리케이션은 이 익스플로잇을 사용하여 유출될 수 있는 다른 민감한 정보(예: 개인 키, 디스크 암호화 키)를 저장합니다.
RMP 항목은 페이지가 기본(default) 상태가 아닌 경우에만 다시 쓰여져야 합니다.