薛定谔的可信下载。 英特尔启动保护

薛定谔的可信下载。 英特尔启动保护
我们建议再次深入到底层,谈谈 x86 兼容计算机平台的固件安全性。 这次,研究的主要成分是英特尔Boot Guard(不要与英特尔BIOS Guard混淆!)——一种硬件支持的可信BIOS启动技术,计算机系统供应商可以在生产阶段永久启用或禁用该技术。 好吧,我们已经熟悉了研究方法:使用逆向工程对这项技术的实施进行细化,描述其架构,用未记录的细节填充它,用攻击向量调味并进行混合。 让我们为这个故事再添上一笔:多年来在多个供应商的产品中克隆的一个错误如何允许潜在的攻击者使用这项技术在系统中创建一个无法删除的隐藏 rootkit(即使使用程序员也无法删除)。

顺便说一句,本文基于会议的报告“On Guard of Rootkit:Intel BootGuard” 零夜 2016 和第29次会议 俄罗斯防御大会 (两个演示 这里).

适用于 Intel 64 架构计算机平台的固件

首先,我们来回答一个问题:Intel 64架构的现代计算机平台的固件是什么? 当然是UEFI BIOS。 但这样的答案并不准确。 我们看一下图片,它显示了该架构的桌面(笔记本)版本。

薛定谔的可信下载。 英特尔启动保护
基础是链接:

  • 处理器(CPU,中央处理单元),除了主核心外,还内置图形核心(并非所有型号都有)和内存控制器(IMC,集成内存控制器);
  • 芯片组(PCH,平台控制器中心),包含用于与外围设备交互和管理子系统的各种控制器。 其中就有大家熟知的Intel管理引擎(ME),它也有固件(Intel ME固件)。

笔记本电脑除了上述之外,还需要一个内置控制器(ACPI EC,Advanced Control and Power Interface Embedded Controller),它负责电源子系统、触摸板、键盘、Fn键(屏幕亮度、音量、键盘背光等)和其他东西。 而且它还有自己的固件。

所以,上述固件的总和就是计算机平台的固件(系统固件),它存储在通用的SPI闪存上。 为了使该内存的用户不会对其位置感到困惑,该内存的内容被分为以下几个区域(如图所示):

  • UEFI BIOS;
  • ACPI EC 固件(Skylake 处理器微架构 (2015) 中出现了一个单独的区域,但实际上我们还没有看到其使用示例,因此内置控制器的固件仍然包含在 UEFI BIOS 中) ;
  • 英特尔 ME 固件;
  • 内置GbE(千兆位以太网)网络适配器的配置(MAC地址等);
  • 闪存描述符是闪存的主要区域,包含指向其他区域的指针以及访问它们的权限。

薛定谔的可信下载。 英特尔启动保护
SPI 总线主控是芯片组中内置的 SPI 控制器,通过它来访问该内存,负责界定对区域的访问(根据指定的权限)。 如果权限设置为 Intel 建议的(出于安全原因)值,则每个 SPI 闪存用户仅对其区域具有完全访问权限(读/写)。 其余的要么是只读的,要么是不可访问的。 众所周知的事实:在许多系统上,CPU 可以完全访问 UEFI BIOS 和 GbE,只能读取闪存描述符,而根本无法访问 Intel ME 区域。 为什么是针对很多,而不是针对全部? 推荐的不是必需的。 我们将在本文后面详细告诉您。

保护计算机平台固件免遭修改的机制

显然,应该保护计算机平台的固件免受可能的损害,这将允许潜在的攻击者在其中获得立足点(在操作系统更新/重新安装中幸存),以最高特权模式执行其代码等。 当然,限制对 SPI 闪存区域的访问还不够。 因此,为了保护固件免遭修改,使用了针对每个操作环境的各种机制。

因此,Intel ME 固件经过签名以控制完整性和真实性,并在每次加载到 ME UMA 内存时由 ME 控制器进行检查。 我们已在其中一篇中讨论过此验证过程 用品,专用于 Intel ME 子系统。

通常,ACPI EC 固件仅检查完整性。 然而,由于该二进制文件包含在 UEFI BIOS 中,因此它几乎总是受到 UEFI BIOS 使用的相同保护机制的约束。 我们来谈谈他们吧。

这些机制可以分为两类。

