在上一轮补丁星期二中,Windows 错误报告服务修复了两个权限提升漏洞,分别编号为 CVE-2020-0753 和 CVE-2020-0754。这两个漏洞均利用了该服务在文件系统操作中的一个竞态条件漏洞。然而,由于竞争窗口较小且文件释放位置不确定,这两个漏洞并不容易利用。在此我们分享利用它们的技术。
我们的报告中给出了两个竞态漏洞的根本原因,其实际原因可概括为 可预测即存在风险。当 WER 服务处理临时文件时,它会操作文件位置 C:\ProgramData\Microsoft\Windows\WER\Temp,该目录对于经过身份验证的用户是可读写(R/W)的。这意味着一个中等 IL 的普通用户可以覆盖 WER 服务创建的文件,甚至可以将其转换为文件系统链接,从而破坏或删除原本无法触及的其他文件。
为确保文件操作安全,WER 服务依赖一个名为 GetTempFileNameW 的标准 API,并用 wersvc.dll->UtilGetTempFile 对其进行封装。该 API 会帮助 WerSvc 生成未被占用的随机文件名,格式为 "WER****.tmp"。
文件名的随机部分由一个 4 字节十六进制数生成,范围从 0000 到 FFFF。如果某个数字已被用于创建文件,API 将会选取另一个随机文件名。
这种策略显然存在缺陷:如果某人创建了 65535 个文件,名称从 WER0000.tmp 到 WERFFFE.tmp,那么 API 会选择一个随机数并测试该文件名是否存在,例如 WERA560.tmp。它会发现文件已存在,于是会从 WERA560.tmp 继续测试直到 WERFFFF.tmp。在测试过程中,由于我们找到了一种方法使 WerSvc 在 GetTempFileNameW 调用上停滞 4-5 秒,从而出现了一个相当大的准备窗口。在此期间,我们强制该服务以固定文件名 WERFFFF.tmp 丢弃一个临时文件。
服务创建名为 WERFFFF.tmp 的临时文件后,API 会自动关闭其对文件持有的句柄,并将文件名返回给服务以进行后续操作。这正是引入漏洞的位置。此时满足三个条件:
在这里,服务会 向文件中写入内容并删除该文件。通过利用文件系统链接和某些利用技术,写入和删除操作均会导致权限提升。
为了将漏洞转化为任意文件删除,我们创造性地利用了多层目录交汇点来完成利用。我们的利用包含以下步骤:
WER***.tmp 放在 $pwd\1\ 中,并创建目录交汇点 $pwd\2\ -> $pwd\1\;$pwd\2\ 触发该功能,并创建另一个进程持续执行命令 SetOplock $pwd\1\WERFFFF.tmp;$pwd\2\ 重新指向 \RPC CONTROL\,然后创建对象符号链接 \RPC CONTROL\WERFFFF.tmp -> $target 和 \RPC CONTROL\WERFFFF.tmp.etl -> $target;详细的利用方法和 PoC 见 WERReport-CVE-2020-0753。
通过利用 GetTempFileNameW 中的缺陷,我们获得了服务将要操作的可预测位置;通过使用多层文件系统交汇点,我们使竞态条件变得可靠可被利用。
同时,我们注意到这种竞态漏洞也可能导致文件覆盖问题,从而在特定情况下可能导致权限提升漏洞。
为了解释为什么任意文件破坏(如果能够控制文件内容中很小的一部分:少于 63 字节)可以转化为 EoP,我们需要关注 Windows Defender 的工作机制。
Windows Defender 有一个恶意软件特征库。如果某个文件包含某些恶意软件特征,Defender 会将其视为恶意软件并删除。然而,这一特性会引入额外的攻击面。例如,在 WCTF2019 中,来自 tokyowesterns 的 @icchy 设计了一个名为 "Gyotaku The Flag" 的 Windows CTF 挑战,该挑战利用此特性作为预言机来泄露信息。
这里我们利用 Windows Defender 的这一特性,在拥有部分可控内容的任意文件破坏能力时,删除任意文件。我们可以简单地将一个恶意软件特征写入文件,然后触发 Windows Defender 的默认扫描,该文件将被放入 Defender 的隔离区。普通用户(即中等 IL 的非管理员用户)只需触发两次扫描操作即可删除该文件。
因此,只要能够通过漏洞将恶意软件特征字符串写入目标文件,任意文件破坏漏洞就可以转化为任意文件删除漏洞。
利用漏洞破坏目标文件,并将一个 Windows Defender 可识别的特征字符串写入其中。
触发 Windows Defender 扫描目标文件,导致文件被隔离。
再次触发扫描,目标文件被删除。
通过利用此技术,我们借助 Defender 实现了任意文件删除。
任意文件删除可以更容易地用于进一步提权。
Microsoft OneDrive 是提供个人云存储服务的应用程序套件。自 Windows 8 起,该应用程序已作为默认安装选项集成到 Windows 中。在我们的研究过程中,我们在 OneDrive 的服务计划任务中发现了 6 个漏洞,并已提交给 MSRC。
以下是我们在 Microsoft OneDrive 相关计划任务中将要披露的漏洞表格:
| 易受攻击的程序 | 类型 | 是否提供 PoC |
|---|---|---|
| FileSyncConfig.exe | HardLink | 是 |
| FileSyncHelper.exe | HardLink | 是 |
| OneDriveFileSyncConfig.exe | SymLink | 是 |
| OneDriveSetup.exe | HardLink | 是 |
| OneDriveSetup.exe | HardLink | 是 |
| OneDriveStandaloneUpdater.exe | HardLink | 是 |
所有这 6 个漏洞均由服务在处理硬链接和符号链接时不当,且操作位置普通用户可控所致。在利用这些漏洞时,一个难点在于文件名通常包含当前进程的 PID 或操作时间戳。两者都可以通过设置 Oplock 在服务触发运行时将尝试加载的某个唯一 DLL 文件上解决,这样我们就能获取预测服务后续操作文件名所需的一切信息。FileSyncConfigTemp_hardlink 目录中提供了一个示例 PoC。
上述 6 个漏洞均提供了完整的报告和 PoC 程序。尽管大多数漏洞最初导致任意文件破坏,但这种漏洞仍会导致系统崩溃(通过覆盖关键系统配置文件),并且所有这些漏洞都需要重新安装 Windows。因此符合 Windows 系统拒绝服务漏洞类型的标准。
此外,此类漏洞在特定情况下实际上可以导致权限提升。我们已经讨论了利用任意文件覆盖问题实现任意文件删除原语,从而实现权限提升的技术。
Zhiniang Peng of Qihoo 360 Core Security
2020 年 2 月 2 日: 提交漏洞报告
2020 年 2 月 8 日: MSRC 调查并回复了我们提交的 OneDrive 6 个漏洞,结论是因 需要过多用户交互/难以构建可靠的利用 而不修复。
2020 年 2 月 8 日: 我们回复:不需要用户交互。只需等待计划任务运行即可。因此,此场景是典型的。
2020 年 2 月 11 日: MSRC 回复:你如何获取用户机器上的特定文件?你是否将该文件的每种排列都放在该文件夹中?它是否必须精确匹配日期/小时/PID?出于这些原因,这似乎需要过多的用户操作。
2020 年 2 月 11 日: 我们回复:我们的 PoC 是简化版本。为了减少预测文件名的难度。实际上,你只需设置一个 Oplock,就可以获得所有 {pid}、{hour}、{data}。因此不需要用户交互。
2020 年 2 月 12 日: 询问我们是否可以发布这 6 个漏洞的分析报告。
2020 年 2 月 13 日: MSRC 回复:你可以发布分析报告。
2020 年 2 月 22 日: 细节发布。
状态更新:这 6 个漏洞均在 2020 年 3 月的补丁星期二中获得了修复。