Windows ARM64指针认证(PAC)漏洞利用开发揭秘

本文深入探讨Windows在ARM64架构上实现的指针认证(PAC)技术,详细分析其内核初始化过程、用户态与内核态密钥管理机制,以及作为内存破坏漏洞缓解措施的实际防护效果和绕过可能性。

Exploit Development: Unveiling Windows ARM64 Pointer Authentication (PAC)

引言

指针认证码(PAC)是一种反漏洞利用/内存破坏功能,通过对指针进行签名,以便在运行时验证其使用(作为代码或数据)。PAC可用于Armv8.3-A和Armv9.0-A(及更高版本)ARM架构,并利用虚拟地址在指针值旁边存储小型加密签名。

在典型的64位处理器上,如果64位地址的第47位设置为0(意味着第48-63位也为0),则该指针被视为"用户模式"指针。这被称为规范用户模式地址。如果第47位设置为1,则第48-63位也设置为1,这被视为规范内核模式地址。

Windows上的PAC启用

Windows上的PAC启用始于ntoskrnl.exe的入口点KiSystemStartup。KiSystemStartup负责确定Windows是否支持PAC,并初始化基本PAC支持。KiSystemStartup从Windows引导加载程序winload.efi接收加载器参数块(LOADER_PARAMETER_BLOCK)。加载器块指示是否支持PAC。

ARM架构支持为不同场景使用多个签名密钥,例如使用不同密钥对指令指针或数据指针进行签名。Windows当前仅对"指令指针"使用PAC,并且仅使用"密钥B"进行加密签名。

Windows PAC作为漏洞利用缓解措施

Windows当前提供PAC的实现(具有未来扩展能力)。Windows当前支持对"指令指针"进行签名和认证。然而,这种方式实际上表现为对返回地址的签名。

在ARM64架构中,跨越调用边界保存返回地址的语义与Intel x86略有不同。在基于x86的系统上,调用指令还会将目标返回地址推送到堆栈上。然后,在返回之前,将前述返回地址从堆栈中"弹出"并加载到指令指针中。在ARM64上,bl(带链接的分支,类似于调用)指令将当前范围内的返回地址放在架构寄存器(lr,或"链接寄存器")中。

pacibsp指令将使用"密钥b"(APIBKeyLo_EL1和APIBKeyHi_EL1)和范围内堆栈指针的值对返回地址进行签名。目标返回地址将保持此状态,高位(非规范位)通过签名进行转换。

安全内核与PAC

细心的读者可能会注意到,内核本身负责管理PAC的密钥值。此外,我们已经介绍过,由于HVCI的服务,用于跟踪内核PAC签名密钥(用于签名内核指针)的内存变量在VTL 0内存中是只读的。

为了帮助缓解这个问题,使用了安全内核补丁防护,通常称为"HyperGuard" - 由安全内核推广的安全功能!HyperGuard实现了PatchGuard试图防御的大部分内容(内核数据结构、x86系统上的MSR、控制寄存器等的修改),但它是确定性的,与PatchGuard不同,因为HyperGuard在比其试图防御的代码(VTL 0的内核)更高的安全边界运行。

结论

基于ARM的处理器,在没有像CET这样的后向边缘控制流完整性(CFI)缓解措施的情况下,能够有效利用PAC来防御返回地址破坏。正如我们所看到的,Windows当前仅在有限情况下利用PAC(如保护返回地址),这在许多主流PAC实现中是标准的。PAC提供了一个可行的解决方案,以保护非x86-based处理器免受某些类别的内存破坏漏洞利用。

此外,当前一代的ARM64 Microsoft设备,如Surface Pro,并未配备支持内存标记扩展(MTE)功能的芯片。尽管目前在Windows系统上未实现,但未来同时实现PAC和MTE将大大增加内存破坏漏洞利用的成本。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计