作者: Alon Leviev
降级攻击(也称为版本回滚攻击)是一种旨在将免疫的、完全最新的软件恢复到旧版本的攻击。它们允许恶意行为者暴露和利用之前修复/修补的漏洞来破坏系统并获得未经授权的访问。
概述
主要发现
由于我的研究目标是开发一种无法检测的 Microsoft Windows 降级流程,因此 Windows 更新过程似乎是我可能执行此类攻击的最不可疑的实体。当我探索 Windows 更新过程的复杂性时,我发现了一个重大漏洞,使我能够完全控制该过程。因此,我能够创建 Windows Downdate,这是一种实施降级更新并绕过所有验证步骤(包括完整性验证和受信任安装程序强制执行)的工具。
借助这些功能,我成功降级了关键操作系统组件,包括动态链接库 (DLL)、驱动程序,甚至 NT 内核。降级后,操作系统报告已完全更新,无法安装未来更新,而恢复和扫描工具无法检测到问题。
然后我把目标设得更高,发现整个虚拟化堆栈也处于危险之中。我成功降级了 Credential Guard 的隔离用户模式进程、安全内核和 Hyper-V 的虚拟机管理程序,以暴露过去的特权提升漏洞。
最后,我发现了多种禁用 Windows 虚拟化安全性 (VBS) 的方法,包括其 Credential Guard 和 Hypervisor 保护代码完整性 (HVCI) 等功能,即使在使用 UEFI 锁强制执行的情况下也是如此。据我所知,这是第一次在没有物理访问的情况下绕过 VBS 的 UEFI 锁。
结果,我能够让一台完全修补的 Windows 机器容易受到过去数千个漏洞的攻击,将修复的漏洞变成零日漏洞,并让世界上任何一台 Windows 机器上的“完全修补”一词变得毫无意义。
总结
这项研究的意义不仅在于微软 Windows(世界上使用最广泛的桌面操作系统),还在于其他可能受到降级攻击的操作系统供应商。我们认为研究结果可以得出几个重要结论:
-
有必要提高对基于操作系统的降级攻击的认识和研究。在此过程中,我发现没有缓解措施可以防止 Microsoft Windows 中关键操作系统组件的降级。我们认为其他操作系统可能同样容易受到类似的攻击媒介的影响,所有操作系统供应商都必须警惕它们带来的危险。
-
无论操作系统中的设计功能有多老,都应始终对其进行审查并将其视为相关的攻击面。我之所以能够在 Windows 中的虚拟化堆栈上实现降级攻击,是因为存在一个设计缺陷,该缺陷允许较低权限的虚拟信任级别/环更新位于较高权限的虚拟信任级别/环中的组件。这非常令人惊讶,因为微软的 VBS 功能是在 2015 年发布的,这意味着我发现的降级攻击面已经存在了近十年。虽然近年来 VBS 已成为安全研究人员中更受欢迎的话题,并且已经发表了几篇出色的研究论文,但仍需要更多专门针对虚拟化堆栈设计的研究。
-
我们认为,研究人员应尽可能彻底检查和扩展野外攻击。BlackLotus UEFI Bootkit 将降级攻击的概念引入了网络安全社区。值得庆幸的是,通过这项研究,我们能够在恶意行为者之前扩展此类攻击。然而,这并非总是有保证的,这强调了研究野外攻击并利用它们考虑可能受到影响的其他组件或区域的重要性。
研究过程
为了开始我的研究,我需要定义“完美”降级攻击的成功标准是什么:
-
首先,降级必须完全不可检测,这样端点检测和响应 (EDR) 解决方案就无法阻止降级。因此,我的目标是以最合法的方式进行降级。
-
第二,降级必须是不可见的。降级的组件应该显示为最新,即使它们在技术上已经降级。
-
第三,降级必须是持久的,以便将来的软件更新不会覆盖它。
-
最后,降级必须是不可逆的,这样扫描和修复工具将无法检测或修复降级。
明确降级要求后,我开始考虑合适的目标组件。执行降级的最意想不到的组件是什么?我把目光投向了 Windows 更新过程。
Windows 更新
Windows 更新体系结构Windows Update Architecture
Windows 更新架构包括一个更新客户端和一个更新服务器,它们通过 COM(Windows 上的一种进程间通信方法)进行通信。管理员通常在客户端执行,而受信任的安装程序始终在服务器端执行,这意味着 Windows 更新拥有的系统文件只能由受信任的安装程序访问。因此,即使是管理员和 NT SYSTEM 也无法直接修改系统文件。
这是我在 Windows Update 中发现的第一个设计问题。管理员到受信任安装程序不是安全边界,并且有多个有效的公开概念验证来证明这种提升。Windows Update 团队试图通过强制使用受信任安装程序来保护更新过程。但是,由于只有管理员才能访问更新,因此受信任安装程序在强制访问系统文件方面完全无效,因为可以提升到受信任安装程序并执行更改。
不幸的是,管理员到受信任安装程序的提升被视为恶意行为,并被 EDR 阻止,这意味着它违背了我第一个降级原则,即完全不被发现。我考虑尝试绕过提升检测;但是,我必须自己实施更新过程,这仍然可能被视为恶意行为。最好的选择是找到更新过程中的缺陷,以解决所有这些问题。
Windows 更新流程
Windows 更新流程包括以下步骤:
-
首先,客户端要求服务器执行其提供的更新文件夹中包含的更新。
-
然后服务器验证更新文件夹的完整性。
-
验证后,服务器将对更新文件夹进行操作,以完成更新文件。这些文件将保存到服务器控制的文件夹中,客户端无法访问该文件夹。
-
服务器将操作列表保存到服务器控制的文件夹中,客户端无法访问该文件夹。操作列表名为Pending.xml,其中包含要执行的更新操作。例如,它指定要更新哪些文件、源文件和目标文件等。
-
最后,当操作系统重启时,操作动作列表,并在重启过程中执行更新动作。
客户端仅控制初始更新文件夹。因此,我决定先查看此文件夹,看看是否可以修改它,从而导致自定义降级更新文件。我们已经知道,完整性检查是在更新文件夹上执行的。让我们看看它们执行得如何。
调查更新文件夹
update文件夹里面包含更新组件,每个更新组件包含MUM、manifest、different、catalog文件,如下所示。
MUM 文件是 Microsoft 更新元数据,包含元数据信息、组件依赖关系、安装顺序等。
清单文件包含安装特定的信息,如文件路径、注册表项、作为安装的一部分执行的安装程序等等。
差异文件是来自基础文件的增量文件。基础文件加上增量文件将产生完整的更新文件。
目录文件是 MUM 和清单文件的数字签名。目录允许同时对多个文件进行签名,而不是让要签名的文件嵌入其数字签名。此外,目录文件本身也经过数字签名,因此无法修改它们以及它们签名的文件。
再次总结一下:
-
仅目录文件经过数字签名。
-
Manifest 和 MUM 未明确签名,而是由目录签名。
-
差异文件未经过签名。它们还控制最终的更新文件内容。
定位差异文件
我发现最后一个事实很有趣,并想知道是否有可能在验证方面遗漏了差异文件。但是,我运气不佳,因为预期的更新文件哈希值已硬编码在清单中。并且清单无法更改,因为这会破坏其在目录中的签名。
针对行动清单
接下来,我决定探索操作列表。我知道我无法更改其内容,因为它是由受信任的安装程序强制执行的。但我还知道更新过程是在多次重新启动后执行的,因此我可以假设列表的状态已保存在某个地方。
我在注册表中搜索了操作列表路径,发现了一个名为PoqexecCmdline的有趣键。它保存了解析列表的可执行文件和列表路径。
然后我查看了此密钥的安全属性,发现它不是受信任的安装程序强制执行的!这将允许我控制所有更新操作。
操作列表—pending.xml—是一个 XML 文件,提供创建文件、删除文件、移动文件、硬链接文件、创建注册表项和值、删除项和值等功能!
<POQ postAction=”reboot”>
<CreateFile path=”C:WindowsSystem32Create.exe” fileAttributes=”0x00000000″/>
<MoveFile source=”C:UpdateDirSource.exe“ destination=”C:WindowsSystem32Destination.exe”/>
<HardlinkFile source=”C:UpdateDirSource.exe“ destination=”C:WindowsSystem32Destination.exe”/>
<SetFileInformation path=”C:UpdateDirSource.exe“ securityDescriptor=”binary base64:[BASE64-BLOB]” flags=”0x00000040″/>
<DeleteFile path=”C:WindowsSystem32Delete.exe”/>
<CreateDirectory path=”C:WindowsSystem32Directory” fileAttribute=”0x00000080“ securityDescriptor=”binary base64:[BASE64-BLOB]”/>
<CreateKey path=”RegistryMachineKey”/>
<SetKeyValue path=”RegistryMachineKey” name=”Name” type=”0x00000001“ encoding=”base64″ value=”[BASE64-BLOB]”/>
<SetKeySecurity path=”RegistryMachineKey“ securityDescriptor=”binary base64:[BASE64-BLOB]” flags=”0x00000001″/>
<DeleteKeyValue path=”RegistryMachineKey” name=”Value”/>
<DeleteKey flags=”0x00000001″ path=”RegsitryMachineKey”/>
</POQ>
为了降级,我可以使用硬链接文件操作,然后源将替换目标。
<HardlinkFile source=”C:UpdateDirSource.exe“ destination=”C:WindowsSystem32Destination.exe”/>
引入更新
要启动更新,我需要做的就是:
标识符是一个动态数字,用于与操作列表的标识符进行比较以确保完整性。上述三个操作均未由受信任的安装程序强制执行。这使我能够使用自定义的降级操作列表更新系统。所有完整性验证都被绕过,因为操作列表是在验证后创建的,因此假定已验证。
因此,无需执行恶意的 Trusted-Installer 提升。相反,Windows 更新为我完成了所有工作!我能够通过降级攻击实现完整的 Windows 更新接管,即:
完全无法检测。由于它是以合法方式执行的,因此未检测到任何恶意活动。
隐形。由于我技术上“更新”了系统,因此系统会显示为完全最新状态。
持久性。我发现操作列表解析器poqexec.exe未经过数字签名。因此,我能够对其进行修补以安装空更新,这意味着任何新可用的更新都将被错误安装。
不可逆转。我还发现完整性和修复实用程序 SFC.exe 未经过数字签名。我也能修补它,这意味着它将不再检测到任何损坏。我还发现了DISM.exe,但它检测到组件存储中的损坏,没有理由对其进行修改。
演示
为了演示这些功能的实际作用,以下演示展示了我如何将名为AFD.sys 的内核驱动程序降级为旧且易受攻击的版本。接下来,它展示了我如何利用同一个内核驱动程序来实现内核代码执行。
到目前为止,我已经开发出完美的降级能力并获得了内核代码执行权。由于我的起点是管理员,因此这是从管理员到内核的提升。
在 Windows 上,管理员到内核不被视为安全边界。尽管不是边界,但管理员到内核仍然是一个威胁,而且是一个严重的威胁。如今,许多用户仍然以管理员身份运行,以管理员身份运行也是 Windows 上的默认设置。因此,许多用户很容易破坏内核,而这正是 Microsoft 想要解决的问题。
微软的解决方案是降低内核的权限,使内核访问变得不那么重要。降低权限是通过引入一项名为基于虚拟化的安全性 (VBS) 的功能来实现的。
Windows 版本控制
VBS 提供了一个安全且隔离的虚拟环境 - 由 Hyper-V 虚拟机管理程序提供支持。创建 VBS 的原因是因为内核被认为受到攻击,并且需要一个安全的地方来实现安全功能并存储密钥。
VBS 功能包括 Credential Guard、HVCI、System Guard Secure Launch、Shielded VMs 以及更多真正提高 Windows 安全性的安全功能。
VBS 体系结构VBS Architecture
在 VBS 之前,Windows 架构包括 ring 3 中的用户模式、ring 0 中的内核和 ring -1 中的虚拟机管理程序。
借助 VBS,虚拟机管理程序引入了虚拟信任级别 (VTL),这本质上类似于虚拟机。VTL 越高,其特权就越大。较低的 VTL 不应能够访问内存或危害较高的 VTL。目前在 Windows 上,只有两个 VTL。
VTL0 称为正常模式,包含原始操作系统。VTL1 称为安全模式,包含安全功能和缓解措施以及关键隔离技术。
VBS 远程禁用保护
当我探索 VBS 安全功能和缓解措施时,我想知道是否可以轻松关闭 VBS 功能。允许管理员修改 VBS 配置是无效的,因为攻击者只会关闭 VBS 而不是处理它。
VBS 通过实现一项名为 UEFI 锁的功能来防止禁用。锁是一个 UEFI 启动服务变量,用于保存 VBS 配置。如果 VBS 配置了锁,则锁是配置的来源,而不是 Windows 注册表。因此,更改注册表配置不会产生任何影响。UEFI 变量是事实来源。当然,启动服务变量只能在启动期间访问,而不能在运行时从操作系统访问。这是一种非常简单且可靠的保护。
如果用户确实想禁用 VBS,他们必须加载由 Microsoft 签名的 EFI 应用程序。然后,此 EFI 会在启动期间要求用户物理批准禁用 — 只有这样才能禁用 VBS。这里的关键要素是,这是在启动期间执行的,并且假设由于安全启动,只有签名的代码才允许运行。唯一接触变量的签名代码需要物理批准。因此,如果没有对目标机器的物理访问,就不可能禁用 VBS。
绕过 VBS UEFI 锁
现在我有能力控制操作系统上的任何文件,我想知道如果我尝试用无效文件(例如未经数字签名且受攻击者控制的文件)替换安全内核或支持 VBS 的虚拟机管理程序,会发生什么。我假设机器将启动到恢复环境,因为无效文件是受到攻击的标志。
相反,我非常惊讶地发现操作系统加载程序正常启动,如果无法验证 VBS 的某个文件,它就会放弃 VBS。这个过程让我能够禁用 VBS,并发现我认为是第一个绕过 VBS 的 UEFI 锁的方法!
通过结合我开发的降级流程和 UEFI 锁绕过,我能够针对最严格的设置实现凭据提取:
-
已为具有 UEFI 锁的 LSASS 启用 PPL,以保护 LSASS 转储。
-
Credential Guard 已通过 UEFI 锁启用,以保护 VTL1 中的秘密。
-
Windows Defender 已启动并运行。
我首先通过恢复 PPLFault 补丁以允许 PPL 绕过来绕过这些设置。其次,我禁用了 Credential Guard,通过使安全内核无效来绕过 UEFI 锁。最后,我通过使主 Defender 可执行文件 MsMpEng 无效来使 Windows Defender 无法运行。
重要的是要了解 Credential Guard 和 LSASS 的 PPL 是互补的。如果仅绕过 Credential Guard,则无法转储 LSASS。
如果仅绕过 PPL,凭证就会被加密并且无法使用。
演示
为了看到这些功能的实际效果,以下演示展示了如何利用降级流程和 UEFI 锁绕过同时绕过 Credential Guard、PPL 和 Windows Defender。
VBS 安全边界
现在我绕过了 UEFI 锁并禁用了 VBS,是时候调查 VBS 的真正安全边界了。
VBS 引入的安全边界是,任何 VTL0 到 VTL1 的转换都被视为特权提升。任何 VTL0 代码都不能危及 VTL1 代码。另一个边界是,ring 3 到 ring -1 或 ring 0 到 ring -1(即任何用户模式或内核到虚拟机管理程序)也被视为特权提升。由于 VBS 的实现方式,危及虚拟机管理程序可控制所有 VTL。
在考虑 VBS 降级时,我的主要目标是了解虚拟化堆栈中是否存在降级缓解措施(如版本检查或撤销机制)。如果没有找到降级缓解措施,我会尝试降级到易受攻击的代码。无论我现在能降级到什么程度,我都会认为这是一个漏洞。这是因为,如果在未来某个时间点在目标组件中发现并修补了新的漏洞,利用漏洞将变得容易得多。即使不能立即利用,这也是需要解决的问题。
针对安全模式的隔离用户模式进程
首先,我把目光投向了安全模式的隔离用户模式进程。我决定瞄准最著名的隔离用户模式进程:Credential Guard。
Credential Guard 在 Ring3-VTL1 中作为一个名为LsaIso.exe的隔离用户模式进程实现,LsaIso.exe 代表 Lsa 隔离。在 Credential Guard 运行时,机密存储在VTL1 中的LsaIso.exe中,而不是原始的 LSASS 进程中。这就是为什么转储 LSASS 不再有价值的原因,因为 LSASS 仅包含加密的 blob。任何 VTL0 代码都无法访问真正的机密。
我针对CVE-2022-34709进行了降级,这是 Credential Guard 中已修复的特权提升。我发现了易受攻击的模块KerbClientShared和易受攻击的版本 10.0.22000.856。使用 Windows Update 接管降级易受攻击的模块在完全修补的机器上有效!
这使我能够将权限从 Ring3-VTL0 升级到 Ring3-VTL1,从而危及 Credential Guard 及其保护的机密。VTL1隔离用户模式没有降级检测!
针对安全模式的内核
隔离用户模式权限很棒,但我想获得像安全模式内核中的更高权限。
安全模式的内核称为安全内核,它是一个最小内核,仅实现了HVCI、HyperGuard等安全功能。
我针对CVE-2021-27090进行了降级,这是安全内核中已修复的特权提升。此处易受攻击的模块只能是安全内核 ( SecureKernel.exe ) 和易受攻击的版本 10.0.19041.207。
但是,在这种情况下,仅降级安全内核是不够的。我还必须降级依赖模块(如SKCI.dll和CI.dll),然后 Windows 更新接管才能在完全修补的机器上正常工作!
这使我能够将权限从 Ring3-VTL0 升级到 Ring0-VTL1,从而破坏整个 VTL 及其任何缓解措施,包括 HVCI、HyperGuard 等。VTL1安全内核上也没有降级检测!
针对 Hyper-V 的虚拟机管理程序
安全内核特权很棒,但我希望将目标设得更高。因此,我继续瞄准 VBS 中特权最高的实体:Hyper-V 虚拟机管理程序。
在 Intel 系统上,虚拟机管理程序是Hvix64.exe ;在 AMD 系统上,虚拟机管理程序是Hvax64.exe。虚拟机管理程序是一个独立的微内核,因此它成为降级的重要目标。
与隔离用户模式进程和安全内核不同,利用特定漏洞来针对虚拟机管理程序降级更具挑战性。虽然过去两年中已经修复了许多名为 Hyper-V 特权提升的漏洞,但 Hyper-V 是一个很大的组件。在相关的 CVE 描述中,微软并未透露 Hyper-V 堆栈中的哪个组件存在漏洞,因此可能是用户模式提升进程、内核驱动程序或虚拟机管理程序本身,而这正是我所针对的组件。
因此,我决定将 Hyper-V 降级到两年前的版本,似乎有足够的时间让我确信在我选择的版本中至少有一个未修复的虚拟机管理程序特权提升漏洞。
再次,我能够使用 Windows 更新接管成功降级虚拟机管理程序和虚拟机管理程序加载器!
这使我能够将权限从 Ring3-VTL0 提升到 Ring -1,从而有可能危及整个虚拟化堆栈。我发现虚拟化堆栈的任何组件都没有降级缓解措施 — 整个堆栈都容易受到降级影响。
演示
为了看到这些功能的实际效果,以下演示展示了我如何利用降级流程成功降级虚拟机管理程序。
供应商回应
就我们最初的研究而言,SafeBreach 坚定地致力于负责任的披露。根据这一承诺,我们于 2024 年 2 月向 Microsoft 通报了我们的研究结果。Microsoft 发布了两个 CVE(CVE-2024-21302和CVE-2024-38202),并发送了以下官方回应:
“我们感谢 SafeBreach 通过协调漏洞披露识别并负责任地报告此漏洞的工作。我们正在积极开发缓解措施来防范这些风险,同时遵循涉及彻底调查、更新所有受影响版本的开发和兼容性测试的广泛流程,以确保最大限度地保护客户,同时最大限度地减少运营中断。”
Microsoft 通过安全更新指南 ADV24216903提供了额外指导,并要求我们指导任何对其响应计划有进一步疑问的人直接联系 Microsoft 通讯团队[email protected]。
结论
这项研究旨在探索 Windows 更新过程,以确定如何操纵它以发起降级攻击。我能够展示如何使完全修补的 Windows 计算机容易受到数千个过去漏洞的影响,将已修复的漏洞变成零日漏洞,并使世界上任何 Windows 计算机上的“完全修补”一词都变得毫无意义。我们认为,这不仅对世界上使用最广泛的桌面操作系统 Microsoft Windows 具有重大影响,而且对可能容易受到降级攻击的其他操作系统供应商也具有重大影响。为了帮助减轻本研究发现的漏洞的潜在影响,我们:
-
如上所述,我们于 2024 年 2 月负责任地向微软披露了我们的研究结果。
-
在这里以及在我的Black Hat USA 2024和DEF CON 32 (2024) 演示中与更广泛的安全社区公开分享我的研究,以便利用 Windows 操作系统的组织和最终用户更好地了解与这些漏洞相关的风险。
-
提供了一个研究存储库,其中包含能够验证和利用这些漏洞的工具,作为进一步研究和开发的基础。
-
在 SafeBreach 平台中添加了以下攻击内容,使我们的客户能够针对本研究中概述的漏洞和技术验证其环境,从而显著降低风险。这些攻击允许攻击者潜在地接管 Windows 更新过程,将 Windows 降级到旧版本,并使其容易受到任何已知的一日漏洞的攻击。
-
#10341 – Windows Downdate – Windows 更新接管
-
#10342 – Windows 降级 – TrustedInstaller 提升
致谢
我还要对以下才华横溢的个人所做的工作表示感谢:
-
James Forsahw (@tiraniddo) – CVE-2022-34709
-
Saar Amar (@AmarSaar) – CVE-2021-27090
-
Gabriel Landau (@GabrielLandau) – PPLFault
-
Valentina Palmiotti (@chompie1337), Ruben Boonen (@FuzzySec) – CVE-2023-21768 Exploit
-
Benjamin Delphi (@gentilkiwi) – Mimikatz
原文始发于微信公众号(Ots安全):Windows Downdate:利用 Windows 更新进行降级攻击
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论