UEFI BIOS 区域中的写保护

  1. 通过写保护跳线对SPI闪存的内容进行物理保护;
  2. 使用 PRx 芯片组寄存器保护 UEFI BIOS 区域在 CPU 地址空间中的投影;
  3. 通过设置芯片组寄存器中的 BIOS_WE/BLE 和 SMM_BWP 位来生成和处理相应的 SMI 中断,阻止尝试写入 UEFI BIOS 区域;
  4. 这种保护的更高级版本是 Intel BIOS Guard (PFAT)。

除了这些机制之外,供应商还可以开发和实施自己的安全措施(例如,使用 UEFI BIOS 更新对胶囊进行签名)。

需要注意的是,在特定系统上(取决于供应商),并非所有上述保护机制都可以应用,它们可能根本不应用,或者它们可能以易受攻击的方式实现。 您可以阅读有关这些机制及其实施情况的更多信息 本文。 对于那些感兴趣的人,我们建议您阅读有关 UEFI BIOS 安全性的整个系列文章 代码拉什.

UEFI BIOS 身份验证

当我们谈论可信启动技术时,首先想到的是安全启动。 然而,从架构上来说,它旨在验证 UEFI BIOS 外部组件(驱动程序、引导加载程序等)的真实性,而不是固件本身。

因此,Intel在Bay Trail微架构(2012)的SoC中,实现了硬件非禁用的安全启动(Verified Boot),这与上述安全启动技术没有任何共同之处。 后来(2013 年),该机制得到改进,并以 Intel Boot Guard 的名称发布,适用于具有 Haswell 微架构的桌面。

在描述 Intel Boot Guard 之前,我们先来看看 Intel 64 架构中的执行环境,这些环境组合起来就是这种可信启动技术的信任根源。

英特尔CPU

Cap认为处理器是Intel 64架构中的主要执行环境,为什么说它是信任之根呢? 事实证明,他之所以如此,是因为拥有以下要素:

  • 微码ROM是一种用于存储微码的非易失性、不可重写的存储器。 人们认为,微码是使用最简单指令的处理器命令系统的实现。 微代码中也会发生 臭虫。 因此,在 BIOS 中,您可以找到带有微码更新的二进制文件(在引导期间覆盖,因为 ROM 无法被覆盖)。 这些二进制文件的内容是加密的,这使得分析变得非常复杂(因此,微代码的具体内容只有开发它的人知道),并进行签名以控制完整性和真实性;
  • 用于解密微码更新内容的 AES 密钥;
  • 用于验证微码更新签名的 RSA 公钥的哈希值;
  • RSA 公钥哈希,用于验证 Intel 开发的 ACM(认证代码模块)代码模块的签名,CPU 可以在 BIOS 执行(hello 微代码)之前或在其运行期间(当发生某些事件时)启动该代码模块。

英特尔ME

我们的博客专门讨论这个子系统 文章。 让我们回想一下,这个可执行环境基于芯片组中内置的微控制器,并且是系统中最隐藏和最特权的环境。

尽管保密,英特尔 ME 也是信任的根源,因为它具有:

  • ME ROM - 非易失性、不可重写存储器(不提供更新方法),包含启动代码以及 RSA 公钥的 SHA256 哈希值,用于验证 Intel ME 固件的签名;
  • 用于存储秘密信息的AES密钥;
  • 访问集成到芯片组中的一组保险丝(FPF,现场可编程保险丝),用于永久存储某些信息,包括计算机系统供应商指定的信息。

英特尔启动保护 1.x

一个小小的免责声明。 我们在本文中使用的英特尔 Boot Guard 技术版本号是任意的,可能与英特尔内部文档中使用的编号无关。 此外,此处提供的有关该技术实施的信息是在逆向工程过程中获得的,与不太可能发布的英特尔 Boot Guard 规范相比,可能包含不准确之处。

所以,Intel Boot Guard (BG) 是一种硬件支持的 UEFI BIOS 身份验证验证技术。 从《平台嵌入式安全技术揭秘,完整启动或不启动》一书中的简短描述来看,它作为可信启动链运行。 其中第一个链接是CPU内部的启动代码(微代码),它是由RESET事件触发的(不要与BIOS中的RESET向量混淆!)。 CPU在SPI闪存上找到由Intel(Intel BG启动ACM)开发和签名的代码模块,将其加载到其缓存中,验证(上面已经注意到CPU具有验证ACM的公钥的哈希值)签名)并开始。

