此仓库包含针对 SEV 固件中一个漏洞的利用程序。该利用程序允许在 SEV-SNP 客户机关闭后解密其任意内存。
已在 1.55.16 版本上测试(目前最新版)。
snp_reclaim_buffer 无条件地尝试写回 RMP 更改,即使地址不在 RMP 覆盖范围内。如果 address 不在 RMP 覆盖范围内,RMP 条目 page_rmp_paddr 的地址永远不会被正确初始化,并保持其初始值 0。因此固件尝试将 RMP 条目的更改写回地址 0。这很糟糕,因为地址 0 在 RMP 覆盖范围内,不应该在没有更多检查的情况下被写入。如果 address 在 RMP 覆盖区域之外,page_rmp_entry 从未被正确初始化,并包含来自栈的垃圾内存。这个垃圾内存在实践中是恒定的。
有一个注释正是警告这种代码模式,这也是为什么如果我不是第一个报告此问题的人,我也不会感到惊讶。
当管理程序请求退出环形缓冲区模式时,snp_reclaim_buffer 被调用,传入 SEV 环形缓冲区的状态页地址。该地址是攻击者可控的。对此地址有一些检查,但默认页面(即 RMP 覆盖区域之外的页面)被明确允许。
我们可以通过在地址 0 放置一个客户机上下文页来利用这次对地址 0 的写入。方便的是,客户机上下文页的第一个字段是 UMC 密钥种子,其大小与 RMP 条目完全相同(都是 16 字节)。通过欺骗固件将更改写回地址 0,我们可以破坏 UMC 密钥种子。被写入的未初始化 RMP 条目总是相同的,因此被破坏的 UMC 密钥种子也几乎总是相同的:RMP 条目中的子页计数(9 位)没有被写入,但所有其他字段都被写入。通过重复创建新的客户机上下文页,每次会有不同的随机初始子页计数,我们可以最终创建多个具有相同 UMC 密钥种子的客户机。
要利用该漏洞,我们可以执行以下步骤:
0 创建一个客户机上下文页。0 创建一个客户机上下文页。SNP_DBG_ENCRYPT 命令,通过攻击者客户机的上下文页解密受害者客户机的内存。这将成功,因为受害者客户机和攻击者客户机共享一个 UMC 密钥种子。由于我们只能在客户机关闭后才能解密内存,即使我们能够访问客户机的秘密,也无法创建伪造的认证报告。只有当客户机在关闭前已被迁移到另一个主机时,我们才能创建伪造的认证报告:在这种情况下,来自已关闭客户机的秘密(即 VMPCK)也将在新的已迁移实例上生效。
但在实践中,许多应用程序存储其他敏感信息(如私钥、磁盘加密密钥),这些信息可能通过此利用程序泄露。
RMP 条目只应在页面不处于默认状态时写回。