导读
Keynote
本文讲解了计算机硬件固件安全中的BIOS和UEFI机制,涉及如何测试、攻击者会如何感染固件以及虚拟化安全等话题。
如果在设备上发现了一个root权限的恶意软件,你会想到它可能感染了设备,但是否想过攻击者是通过底层硬件或者内核驱动实现的攻击?
本文解释了新的成熟方法,应对攻击者已经通过内核态驱动或固件植入实现root级别驻留的情形。
它提供了一系列测试步骤,让安全工程师判定,攻击者在已经获得用户模式漏洞下,为了达到root权限可能使用的攻击向量。
1. 硬件信任根
为了在恶意环境下,创建一个保持完整性和机密性的安全基础,出现了很多的技术,我们将它们归类于硬件信任根安全分类。
假设硬件厂商在卖设备时植入恶意代码,对设备开展固件配置分析就会非常重要。例如用于大规模数据传输的Amazon Snowball,如果它的底层固件不可信、做不到安全启动,那么用户数据以及整个数据中心就会面临风险。
2. Rootkits和Bootkits
Rootkits是允许攻击者代码在内核空间执行的持久机制。通过LKM(可加载内核模块)、现有内核模式驱动中的漏洞、内核暴露给用户空间进程的接口漏洞,均可获得Rootkits。
rootkit允许攻击者保持对系统的根级别访问,并通过允许直接修改内核空间内存结构,授予根用户额外的权限。
其中包括大量几乎没有文档记录的敏感系统配置结构,这些结构控制操作系统中的核心安全功能。
Bootkit与rootkit的不同之处在于它会感染主机的固件,而不仅仅是感染内核空间。Bootkits劫持部分启动过程,在系统启动过程中、启用安全保护之前,注入恶意代码。通过在启动过程的前期攻击系统,可以确保有机会破坏将来验证系统完整性的所有操作。
这个问题激发了对硬件信任根的需求。如果攻击者可以感染启动过程的任何部分,则防御者需要一个安全的空间,在该空间中可以存储密钥,并且可以在具备足够完整性保证的情况下执行加密操作。
需要一个经过物理安全审计的专用硬件模块来提供这个空间。这部分硬件被称为TPM(可信平台模块),是针对专用bootkit感染的最强大防御。
在深入了解如何正确配置系统以利用TPM之前,我们必须了解引导过程及其漏洞。
3. BIOS是什么,以及为什么重要
随着rootkit防御技术变得越来越复杂,与编写复杂rootkit相关的工作量也随之增加。这使得攻击者深入系统内部寻找更好的目标。如果防御者想跟踪它们并保护系统免受感染,我们必须了解BIOS(基本输入输出系统)。
BIOS最初是一种为更高级别的操作系统抽象准备系统的机制。在没有附加安全保护的最基本级别上,BIOS遵循以下步骤。
- BIOS初始化-硬件自检,热启动时跳过
- MBR(主引导记录)—>在硬盘上查找操作系统
- VBR(卷引导记录)->在驱动器中查找活动分区->运行初始程序加载程序(EFI可执行文件)
- bootmgr(Windows引导加载器)->读取BCD(包含内核代码签名策略的引导配置数据)
- winload.exe->加载操作系统内核模块、deps和ELAM(早期启动反恶意软件)模块。
- 内核映像启动->启动启动驱动程序
- 第一用户模式进程
每一层都依赖于前一层。作为一个攻击者,如果你破坏了一个较早的层,你就可以破坏发生在堆栈下的层,这些层依赖于该层。
4. 存在哪些安全机制?
有关测试用例的完整列表,请查看测试用例的CSV(https://maxfieldchen.com/raw/firmware-testcases.csv)。除了在这里找到的详尽列表之外,本节还将提供一些关于完成这些测试以及每个保护机制完成的内容的详细信息和上下文。
4.1 ELAM(早期启动反恶意软件)模块
此保护模块是从Windows 8开始引入的。这种保护的目的是要打败rootkit,但它不能抵御bootkit。
此机制允许安全软件注册内核模式驱动程序,该驱动程序保证在启动过程的早期,在任何非ELAM驱动程序之前启动。当加载任何未来的驱动程序时,ELAM加载的驱动程序有机会检查它,如果它是恶意的,则阻止加载它。
只有一部分信息可供ELAM驱动程序使用。
映像的名称映像注册为启动驱动程序的注册表位置驱动的发布者和签名者驱动的散列值和散列算法证书指纹及指纹算法
ELAM驱动程序无法访问驱动程序的内容,因此有多种可能的旁路,绕过在此处执行的表面级别的检查。
由于ELAM模块是在windows引导加载程序之后加载的,因此在引导过程的早期发生的任何bootkit破坏都可以使此保护无效。
测试步骤:验证ELAM策略注册表
ELAM模块使用写入注册表值的策略:
HKLM\System\CurrentControlSet\Control\EarlyLaunch\DriverLoadPolicy
可以使用标准注册表工具regedit.exe查看注册表值。此策略值确定了当ELAM模块找到无效驱动程序时会发生的情况。
该策略决定了ELAM模块是否只加载已知的好的驱动程序、好的驱动程序和未知的驱动程序,或者加载好的驱动程序、坏的基本的驱动程序和未知的驱动程序。最后一个选项允许加载已知的坏的基本驱动程序,以确保系统的稳定性,这是大多数系统的默认设置。
如果攻击者能够用恶意驱动程序替换基本驱动程序,需要检查默认设置是否更改,因为此保护将失效。
4.2 内核模式签名保护
此保护是从Windows Vista开始引入的。此保护的目的是确保所有内核模块都由已知方签名,以提高创建恶意内核模式驱动程序的相关成本。需要注意的是,这与PnP设备安装签名策略不同。后者签名策略要求在测试时进行单独的检查,如下一节所述。
当内核模式驱动程序加载到系统中时,将根据已知列表验证所有驱动程序。需要注意的是,在32位Windows上,只验证boot启动驱动程序,而其他所有驱动程序都不受保护,不会验证任何标记为提前开启的驱动程序。
负责执行此签名验证的逻辑存储在ci.dll文件。在Windows Vista和Windows7中,如果出现代码验证逻辑,则由内核映像(nt!g_CiEnabled)中的一个变量控制。
这是在内核模式的内存结构中设置的,任何内核模块都可以对其进行更改。如果在签名的第三方内核模块中发现代码执行,可以利用它加载任意LKM(可加载的内核模块)rootkit!
测试步骤:验证Windows版本
此安全问题已在Windows 8中修补,为了安全引导,不推荐使用该变量。如果项目需要硬件信任根,并且希望实现内核模式驱动程序签名以减轻rootkit和随后的bootkit感染,安全工程师应建议更新系统,使用Windows 8或更高版本。
此外,系统应使用64位版本的Windows。如果使用32位版本,则只验证引导启动驱动程序,这让攻击者可以安装恶意驱动程序(不将自己指定为引导启动驱动程序)。
测试步骤:检查启动配置数据注册表
要检查内核驱动程序签名验证是否已启用,请在以下位置查看注册表数据:
HKEY_LOCAL_MACHINE\BCD000000
检查以下参数,因为它们直接影响BIOS引导进程的安全状态:
BcdLibraryBoolean_DisableIntegrityCheck, BcdOSLoaderBoolean_WinPEMode, BcdLibraryBoolean_AllowPrereleaseSignature
确认这三个布尔值配置正确,并且没有禁用关键的安全机制。
4.3 PnP设备安装签名策略
即插即用设备安装签名策略为内核模式签名提供了一组单独的保护。PnP策略强制的要求仅适用于即插即用设备驱动程序。
此保护的目标是验证PnP驱动程序的发布者的身份和完整性。为了验证这些驱动程序,保护机制检查驱动程序是否由Windows硬件质量实验室(WHQL)或可信的第三方签名。
如果不满足这些要求,将向必须手动接受才能继续引导的用户显示警告提示。此策略仅在PnP驱动程序安装期间强制执行,而不是在以后的运行期间强制执行。这不是一个固有的漏洞,而是一组额外的验证,因为内核模式签名保护中描述的机制仍然适用于PnP驱动程序。
测试步骤:检查“禁用PnP签名注册表”
检查以下注册表项,查看是否已禁用PnP签名以允许内核模块调试:
HKLM\SYSTEM\CurrentControlSet\Control\CI\DebugFlag
如果此注册表设置为0x00000001,则在加载未正确签名的PnP驱动程序时将启动调试器。对系统具有本地访问权限的攻击者可以在调试器提示下按“g”以加载恶意驱动程序。
请确保将此注册表值设置为0x00000010,这表示应忽略任何调试器并拒绝驱动程序。
4.4 安全引导
安全引导是对BIOS启动过程的一次彻底检查,和后面的安全措施相配合。它改变了早期引导的流程,如下所示:
BIOS初始化-硬件自检,热启动时跳过UEFIbootmgr->winload.exe内核映像启动->引导启动驱动程序ELAM驱动程序内核模式引导启动驱动程序第一用户模式进程
理论上来说,当启用安全引导时,所有UEFI驱动程序都必须具有数字签名才能由系统加载。在实际中,有许多配置可以大大削弱或禁用此保护。在我们讨论这些之前,你需要了解一下UEFI。
4.5 通用可扩展固件接口
UEFI在几个关键方面不同于典型的BIOS进程。不再有MBR和VBR来定位代码。相反,GPT(GUID分区表)被配置为bootloader中指向FAT32 EFI系统分区的特殊分区。它在GPT条目中包含一个polyglot MBR条目,以防止只识别MBR的旧系统攻击这种新格式。
这个引导加载程序分区的路径由一个NVRAM变量控制(提示以后利用)。这里的引导加载程序负责查找操作系统内核加载程序并将控制权传递给它。此代码直接存储在主板上的SPI闪存中,并在启动时加载到RAM中。
操作系统加载程序由存储在EFI系统分区中的多个文件组成。需要注意的是,正是在这个引导加载程序中,控制从存储在SPI flash上的代码转移到存储在HDD上的代码。这是物理访问硬盘驱动器内存的攻击者有机会攻击的位置。如果禁用了安全引导,则可以在此处更改任何代码,因为在初始化windows内核之前,补丁保护不存在。
一旦控件从操作系统加载程序传输到winloader,启动服务将被删除,但所有运行时服务都已启用。值得注意的是,OS加载器启动后通过从hal.dll模块到内核模块,暴露出一组实时服务。此模块中的错误通常用作bootkit的插入点。这些服务包括读/写NVRAM变量的能力,通过压缩更新执行固件更新,以及重启/关闭设备。
UEFI规范
UEFI规范定义了4个不同的引导阶段。
- SEC-Security boot:查找PEI的加载程序并从SPI Flash运行
- PEI-Pre-EFI初始化:配置内存,执行基本的硬件操作,在tmp内存中运行,然后转换到perm内存。
- DXE-驱动程序执行环境:初始化系统管理模式(也称为ring-2)和DXE服务可执行文件。它还提供引导和运行时服务。
- BDS-引导驱动器选择:发现将使用GPT从中加载操作系统的硬件设备
测试步骤:SPI闪存位
许多配置都会严重削弱UEFI安全引导的安全性。以下内存位存储在SPI flash中,并控制安全引导的关键部分。我们应该始终检查通过内核模块直接写入SPI flash是否受到限制,以防止攻击者更改这些变量。
BIOSWE-BIOS写入启用位(0已锁定,1已解锁)BLE-BIOS锁定启用位(1被锁定,0被解锁)SMM_BWP-系统管理模式BIOS写保护位(1已锁定,0已解锁)PR(0-5)-SPI保护范围,有选择地防止写入BIOS
所有这些变量最初都是在驱动程序执行环境阶段设置的。为了验证这些变量,我强烈建议使用Intel提供的CHIPSEC(https://github.com/chipsec/chipsec)内核模块。本页底部参考资料部分提供了一个指南,介绍如何安装此工具。
要在安装CHIPSEC内核驱动程序后检查BIOS写保护位,请在根终端中运行以下命令:
chipsec_main.py -m common.bios_wp
如果PR范围都是0,那么它们根本没有被利用,应该设置为保护BIOS中的敏感内存区域。
5. 攻击者如何感染UEFI固件?
攻击者可以通过多种方式感染固件,但下面列出了最常见/最明显的方法:
修改未签名的UEFI选项ROM,这些ROM可能无法根据配置进行验证
添加/修改DXE驱动程序
替换/修改引导管理器(使用回退引导管理器)
修改回退引导加载程序EFI/BOOT/bootx64.EFI
添加辅助引导加载程序
绕过SPI写保护并设置敏感内存位以禁用保护
从具有根权限的用户空间,使用签名旁路插入内核代码,使用硬件抽象层接口访问系统管理模式。然后找到一种绕过SPI保护的方法,直接写入上面列出的一个早期启动阶段。
6. 回到安全引导
有三种形式的安全引导。
6.1 操作系统安全引导
这种形式的安全引导发生在操作系统引导加载程序中,只验证操作系统内核和引导启动驱动程序。
6.2 安全启动
此安全引导在UEFI固件中实现。在加载UEFI应用程序和驱动程序时,验证本身在驱动程序执行环境阶段进行。在BIOS的PEI或SEC阶段,感染仍然可能发生。
此外,如果攻击者能够破坏平台映像本身,他们将能够绕过此保护。
6.3 平台安全引导-使用TPM
这种形式的安全引导验证所有平台初始化固件,并在受信任的平台模块中运行。
最初,安全引导驱动程序验证在DXE中进行,然后在PEI中进行,但现在应该在TPM(可信平台模块)中进行,或者在只能通过Intel ME固件提供的现场可编程器件中进行。
测试步骤:重要的关键位置
这些签名存储在一个数据库中,该数据库位于SPI flash或NVRAM变量中,具体取决于实现方式。还有一个单独的Dbx数据库,其中包含一个黑名单公钥和哈希的列表,这些列表将被直接拒绝。
这些数据库受平台密钥或供应商密钥NVRAM变量(KEK)保护。此NVRAM变量应安全地存储在TPM中,并由平台密钥签名。
在安全参与过程中,必须验证平台和供应商密钥是否仅由合适的各方控制。数据库中已批准的签名者列表应仅限于系统操作所需的签名者。理想情况下,这将限于项目所有者。
另外,Dbx数据库应该显式拒绝已知的错误签名者。
测试步骤:安全启动策略
以上各节详细介绍了系统在理论上应该如何工作,但在实践中,它取决于安全引导策略。此策略可能指定某些媒体(如PCDOption ROM)在默认情况下是受信任的。
在管理终端中运行以下PowerShell命令,检查被测系统是否启用了安全引导:
Confirm-SecureBootUEFI
在管理终端中运行以下PowerShell命令,检查是否为受测系统启用了生产安全引导策略。
Get-SecureBootPolicy
如果使用生产策略运行,则该命令将返回值{77FA9ABD-0359-4D32-BD60-28F4E78F784B}。任何其他值表示正在使用调试或制造商策略,应进一步检查。
在非windows机器上,需要使用特定操作系统和内核映像的方法来检查正在使用的安全引导策略。在Rootkits和Bootkits中,作者发现Intel EDK2源代码有几个策略值,这些值不能验证位于可移动媒体或可选rom上的映像。
在这些实现细节中,对系统内部有很强了解的攻击者可能会破坏安全的系统。
7. 基于虚拟化的安全性
从Windows 10开始,通过虚拟安全模式和设备保护功能,代码完整性机制已经被移出了系统内核。这两种技术利用硬件辅助的内存隔离,在受虚拟机监视器保护的容器中运行操作系统和关键系统驱动程序。这试图确保即使运行时内核受到感染,固件和操作系统也不会受到进一步的攻击。
虚拟安全模式消除了具有RCE漏洞(该漏洞会危害整个系统)的合法内核模块的威胁,因为攻击者无法在安全容器之外提升其权限。
设备保护通过将虚拟安全模式与平台和UEFI安全引导相结合来构建此技术。其目的是从启动过程的一开始就加强设备的完整性,并防止启动包受到任何感染。平台和UEFI安全引导如上所述,但一旦引导管理器将控制权转移到操作系统内核,device guard就会将敏感的系统组件(如正在运行的内核)包装在保护性虚拟安全监视器的虚拟容器中。
获得这些出色的安全特性的折衷方案是,为设备保护开发的所有驱动程序必须遵循以下附加规则:
驱动程序只能从无可执行池分配非分页内存。驱动程序不能有可写和可执行部分驱动程序不能有动态或自修改代码驱动程序无法将任何数据加载为可执行文件
8. 经验证和测量的启动
现代TPM提供了一些技术,使系统能够在打开封装在TPM内的秘密之前,验证其是否处于已知的安全状态。该技术验证了平台镜像没有被改变。
测量的引导在TPM PCRS(平台配置注册表)中存储引导组件的散列并在运行时检查它们。
TPM认证是证明系统身份的一种方法。它证明了TPM持有某个密钥而不用显示该密钥。它通常用于限制端点仅与特定数量的已知设备通信。
Intel Boot Guard-一种平台安全引导实现
Intel Boot Guard是经验证和测量的引导的实现。需要注意的是,它有自己的策略,这与常规的安全引导不同,后者也应该进行评估。
BootGuard验证BIOS映像以确保它没有被bootkit感染。它使用硬件信任根(TPM或fuses)保存正确BIOS内容的哈希值,并在TPM中运行验证代码。
这减少了以前对SPI闪存完整性的依赖,并将所有信任直接转移到硬件中。
后记
在评估硬件设备时,早期的引导系统常常被忽略。在涉及对目标设备具有隔离访问权限的客户的威胁模型中,确保涉及固件植入的攻击向量得到缓解至关重要。使用你的新BIOS超级能力,放弃一些ring-2套件,保护硬件安全!