薛定谔的可信下载。 英特尔启动保护

该代码模块负责验证 UEFI BIOS 的一小部分启动部分 - 初始引导块 (IBB),而 IBB 又包含验证 UEFI BIOS 主要部分的功能。 因此,Intel BG 允许您在加载操作系统之前验证 BIOS 的真实性(这可以在安全启动技术的监督下执行)。

英特尔 BG 技术提供两种操作模式(其中一种模式互不干扰,即两种模式都可以在系统上启用,或者两种模式都可以禁用)。

测量引导

在测量启动 (MB) 模式下,每个启动组件(从 CPU 启动 ROM 开始)使用 TPM(可信平台模块)的功能“测量”下一个启动组件。 对于那些不了解的人,让我解释一下。

TPM 具有 PCR(平台配置寄存器),哈希运算的结果根据以下公式写入其中:

薛定谔的可信下载。 英特尔启动保护

那些。 当前的 PCR 值取决于前一个值,并且这些寄存器仅在系统复位时复位。

因此,在 MB 模式下,在某个时间点,PCR 反映了“测量”的代码或数据的唯一(在散列操作的能力范围内)标识符。 PCR值可用于某些数据加密(TPM_Seal)操作。 此后,只有当 PCR 值没有因加载而改变(即没有修改任何“测量”组件)时,它们的解密(TPM_Unseal)才可能。

验证启动

对于那些喜欢修改 UEFI BIOS 的人来说,最糟糕的是验证启动 (VB) 模式,在该模式中,每个启动组件都会以加密方式验证下一个启动组件的完整性和真实性。 如果出现验证错误,则会发生(其中之一):

  • 超时关闭 1 分钟到 30 分钟(以便用户有时间了解计算机无法启动的原因,并在可能的情况下尝试恢复 BIOS);
  • 立即关闭(这样用户就没有时间去理解,更不用说做任何事情了);
  • 保持平静的表情继续工作(这种情况是没有时间保证安全,因为还有更重要的事情要做)。

操作的选择取决于指定的英特尔BG配置(即所谓的强制策略),该配置由计算机平台供应商永久记录在专门设计的存储芯片组熔断器(FPF)中。 稍后我们将更详细地讨论这一点。

除了配置之外,供应商还生成两个 RSA 2048 密钥并创建两个数据结构(如图所示):

  1. 供应商的根密钥清单(KEYM,OEM Root Key Manifest),其中包含该清单的 SVN(安全版本号)、下一个清单的公钥的 SHA256 哈希值、RSA 公钥(即该清单的公开部分)供应商的根密钥)来验证此宣言的签名和签名本身;
  2. IBB Manifest(IBBM,Initial Boot Block Manifest),包含该宣言的SVN、IBB的SHA256哈希值、用于验证该宣言签名的公钥以及签名本身。

OEM 根密钥公钥的 SHA256 哈希永久记录在芯片组熔丝 (FPF) 中,就像 Intel BG 配置一样。 如果 Intel BG 配置规定包含该技术,那么从现在开始,只有 OEM 根密钥私有部分的所有者才能更新该系统上的 BIOS(即能够重新计算这些清单),即小贩。

薛定谔的可信下载。 英特尔启动保护

当看到这张图片时,立即产生了对是否需要如此长的验证链的怀疑——他们本来可以使用一个清单。 为什么要把事情复杂化呢?

事实上,英特尔因此为供应商提供了对其不同系列产品使用不同 IBB 密钥的机会,并使用一个作为根密钥。 如果 IBB 密钥的私有部分(用于签署第二个清单)泄露,则该事件将仅影响一个产品线,并且只会影响供应商生成新的密钥对并将重新计算的清单包含在下一次 BIOS 更新中。

但是,如果根密钥(用于签署第一个清单)被泄露,则无法替换它;没有提供撤销程序。 该密钥的公共部分的哈希值被一次性编程到 FPF 中。

英特尔引导防护配置

现在让我们仔细看看英特尔 BG 配置及其创建过程。 如果您查看英特尔系统工具套件 (STK) 中闪存映像工具实用程序 GUI 中的相应选项卡,您会注意到英特尔 BG 配置包含供应商根密钥的公共部分的哈希值、几个价值观不明确等英特尔BG简介。

