在具有 UEFI 安全启动的机器上如何支持休眠?

信息安全 操作系统 硬件 开机 uefi
2021-09-09 22:40:03

我一直在学习UEFI Secure Boot,它试图通过锁定引导过程来防止“bootkits”,以便只能加载签名的引导加载程序和内核。

休眠似乎是一个主要的攻击媒介。休眠(也称为挂起到磁盘)涉及将整个内存状态(包括所有内核内存)写入磁盘。将此状态写入磁盘后,您可以关闭电源。当电源恢复时,您可以通过从磁盘读取此状态并将其写入内存来恢复。是什么阻止了攻击者修改磁盘上内存的休眠状态,例如修改内核内存以将恶意软件注入内核?当用户恢复时,似乎这会将一个现在被感染的操作系统内核加载到内存中。

同样,恶意恶意软件可能会创建一个精心设计的休眠文件(包含真实休眠文件的修改版本,经过修改以将恶意软件插入运行的内核),然后强制重启。重新启动后,我认为这会将休眠的映像加载到内存中——这似乎违反了 UEFI 安全启动的安全目标。

我怀疑我让自己感到困惑或不知何故扭曲了。任何人都可以清除这个吗?休眠是否与 UEFI 安全启动兼容?它是否对 UEFI 安全启动的目标构成任何安全风险,如果是,在 UEFI 安全启动的部署使用中如何解决这些风险?

3个回答

休眠是否与 UEFI 安全启动兼容?

为此,您需要查看 UEFI 规范的第 27 节。在本规范中,您将看到正在使用的协议的完整说明。我将简要总结一下 - 这是一个粗略的解释,可能有松散的边缘(如果你想要一个明确的解释,找一个 UEFI 人:)):

  • EFI_AUTHENTICATION_INFO_PROTOCOL部分定义了许多方法,用于为许多不同的实现获取和设置身份验证信息。
  • 签署 UEFI 驱动程序(支持 UEFI 固件的应用程序)。由于 UEFI 可执行文件基于 Windows PE 映像文件格式,因此您可以将其视为 EFI 模块的身份验证代码。
  • EFI_HASH_PROTOCOL 提供用于散列的编程 API。
  • 然后是有趣的部分:固件/操作系统密钥交换这负责注册平台密钥。EFI指的是两种模式:

    • 设置模式
    • 用户模式 ​​前一种模式是指没有注册密钥的设置,后一种模式是指有注册密钥的设置。

    注册的密钥是可以信任图像签名的私钥根。

  • 将公钥传递给操作系统固件部分正是它听起来的样子——一种用于通知固件它应该用来与操作系统对话的密钥的协议。
  • UEFI 映像验证是指根据签名数据库检查 UEFI 映像(引导加载程序等)的过程。
  • 签名数据库是已使用平台密钥签名的有效 UEFI 映像的列表。映像必须与签名数据库中的签名匹配才能启动。

涵盖这些 EFI 规范细节的原因是指出 UEFI 安全启动规范涵盖了 UEFI 安全启动的扩展程度——也就是说,它旨在实现两件事:

  • 如果启用 UEFI 安全启动并注册了平台密钥(由平台所有者完成),UEFI 加载程序将仅加载签名数据库中存在签名的 EFI 映像。
  • UEFI 规范提供了一种在操作系统和 UEFI 固件之间传递信息以询问签名数据库和 EFI 变量的方法。

这里重要的一点是,不需要 EFI 映像(一旦加载)或 OS 内核(一旦加载)就可以强制对随后加载的任何内容进行签名。

例如;

  • Fedora 将强制对内核和相应的模块进行签名 - 请参阅此状态更新 和此
  • 阅读这篇关于 Fedora EFI 引导过程中的 UEFI shim 的文章。此 shim 可以选择设置 UEFI 变量,以禁用对引导过程后期部分(如内核)的签名检查。更详细
  • Ubuntu 本身不会签署它的内核

    因此,我们只需要对引导加载程序二进制文件进行身份验证。Ubuntu 不需要签名的内核映像或内核模块。

所以,好的,让我们回到 UEFI:

同样,恶意恶意软件可能会创建一个精心设计的休眠文件(包含真实休眠文件的修改版本,经过修改以将恶意软件插入运行的内核),然后强制重启。重新启动后,我认为这会将休眠的映像加载到内存中——这似乎违反了 UEFI 安全启动的安全目标。

是的。对于当前的操作系统来说,这是一个非常好的攻击媒介,它起源于页面文件攻击

这两种攻击都是有效的,因为内核(在 Windows 内核的情况下过去常常如此)盲目地将数据从磁盘加载回 RAM。正确的修改使您可以更改驱动程序,安装自己的驱动程序等,然后离开,环 0 和一个受损系统。

在 UEFI 安全启动环境中,EFI 固件保证您的引导加载程序在关闭 EFI 固件并继续运行操作系统之前不会被篡改。就是这样。UEFI 安全启动不保证加载的操作系统未修改,或者加载的操作系统已从引导加载更改的映像。这取决于操作系统来检查和执行。

现在一些个人想法:

是否会对 UEFI 安全启动的目标造成任何安全风险

我想确实如此,因为您对 UEFI 安全启动的期望是一个健全的状态内核。这不是你保证会得到的,但它是你所期望的。

在 UEFI 安全启动的部署使用中如何解决这些风险?

我认为更准确地说,这些风险正在通过 AuthentiCode 等代码签名计划得到全面缓解。例如,64 位 Windows 不会加载未签名的驱动程序代码,除非您执行涉及 F8 和启动菜单的特殊舞蹈。大多数 Microsoft 映像都已签名,并且 - 我不知道但会猜测 -ntkrnlmp.exe由 Microsoft EFI 引导加载程序签名和验证。

如您所见,Fedora 等发行版肯定采用了这种方法,因为如果您只是获得了经过验证的引导加载程序,那么整个系统的安全性就没有多大意义。

我怀疑这个过程的下一个阶段是关闭攻击媒介,例如休眠。例如,页面文件攻击被微软修复。如果您认为您只需要一个签名校验和,那么修复它是微不足道的,例如,您可以使用存储在 EFI 固件中的一个密钥生成该校验和,并在引导加载程序或内核中进行验证。

易受攻击但可寻址

正如 user2213 所指出的,UEFI 安全启动规范中的任何内容都无法阻止休眠文件攻击。

解决方案是对系统卷和任何包含分页/休眠数据的卷使用全盘加密。Windows 有 Bitlocker,Linux 有 LUKS。

在典型的 Windows 安装中,您只需加密 C:\ 即可防止这种攻击,因为 hiberfil.sys 默认存储在那里。

由于在现代 CPU 上执行 AES 的开销很低,因此加密所有驱动器可能是个好主意。英特尔 CPU 支持 AES 硬件加速已有大约十年的时间。

实际上,操作系统需要做的只是验证内存映像是否已更新。这可以通过让操作系统引导加载程序在加载磁盘映像时对其进行散列来验证。只要哈希存储在安全的地方,并且图像是从固件验证的引导加载程序内部验证的,那么一切都是安全的。