薛定谔的可信下载。 英特尔启动保护

该配置文件的结构:

typedef struct BG_PROFILE
{
	unsigned long Force_Boot_Guard_ACM : 1;
	unsigned long Verified_Boot : 1;
	unsigned long Measured_Boot : 1;
	unsigned long Protect_BIOS_Environment : 1;
	unsigned long Enforcement_Policy : 2; // 00b – do nothing
                                              // 01b – shutdown with timeout
                                              // 11b – immediate shutdown
	unsigned long : 26;
};

总的来说,英特尔BG配置是一个非常灵活的实体。 例如,考虑 Force_Boot_Guard_ACM 标志。 去掉后,如果找不到SPI flash上​​的BG启动ACM模块,则不会发生可信启动。 她将变得不被信任。

我们上面已经写过,可以配置 VB 模式的强制策略,这样如果出现验证错误,就会发生不受信任的下载。

将这些事情留给供应商自行决定......

GUI 实用程序提供以下“现成”配置文件:


政权
使用说明

0
否_FVME
禁用英特尔 BG 技术

1
VE
VB模式启用,超时关闭

2
VME
两种模式均启用(VB 和 MB),超时关闭

3
VM
两种模式均启用,无需关闭系统

4
FVE
VB模式启用,立即关闭

5
FVME
两种模式均启用,立即关闭

正如已经提到的,Intel BG 配置必须由系统供应商一次性写入芯片组熔断器(FPF)中——芯片组内部的一个小型(根据未经验证的信息,只有 256 字节)信息硬件存储,可以进行编程在英特尔的生产设施之外(这就是为什么 现场可编程 保险丝)。

它非常适合存储配置,因为:

  • 具有用于存储数据的一次性可编程区域(正是写入 Intel BG 配置的位置);
  • 只有 Intel ME 可以读取和编程它。

因此,为了在特定系统上设置英特尔 BG 技术的配置,供应商在生产过程中执行以下操作:

  1. 使用闪存映像工具实用程序(来自英特尔 STK),它可以在英特尔 ME 区域内以变量的形式创建具有给定英特尔 BG 配置的固件映像(所谓的 FPF 临时镜像);
  2. 使用闪存编程工具实用程序(来自英特尔 STK),将此映像写入系统的 SPI 闪存并关闭所谓的。 制造模式(在这种情况下,相应的命令将发送到 Intel ME)。

这些操作的结果是,Intel ME 会将 ME 区域中的 FPF 镜像中的指定值提交给 FPF,将 SPI 闪存描述符中的分辨率设置为 Intel 推荐的值(在文章)并执行系统重置。

Intel Boot Guard实现分析

为了通过具体的例子来分析该技术的实现情况,我们检查了以下系统中是否存在英特尔BG技术的踪迹:

系统
注意

技嘉GA-H170-D3H
Skylake,有支持

技嘉 GA-Q170-D3H
Skylake,有支持

技嘉 GA-B150-HD3
Skylake,有支持

微星 H170A 游戏专业版
Skylake,不支持

联想ThinkPad 460
Skylake,受支持,技术启用

联想瑜伽临2
哈斯韦尔,不支持

联想U330p
哈斯韦尔,不支持

“支持”是指存在英特尔 BG 启动 ACM 模块、上述清单以及 BIOS 中的相应代码,即实施进行分析。

我们以从办公室下载的为例。 Gigabyte GA-H170-D3H(版本 F4)的 SPI 闪存供应商网站图像。

英特尔CPU启动ROM

首先,我们来谈谈启用Intel BG技术后处理器的动作。

不可能找到解密的微代码的样本,因此如何实现下面描述的操作(在微代码或硬件中)是一个悬而未决的问题。 然而,事实是现代英特尔处理器“可以”执行这些操作。

退出RESET状态后,处理器(闪存的内容已经映射到地址空间)找到FIT(固件接口表)表。 它很容易找到;指向它的指针写在地址 FFFF FFC0h 处。

薛定谔的可信下载。 英特尔启动保护
在所考虑的示例中,值 FFD6 9500h 位于该地址。 通过访问该地址,处理器可以看到 FIT 表,其中的内容被分为多个记录。 第一个条目是以下结构的标头:

typedef struct FIT_HEADER
{
	char           Tag[8];     // ‘_FIT_   ’
	unsigned long  NumEntries; // including FIT header entry
	unsigned short Version;    // 1.0
	unsigned char  EntryType;  // 0
	unsigned char  Checksum;
};

薛定谔的可信下载。 英特尔启动保护
由于某些未知的原因,这些表中并不总是计算校验和(该字段保留为零)。

其余条目指向在执行 BIOS 之前需要解析/执行的各种二进制文件,即在切换到传统复位向量(FFFF FFF0h)之前。 每个此类条目的结构如下:

typedef struct FIT_ENTRY
{
	unsigned long  BaseAddress;
	unsigned long  : 32;
	unsigned long  Size;
	unsigned short Version;     // 1.0
	unsigned char  EntryType;
	unsigned char  Checksum;
};

薛定谔的可信下载。 英特尔启动保护
EntryType 字段告诉您该条目指向的块的类型。 我们知道几种类型:

enum FIT_ENTRY_TYPES
{
	FIT_HEADER = 0,
	MICROCODE_UPDATE,
	BG_ACM,
	BIOS_INIT = 7,
	TPM_POLICY,
	BIOS_POLICY,
	TXT_POLICY,
	BG_KEYM,
	BG_IBBM
};

现在很明显,其中一个条目指向 Intel BG 启动 ACM 二进制文件的位置。 该二进制文件的标头结构是 Intel 开发的代码模块的典型结构(ACM、微代码更新、Intel ME 代码段……)。

typedef struct BG_ACM_HEADER
{
	unsigned short ModuleType;     // 2
	unsigned short ModuleSubType;  // 3
	unsigned long  HeaderLength;   // in dwords
	unsigned long  : 32;
	unsigned long  : 32;
	unsigned long  ModuleVendor;   // 8086h
	unsigned long  Date;           // in BCD format
	unsigned long  TotalSize;      // in dwords
	unsigned long  unknown1[6];
	unsigned long  EntryPoint;
	unsigned long  unknown2[16];
	unsigned long  RsaKeySize;     // in dwords
	unsigned long  ScratchSize;    // in dwords
	unsigned char  RsaPubMod[256];
	unsigned long  RsaPubExp;
	unsigned char  RsaSig[256];
};

薛定谔的可信下载。 英特尔启动保护
处理器将此二进制文件加载到其缓存中,验证它并运行它。

英特尔BG启动ACM

通过分析该 ACM 的工作,可以清楚地看出它执行以下操作:

  • 从 Intel ME 接收 Intel BG 配置,写入芯片组熔丝 (FPF);
  • 找到 KEYM 和 IBBM 清单并验证它们。

为了查找这些清单,ACM 还使用 FIT 表,该表具有两种条目类型来指示结构数据(请参阅上面的 FIT_ENTRY_TYPES)。

让我们仔细看看宣言。 在第一个清单的结构中,我们看到几个晦涩的常量、第二个清单中的公钥的哈希值以及签名为嵌套结构的公共 OEM 根密钥:

typedef struct KEY_MANIFEST
{
	char           Tag[8];          // ‘__KEYM__’
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 0
	unsigned char  : 8;             // 1
	unsigned short : 16;            // 0Bh
	unsigned short : 16;            // 20h == hash size?
	unsigned char  IbbmKeyHash[32]; // SHA256 of an IBBM public key
	BG_RSA_ENTRY   OemRootKey;
};

typedef struct BG_RSA_ENTRY
{
	unsigned char  : 8;             // 10h
	unsigned short : 16;            // 1
	unsigned char  : 8;             // 10h
	unsigned short RsaPubKeySize;   // 800h
	unsigned long  RsaPubExp;
	unsigned char  RsaPubKey[256];
	unsigned short : 16;            // 14
	unsigned char  : 8;             // 10h
	unsigned short RsaSigSize;      // 800h
	unsigned short : 16;            // 0Bh
	unsigned char  RsaSig[256];
};

薛定谔的可信下载。 英特尔启动保护
为了验证 OEM 根密钥公钥,我们使用了熔断器的 SHA256 哈希值,此时已从 Intel ME 收到该哈希值。

让我们继续讨论第二个宣言。 它由三个结构组成:

typedef struct IBB_MANIFEST
{
	ACBP Acbp;         // Boot policies
	IBBS Ibbs;         // IBB description
	IBB_DESCRIPTORS[];
	PMSG Pmsg;         // IBBM signature
};

第一个包含一些常量:

typedef struct ACBP
{
	char           Tag[8];          // ‘__ACBP__’
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 1
	unsigned char  : 8;             // 10h
	unsigned char  : 8;             // 0
	unsigned short : 16;            // x & F0h = 0
	unsigned short : 16;            // 0 < x <= 400h
};

第二个包含 IBB 的 SHA256 哈希值以及描述 IBB 内容的描述符数量(即哈希值的计算依据):

typedef struct IBBS
{
	char           Tag[8];            // ‘__IBBS__’
	unsigned char  : 8;               // 10h
	unsigned char  : 8;               // 0
	unsigned char  : 8;               // 0
	unsigned char  : 8;               // x <= 0Fh
	unsigned long  : 32;              // x & FFFFFFF8h = 0
	unsigned long  Unknown[20];
	unsigned short : 16;              // 0Bh
	unsigned short : 16;              // 20h == hash size ?
	unsigned char  IbbHash[32];       // SHA256 of an IBB
	unsigned char  NumIbbDescriptors;
};

IBB 描述符一个接一个地遵循这一结构。 它们的内容具有以下格式:

typedef struct IBB_DESCRIPTOR
{
	unsigned long  : 32;
	unsigned long  BaseAddress;
	unsigned long  Size;
};

很简单:每个描述符包含 IBB 块的地址/大小。 因此,这些描述符所指向的块的串联(按照描述符本身的顺序)是IBB。 通常,IBB 是 SEC 和 PEI 阶段所有模块的集合。

第二个清单由包含 IBB 公钥(由第一个清单中的 SHA256 哈希验证)和该清单签名的结构完成:

typedef struct PMSG
{
	char           Tag[8];            // ‘__PMSG__’
	unsigned char  : 8;               // 10h
	BG_RSA_ENTRY   IbbKey;
};

薛定谔的可信下载。 英特尔启动保护
因此,即使在 UEFI BIOS 开始执行之前,处理器也会启动 ACM,它将使用 SEC 和 PEI 阶段代码验证各部分内容的真实性。 接下来,处理器退出 ACM,遵循 RESET 向量并开始执行 BIOS。

已验证的 PEI 分区必须包含一个用于检查 BIOS 其余部分(DXE 代码)的模块。 该模块已由 IBV(独立 BIOS 供应商)或系统供应商本身开发。 因为只有 Lenovo 和 Gigabyte 系统可供我们使用并拥有 Intel BG 支持;让我们看看从这些系统中提取的代码。

UEFI BIOS 模块 LenovoVerifiedBootPei

就联想而言,它是联想开发的LenovoVerifiedBootPei模块{B9F2AC77-54C7-4075-B42E-C36325A9468D}。

它的工作是查找(通过 GUID)DXE 的哈希表并验证 DXE。

if (EFI_PEI_SERVICES->GetBootMode() != BOOT_ON_S3_RESUME)
{
	if (!FindHashTable())
		return EFI_NOT_FOUND;
	if (!VerifyDxe())
		return EFI_SECURITY_VIOLATION;
}

Хеш таблица {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} имеет следующий формат:

typedef struct HASH_TABLE
{
	char          Tag[8];            // ‘$HASHTBL’
	unsigned long NumDxeDescriptors;
	DXE_DESCRIPTORS[];
};

typedef struct DXE_DESCRIPTOR
{
	unsigned char BlockHash[32];     // SHA256
	unsigned long Offset;
	unsigned long Size;
};

UEFI BIOS 模块 BootGuardPei

就技嘉而言,它是 AMI 开发的 BootGuardPei 模块 {B41956E1-7CA2-42DB-9562-168389F0F066},因此存在于任何支持 Intel BG 的 AMI BIOS 中。

它的操作算法有些不同,但归结起来都是一样的:

int bootMode = EFI_PEI_SERVICES->GetBootMode();

if (bootMode != BOOT_ON_S3_RESUME &&
    bootMode != BOOT_ON_FLASH_UPDATE &&
    bootMode != BOOT_IN_RECOVERY_MODE)
{
	HOB* h = CreateHob();
	if (!FindHashTable())
		return EFI_NOT_FOUND;
	WriteHob(&h, VerifyDxe());
	return h;
}

它正在查找的哈希表 {389CC6F2-1EA8-467B-AB8A-78E769AE2A15} 具有以下格式:

typedef HASH_TABLE DXE_DESCRIPTORS[];

typedef struct DXE_DESCRIPTOR
{
	unsigned char BlockHash[32];     // SHA256
	unsigned long BaseAddress;
	unsigned long Size;
};

英特尔启动保护 2.x

让我们简单谈谈英特尔 Boot Guard 的另一种实现,它出现在基于采用 Apollo Lake 微架构的英特尔 SoC 的较新系统 - 华擎 J4205-IT 中。

虽然这个版本只会用在 SoC 中(采用 Kaby Lake 处理器微架构的新系统继续使用 Intel Boot Guard 1.x),但研究 Intel SoC 平台的新架构选项非常有兴趣,它已经发生了重大变化,例如:

  • BIOS 和 Intel ME 区域(或者更确切地说是 Intel TXE,根据 Intel SoC 的术语)现在是一个 IFWI 区域;
  • 虽然平台上启用了Intel BG,但闪存中未发现FIT、KEYM、IBBM等结构;
  • 除了 TXE 和 ISH 内核 (x86) 之外,芯片组中还添加了第三个内核(顺便说一下,又是 ARC) - PMC(电源管理控制器),与确保电源子系统和性能监控的可操作性相关。

薛定谔的可信下载。 英特尔启动保护
新的 IFWI 区域的内容是一组以下模块:

移位
名字
使用说明

0000 2000小时
SMIP
由供应商签署的特定平台配置

0000 6000小时
RBEP
Intel TXE 固件代码部分,x86,Intel 签名

0001 0000小时
PMCP
Intel PMC 固件代码部分,ARC,Intel 签名

0002 0000小时
FTPR
Intel TXE 固件代码部分,x86,Intel 签名

0007 B000h
超临界COD
CPU 微代码更新,由 Intel 签名

0008 0000小时
IBBP
UEFI BIOS,SEC/PEI 阶段,x86,由供应商签名

0021 8000小时
国际卫生保健中心
英特尔 ISH 固件代码部分,x86,由供应商签名

0025 8000小时
网络FTP
Intel TXE 固件代码部分,x86,Intel 签名

0036 1000小时
国际自然保护联盟
未知

0038 1000小时
OBBP
UEFI BIOS,DXE 阶段,x86,未签名

在分析 TXE 固件期间,很明显,在 RESET 后,TXE 会将处理器保持在这种状态,直到它为 CPU 准备好地址空间的基本内容(FIT、ACM、RESET 向量...)。 此外,TXE 将此数据放入其 SRAM 中,之后它暂时向处理器提供访问权限,并将其从 RESET 中“释放”。

防范 Rootkit

好吧,现在让我们继续讨论“热门”内容。 我们曾经发现,在许多系统上,SPI闪存描述符包含访问SPI闪存区域的权限,以便该存储器的所有用户都可以写入和读取任何区域。 那些。 决不。

在检查 MEinfo 实用程序(来自 Intel STK)后,我们发现这些系统上的制造模式并未关闭,因此芯片组熔丝 (FPF) 处于未定义状态。 是的,在这种情况下,英特尔 BG 既不会打开也不会关闭。

我们正在讨论以下系统(关于 Intel BG 以及本文后面将介绍的内容,我们将讨论具有 Haswell 处理器微架构及更高版本的系统):

  • 所有技嘉产品;
  • 所有 MSI 产品;
  • 21款联想笔记本电脑和4款联想服务器。

当然,我们向这些供应商以及英特尔报告了这一发现。

充分的反应仅来自 联想 Lenovo谁认识到了这个问题并且 发布了一个补丁.

技嘉 他们似乎接受了有关该漏洞的信息,但没有以任何方式发表评论。

微星 我们发送您的公共 PGP 密钥(以加密形式向他们发送安全建议)的请求完全陷入停滞。 他们表示,他们“是一家硬件制造商,不生产 PGP 密钥”。

但让我们进入正题吧。 由于保险丝处于未指定的状态,因此用户(或攻击者)可以对其进行独立编程(最困难的是 查找英特尔STK)。 为此,您需要完成以下步骤。

1. 引导至 Windows 操作系统(一般来说,如果您为所需操作系统开发了类似的英特尔 STK,则下面描述的操作也可以在 Linux 下完成)。 使用 MEinfo 实用程序,确保该系统上未对熔丝进行编程。

薛定谔的可信下载。 英特尔启动保护
2. 使用闪存编程工具读取闪存的内容。

薛定谔的可信下载。 英特尔启动保护
3. 使用任何 UEFI BIOS 编辑工具打开读取的映像,进行必要的更改(例如引入 rootkit),在 ME 区域中创建/编辑现有的 KEYM 和 IBBM 结构。

薛定谔的可信下载。 英特尔启动保护
薛定谔的可信下载。 英特尔启动保护
该图突出显示了 RSA 密钥的公共部分,其哈希值将与英特尔 BG 配置的其余部分一起编程到芯片组熔丝中。

4. 使用闪存映像工具构建新的固件映像(通过设置 Intel BG 配置)。

薛定谔的可信下载。 英特尔启动保护
5. 使用闪存编程工具将新映像写入闪存,并使用 MEinfo 验证 ME 区域现在包含英特尔 BG 配置。

薛定谔的可信下载。 英特尔启动保护
6. 使用Flash编程工具关闭制造模式。

薛定谔的可信下载。 英特尔启动保护
7. 系统将重新启动,之后您可以使用 MEinfo 来验证 FPF 现在是否已编程。

薛定谔的可信下载。 英特尔启动保护
这些动作 永远 在此系统上启用 Intel BG。 该操作无法撤消,这意味着:

  • 只有根密钥私有部分的所有者(即启用 Intel BG 的人)才能更新该系统上的 UEFI BIOS;
  • 如果您将原始固件返回到该系统,例如使用编程器,它甚至不会打开(这是验证错误时执行策略的结果);
  • 要摆脱这样的 UEFI BIOS,您需要将带有已编程 FPF 的芯片组替换为“干净”的芯片组(即,如果您可以使用红外焊台(价格相当于汽车的价格),则重新焊接芯片组,或者只需更换主板)。

要了解此类 Rootkit 的功能,您需要评估是什么使得您的代码可以在 UEFI BIOS 环境中执行。 比方说,处于最高特权处理器模式 - SMM。 此类 Rootkit 可能具有以下属性:

  • 与操作系统并行执行(您可以配置处理以生成 SMI 中断,该中断将由计时器触发);
  • 具有 SMM 模式的所有优点(完全访问 RAM 和硬件资源的内容,对操作系统保密);
  • Rootkit的程序代码在SMM模式下启动时可以被加密和解密。 任何仅在 SMM 模式下可用的数据都可以用作加密密钥。 例如,SMRAM 中一组地址的哈希值。 要获得此密钥,您需要进入 SMM。 这可以通过两种方式完成。 在SMM代码中找到RCE并利用它,或者将自己的SMM模块添加到BIOS中,这是不可能的,因为我们启用了Boot Guard。

因此,该漏洞允许攻击者:

  • 在系统中创建一个隐藏的、不可删除的、用途不明的 Rootkit;
  • 在英特尔 SoC 内的芯片组核心之一(即英特尔 ISH)上执行代码(仔细查看图片)。

薛定谔的可信下载。 英特尔启动保护
薛定谔的可信下载。 英特尔启动保护
尽管英特尔 ISH 子系统的功能尚未被探索,但它似乎是英特尔 ME 的一个有趣的攻击媒介。

发现

  1. 该研究使得获得英特尔 Boot Guard 技术操作的技术描述成为可能。 通过模糊模型消除英特尔安全中的一些秘密。
  2. 提供了一种攻击场景,允许您在系统中创建可卸载的 Rootkit。
  3. 我们看到现代英特尔处理器甚至在 BIOS 开始运行之前就能够执行大量专有代码。
  4. 采用 Intel 64 架构的平台越来越不适合运行自由软件:硬件验证、越来越多的专有技术和子系统(SoC 芯片组中的三个核心:x86 ME、x86 ISH 和 ARC PMC)。

缓解措施

有意将制造模式保持开放的供应商应确保将其关闭。 到目前为止,他们只是闭着眼睛,新的卡比湖系统表明了这一点。

用户可以通过使用 -closemnf 参数运行闪存编程工具来禁用其系统上的 Intel BG(容易受到所述漏洞的影响)。 首先,您应该确保(使用 MEinfo)ME 区域中的 Intel BG 配置可以在 FPF 中编程后关闭此技术。

来源: habr.com

添加评论