The Windows Registry Adventure #1: Introduction and research results

In the 20-month period between May 2022 and December 2023, I thoroughly audited the Windows Registry in search of local privilege escalation bugs. It all started unexpectedly: I was in the process of developing a coverage-based Windows kernel fuzzer based on the Bochs x86 emulator (one of my favorite tools for security research: see BochspwnBochspwn Reloaded, and my earlier font fuzzing infrastructure), and needed some binary formats to test it on. My first pick were PE files: they are very popular in the Windows environment, which makes it easy to create an initial corpus of input samples, and a basic fuzzing harness is equally easy to develop with just a single GetFileVersionInfoSizeW API call. The test was successful: even though I had previously fuzzed PE files in 2019, the new element of code coverage guidance allowed me to discover a completely new bug: issue #2281.
在 2022 年 5 月至 2023 年 12 月的 20 个月期间,我彻底审核了 Windows 注册表以查找本地权限提升错误。这一切都出乎意料地开始了:我正在开发一个基于 Bochs x86 模拟器的基于覆盖率的 Windows 内核模糊器(我最喜欢的安全研究工具之一:参见 Bochspwn、Bochspwn Reloaded 和我早期的字体模糊测试基础设施),并且需要一些二进制格式来测试它。我首先选择的是 PE 文件:它们在 Windows 环境中非常流行,这使得创建输入示例的初始语料库变得容易,并且只需调用一个 GetFileVersionInfoSizeW API 即可轻松开发基本的模糊测试工具。测试是成功的:尽管我之前在 2019 年对 PE 文件进行了模糊处理,但代码覆盖率指南的新元素让我发现了一个全新的错误:问题 #2281。

For my next target, I chose the Windows registry. That’s because arbitrary registry hives can be loaded from disk without any special privileges via the RegLoadAppKey API (since Windows Vista). The hives use a binary format and are fully parsed in the kernel, making them a noteworthy local attack surface. Furthermore, I was also somewhat familiar with basic harnessing of the registry, having fuzzed it in 2016 together with James Forshaw. Once again, the code coverage support proved useful, leading to the discovery of issue #2299. But when I started to perform a root cause analysis of the bug, I realized that:
对于我的下一个目标,我选择了 Windows 注册表。这是因为可以通过 RegLoadAppKey API(从 Windows Vista 开始)从磁盘加载任意注册表配置单元,而无需任何特殊权限。这些配置单元使用二进制格式,并在内核中完全解析,使其成为值得注意的局部攻击面。此外,我还对注册表的基本利用有些熟悉,曾在 2016 年与 James Forshaw 一起对其进行了模糊处理。代码覆盖率支持再次被证明是有用的,导致发现了问题 #2299。但是当我开始对错误进行根本原因分析时,我意识到:

  • The hive binary format is not very well suited for trivial bitflipping-style fuzzing, because it is structurally simple, and random mutations are much more likely to render (parts of) the hive unusable than to trigger any interesting memory safety violations.
    hive 二进制格式不太适合简单的 bitflipping 风格的模糊测试,因为它在结构上很简单,并且随机突变更有可能使 hive (部分)不可用,而不是触发任何有趣的内存安全违规。
  • On the other hand, the registry has many properties that make it an attractive attack surface for further research, especially for manual review. It is 30+ years old, written in C, running in kernel space but highly accessible from user-mode, and it implements much more complex logic than I had previously imagined.
    另一方面,注册表具有许多属性,使其成为进一步研究的有吸引力的攻击面,尤其是对于手动审查。它已经有 30+ 年的历史了,用 C 语言编写,在内核空间中运行,但可以从用户模式高度访问,它实现了比我以前想象的要复杂得多的逻辑。

And that’s how the story starts. Instead of further refining the fuzzer, I made a detour to reverse engineer the registry implementation in the Windows kernel (internally known as the Configuration Manager) and learn more about its inner workings. The more I learned, the more hooked I became, and before long, I was all-in on a journey to audit as much of the registry code as possible. This series of blog posts is meant to document what I’ve learned about the registry, including its basic functionality, advanced features, security properties, typical bug classes, case studies of specific vulnerabilities, and exploitation techniques.
故事就是这样开始的。我没有进一步优化模糊器,而是绕道对 Windows 内核(内部称为 Configuration Manager)中的注册表实现进行逆向工程,并详细了解其内部工作原理。我学得越多,我就越着迷,不久之后,我就全身心地投入到尽可能多地审计注册表代码的旅程中。本系列博客文章旨在记录我对注册表的了解,包括其基本功能、高级功能、安全属性、典型错误类、特定漏洞的案例研究以及利用技术。

While this blog is one of the first places to announce this effort, I did already give a talk titled “Exploring the Windows Registry as a powerful LPE attack surface” at Microsoft BlueHat Redmond in October 2023 (see slides and video recording). The upcoming blog posts will go into much deeper detail than the presentation, but if you’re particularly curious and can’t wait to find out more, feel free to check these resources as a starter. 🙂
虽然这个博客是最早宣布这项工作的地方之一,但我确实已经在 2023 年 10 月的 Microsoft BlueHat Redmond 上发表了题为“探索 Windows 注册表作为强大的 LPE 攻击面”的演讲(请参阅幻灯片和视频录制)。即将发布的博客文章将比演示文稿更深入,但如果您特别好奇并且迫不及待地想了解更多信息,请随时查看这些资源作为初学者。🙂

Research results 研究成果

In the course of the research, I filed 39 bug reports in the Project Zero bug tracker, which have been fixed by Microsoft as 44 CVEs. There are a few reasons for the discrepancy between these numbers:
在研究过程中,我在Project Zero错误跟踪器中提交了39个错误报告,Microsoft将其修复为44个CVE。这些数字之间存在差异有几个原因:

  • Some single reports included information about multiple problems, e.g. issue #2375 was addressed by four CVEs,
    一些单个报告包含有关多个问题的信息,例如问题 #2375 由四个 CVE 解决,
  • Some groups of reports were fixed with a single patch, e.g. issues #2392 and #2408 as CVE-2023-23420,
    某些报告组已通过单个补丁进行修复,例如问题 #2392 和 #2408 为 CVE-2023-23420,
  • One bug report was closed as WontFix and not addressed in a security bulletin at all (issue #2508).
    一个错误报告作为 WontFix 关闭,并且根本没有在安全公告中解决(问题 #2508)。

All of the reports were submitted under the Project Zero 90-day disclosure deadline policy, and Microsoft successfully met the deadline in all cases. The average time from report to fix was 81 days.
所有报告都是根据 Project Zero 90 天披露截止日期政策提交的,Microsoft 在所有情况下都成功地满足了截止日期。从报告到修复的平均时间为 81 天。

Furthermore, between November 2023 and January 2024, I reported 20 issues that had low or unclear security impact, but I believed the vendor should nevertheless be made aware of them. They were sent without a disclosure deadline and weren’t put on the PZ tracker; I have since published them on our team’s GitHub. Upon assessment, Microsoft decided to fix 6 of them in a security bulletin in March 2024, while the other 14 were closed as WontFix with the option of being addressed in a future version of Windows.
此外,在 2023 年 11 月至 2024 年 1 月期间,我报告了 20 个安全影响不大或不明确的问题,但我认为供应商仍然应该意识到这些问题。它们是在没有披露截止日期的情况下发送的,也没有放在 PZ 跟踪器上;从那以后,我将它们发布在我们团队的 GitHub 上。经过评估,Microsoft 决定在 2024 年 3 月的安全公告中修复其中的 6 个,而其他 14 个则作为 WontFix 关闭,并可选择在未来版本的 Windows 中解决。

This sums up to a total of 50 CVEs, classified by Microsoft as:
这总共有 50 个 CVE,由 Microsoft 分类为:

  • 39 × Windows Kernel Elevation of Privilege Vulnerability
    39 × Windows 内核特权提升漏洞
  • 9 × Windows Kernel Information Disclosure Vulnerability
    9 × Windows 内核信息泄露漏洞
  • 1 × Windows Kernel Memory Information Disclosure Vulnerability
    1 × Windows 内核内存信息泄露漏洞
  • 1 × Windows Kernel Denial of Service Vulnerability
    1 × Windows 内核拒绝服务漏洞

A full summary of the security-serviced bugs is shown below:
安全服务错误的完整摘要如下所示:

GPZ #

CVE

Title

Reported

Fixed

2295

CVE-2022-34707

Windows Kernel use-after-free due to refcount overflow in registry hive security descriptors
由于注册表配置单元安全描述符中的 refcount 溢出,Windows 内核释放后使用

2022-May-11

2022-Aug-09

2297

CVE-2022-34708

Windows Kernel invalid read/write due to unchecked Blink cell index in root security descriptor
由于根安全描述符中未选中的闪烁单元格索引,Windows 内核读/写无效

2022-May-17

2299

CVE-2022-35768

Windows Kernel multiple memory problems when handling incorrectly formatted security descriptors in registry hives
Windows 内核:处理注册表配置单元中格式不正确的安全描述符时出现多个内存问题

2022-May-20

2318

CVE-2022-37956

Windows Kernel integer overflows in registry subkey lists leading to memory corruption
注册表子项列表中的 Windows 内核整数溢出导致内存损坏

2022-Jun-22

2022-Sep-13

2330

CVE-2022-37988

Windows Kernel registry use-after-free due to bad handling of failed reallocations under memory pressure
Windows 内核注册表释放后使用,这是由于在内存压力下对失败的重新分配处理不当

2022-Jul-8

2022-Oct-11

2332

CVE-2022-38037

Windows Kernel memory corruption due to type confusion of subkey index leaves in registry hives
由于注册表配置单元中子项索引的类型混淆而导致的 Windows 内核内存损坏

2022-Jul-11

2341

CVE-2022-37990

Windows Kernel multiple memory corruption issues when operating on very long registry paths
在很长的注册表路径上运行时,Windows 内核多个内存损坏问题

2022-Aug-3

CVE-2022-38039

CVE-2022-38038

2344

CVE-2022-37991

Windows Kernel out-of-bounds reads and other issues when operating on long registry key and value names
对长注册表项和值名称进行操作时,Windows 内核越界读取和其他问题

2022-Aug-5

2359

CVE-2022-44683

Windows Kernel use-after-free due to bad handling of predefined keys in NtNotifyChangeMultipleKeys
由于 NtNotifyChangeMultipleKeys 中预定义键处理不当,Windows 内核在释放后使用

2022-Sep-22

2022-Dec-13

2366

CVE-2023-21675

Windows Kernel memory corruption due to insufficient handling of predefined keys in registry virtualization
由于注册表虚拟化中未充分处理预定义项而导致的 Windows 内核内存损坏

2022-Oct-6

2023-Jan-10

2369

CVE-2023-21747

Windows Kernel use-after-free due to dangling registry link node under paged pool memory pressure
Windows 内核在释放后使用,因为在分页池内存压力下悬空注册表链接节点

2022-Oct-13

2389

CVE-2023-21748

Windows Kernel registry virtualization incompatible with transactions, leading to inconsistent hive state and memory corruption
Windows 内核注册表虚拟化与事务不兼容,导致配置单元状态和内存损坏不一致

2022-Nov-30

2375

Windows Kernel multiple issues in the key replication feature of registry virtualization
Windows 内核注册表虚拟化的关键复制功能中的多个问题

2022-Oct-25

CVE-2023-21772

CVE-2023-21773

CVE-2023-21774

2378

CVE-2023-21749

Windows Kernel registry SID table poisoning leading to bad locking and other issues
Windows 内核注册表 SID 表中毒导致锁定错误和其他问题

2022-Oct-31

CVE-2023-21776

2379

CVE-2023-21750

Windows Kernel allows deletion of keys in virtualizable hives with KEY_READ and KEY_SET_VALUE access rights

2022-Nov-2

2392

CVE-2023-23420

Windows Kernel multiple issues with subkeys of transactionally renamed registry keys

2022-Dec-7

2023-Mar-14

2408

Windows Kernel insufficient validation of new registry key names in transacted NtRenameKey

2023-Jan-13

2394

CVE-2023-23421

Windows Kernel multiple issues in the prepare/commit phase of a transactional registry key rename

2022-Dec-14

CVE-2023-23422

CVE-2023-23423

2410

CVE-2023-28248

Windows Kernel CmpCleanupLightWeightPrepare registry security descriptor refcount leak leading to UAF

2023-Jan-19

2023-Apr-11

2418

CVE-2023-28271

Windows Kernel disclosure of kernel pointers and uninitialized memory through registry KTM transaction log files

2023-Jan-31

2419

CVE-2023-28272

Windows Kernel out-of-bounds reads when operating on invalid registry paths in CmpDoReDoCreateKey/CmpDoReOpenTransKey

2023-Feb-2

CVE-2023-28293

2433

CVE-2023-32019

Windows Kernel KTM registry transactions may have non-atomic outcomes

2023-Mar-7

2023-Jun-13

2445

CVE-2023-35356

Windows Kernel arbitrary read by accessing predefined keys through differencing hives

2023-Apr-19

2023-Jul-11

2452

Windows Kernel CmDeleteLayeredKey may delete predefined tombstone keys, leading to security descriptor UAF

2023-May-10

2446

CVE-2023-35357

Windows Kernel may reference unbacked layered keys through registry virtualization

2023-Apr-20

2447

CVE-2023-35358

Windows Kernel may reference rolled-back transacted keys through differencing hives

2023-Apr-27

2449

CVE-2023-35382

Windows Kernel renaming layered keys doesn’t reference count security descriptors, leading to UAF

2023-May-2

2023-Aug-8

2454

CVE-2023-35386

Windows Kernel out-of-bounds reads due to an integer overflow in registry .LOG file parsing

2023-May-15

2456

CVE-2023-38154

Windows Kernel partial success of registry hive log recovery may lead to inconsistent state and memory corruption
Windows 内核注册表配置单元日志恢复部分成功可能会导致状态和内存损坏不一致

2023-May-22

2457

CVE-2023-38139

Windows Kernel doesn’t reset security cache during self-healing, leading to refcount overflow and UAF
Windows 内核在自我修复期间不会重置安全缓存,从而导致 refcount 溢出和 UAF

2023-May-31

2023-Sep-12

2462

CVE-2023-38141

Windows Kernel passes user-mode pointers to registry callbacks, leading to race conditions and memory corruption
Windows 内核将用户模式指针传递给注册表回调,从而导致争用条件和内存损坏

2023-Jun-26

2463

CVE-2023-38140

Windows Kernel paged pool memory disclosure in VrpPostEnumerateKey
VrpPostEnumerateKey 中的 Windows 内核分页池内存泄漏

2023-Jun-27

2464

CVE-2023-36803

Windows Kernel out-of-bounds reads and paged pool memory disclosure in VrpUpdateKeyInformation
VrpUpdateKeyInformation 中的 Windows 内核越界读取和分页池内存泄漏

2023-Jun-27

2466

CVE-2023-36576

Windows Kernel containerized registry escape through integer overflows in VrpBuildKeyPath and other weaknesses
Windows 内核容器化注册表通过 VrpBuildKeyPath 中的整数溢出和其他弱点进行转义

2023-Jul-7

2023-Oct-10

2479

CVE-2023-36404

Windows Kernel time-of-check/time-of-use issue in verifying layered key security may lead to information disclosure from privileged registry keys
验证分层密钥安全性时的 Windows 内核检查时间/使用时间问题可能会导致特权注册表项的信息泄露

2023-Aug-10

2023-Nov-14

2480

CVE-2023-36403

Windows Kernel bad locking in registry virtualization leads to race conditions
注册表虚拟化中的 Windows 内核错误锁定导致争用条件

2023-Aug-22

2492

CVE-2023-35633

Windows registry predefined keys may lead to confused deputy problems and local privilege escalation
Windows 注册表预定义项可能会导致混淆代理问题和本地权限提升

2023-Oct-6

2023-Dec-12

2511

CVE-2024-26182

Windows Kernel subkey list use-after-free due to mishandling of partial success in CmpAddSubKeyEx
由于 CmpAddSubKeyEx 中部分成功的处理不当,Windows 内核子项列表释放后使用

2023-Dec-13

2024-Mar-12

None (MSRC-84131) 无 (MSRC-84131)

CVE-2024-26174

Windows Kernel out-of-bounds read of key node security in CmpValidateHiveSecurityDescriptors when loading corrupted hives
加载损坏的配置单元时,CmpValidateHiveSecurityDescriptors 中的关键节点安全性的 Windows 内核越界读取

2023-Nov-29

None (MSRC-84149) 无 (MSRC-84149)

CVE-2024-26176

Windows Kernel out-of-bounds read when validating symbolic links in CmpCheckValueList
验证 CmpCheckValueList 中的符号链接时,Windows 内核越界读取

2023-Nov-29

None (MSRC-84046) 无 (MSRC-84046)

CVE-2024-26173

Windows Kernel allows the creation of stable subkeys under volatile keys via registry transactions
Windows 内核允许通过注册表事务在易失性键下创建稳定的子项

2023-Nov-30

None (MSRC-84228) 无 (MSRC-84228)

CVE-2024-26177

Windows Kernel unsafe behavior in CmpUndoDeleteKeyForTrans when transactionally re-creating registry keys
以事务方式重新创建注册表项时,CmpUndoDeleteKeyForTrans 中的 Windows 内核不安全行为

2023-Dec-1

None (MSRC-84237) 无 (MSRC-84237)

CVE-2024-26178

Windows Kernel security descriptor linked list confusion in CmpLightWeightPrepareSetSecDescUoW
CmpLightWeightPrepareSetSecDescUoW 中的 Windows 内核安全描述符链表混淆

2023-Dec-1

None (MSRC-84263) 无 (MSRC-84263)

CVE-2024-26181

Windows Kernel registry quota exhaustion may lead to permanent corruption of the SAM database
Windows 内核注册表配额耗尽可能会导致 SAM 数据库永久损坏

2023-Dec-11

Exploitability 可利用性

Software bugs are typically only interesting to either the offensive/defensive sides of the security community if they have practical security implications. Unfortunately, it is impossible to give a blanket statement regarding the exploitability of all registry-related vulnerabilities due to their sheer diversity on a number of levels:
软件错误通常只对安全社区的进攻/防御双方感兴趣,前提是它们具有实际的安全影响。不幸的是,由于所有与注册表相关的漏洞在多个层面上的多样性,因此不可能对所有注册表相关漏洞的可利用性给出笼统的声明:

  • Affected platforms: Windows 10, Windows 11, various Windows Server versions (32/64-bit)
    受影响的平台:Windows 10、Windows 11、各种 Windows Server 版本(32/64 位)
  • Attack targets: the kernel itself, drivers implementing registry callbacks, privileged user-mode applications/services
    攻击目标:内核本身、实现注册表回调的驱动程序、特权用户模式应用程序/服务
  • Entry points: direct registry operations, hive loading, transaction log recovery
    入口点:直接注册表操作、配置单元加载、事务日志恢复
  • End results: memory corruption, broken security guarantees, broken API contracts, memory/pointer disclosure, out-of-bounds reads, invalid/controlled cell index accesses
    最终结果:内存损坏、安全保证中断、API 协定损坏、内存/指针泄露、越界读取、无效/受控单元索引访问
  • Root cause of issues: C-specific, logic errors, bad reference counting, locking problems
    问题的根本原因:特定于 C 语言、逻辑错误、引用计数错误、锁定问题
  • Nature of memory corruption: temporal (use-after-free), spatial (buffer overflows)
    内存损坏的性质:时间性(释放后使用)、空间性(缓冲区溢出)
  • Types of corrupted memory: kernel pools, hive data
    损坏的内存类型:内核池、配置单元数据
  • Exploitation time: instant, up to several hours
    利用时间:即时,长达数小时

As we can see, there are multiple factors at play that determine how the bugs came to be and what state they leave the system in after being triggered. However, to get a better understanding of the impact of the findings, I have performed a cursory analysis of the exploitability of each bug, trying to classify it as either “easy”, “moderate” or “hard” to exploit according to my current knowledge and experience (this is of course highly subjective). The proportions of these exploitability ratings are shown in the chart below:
正如我们所看到的,有多种因素在起作用,这些因素决定了错误是如何形成的,以及它们在被触发后离开系统的状态。但是,为了更好地了解这些发现的影响,我对每个漏洞的可利用性进行了粗略的分析,试图根据我目前的知识和经验将其归类为“容易”、“中等”或“难以”利用(这当然是高度主观的)。这些可利用性等级的比例如下图所示:

The Windows Registry Adventure #1: Introduction and research results

The ratings were largely based on the following considerations:
评级主要基于以下考虑因素:

  • Hive-based memory corruption is generally considered easy to exploit, while pool-based memory corruption is considered moderate/hard depending on the specifics of the bug.
    基于 Hive 的内存损坏通常被认为易于利用,而基于池的内存损坏被认为是中等/困难的,具体取决于 bug 的具体情况。
  • Triggering OOM-type conditions in the hive space is easy, but completely exhausting the kernel pools is more difficult and intrusive.
    在 hive 空间中触发 OOM 类型的条件很容易,但完全耗尽内核池更加困难和侵入性。
  • Logic bugs are typically easier and more reliable to exploit than memory corruption.
    逻辑错误通常比内存损坏更容易、更可靠地被利用。
  • The kernel itself is typically easier to attack than other user-mode processes (system services etc.).
    内核本身通常比其他用户模式进程(系统服务等)更容易受到攻击。
  • Direct information disclosure (leaking kernel pointers / uninitialized memory via various channels) is usually straightforward to exploit.
    直接信息泄露(通过各种渠道泄漏内核指针/未初始化的内存)通常很容易被利用。
  • However, random out-of-bounds reads, as well as read access to invalid/controlled cell indexes is generally hard to do anything useful with.
    但是,随机越界读取以及对无效/受控单元格索引的读取访问通常很难执行任何有用操作。

Overall, it seems that more than half of the findings can be feasibly exploited for information disclosure or local privilege escalation (rated easy or moderate). What is more, many of them exhibit registry-specific bug classes which can enable particularly unique exploitation primitives. For example, hive-based memory corruption can be effectively transformed into both a KASLR bypass and a fully reliable arbitrary read/write capability, making it possible to use a single bug to compromise the kernel with a data-only attack. To demonstrate this, I have successfully developed exploits for CVE-2022-34707 and CVE-2023-23420. The outcome of running one of them to elevate privileges to SYSTEM on Windows 11 is shown on the screenshot below:
总体而言,似乎超过一半的调查结果可用于信息披露或本地权限升级(评级为简单或中等)。更重要的是,它们中的许多都表现出特定于注册表的错误类,这些错误类可以启用特别独特的利用原语。例如,基于 hive 的内存损坏可以有效地转换为 KASLR 绕过和完全可靠的任意读/写功能,从而可以使用单个错误通过纯数据攻击来破坏内核。为了证明这一点,我成功开发了针对 CVE-2022-34707 和 CVE-2023-23420 的漏洞。运行其中之一以在 Windows 11 上将权限提升到 SYSTEM 的结果显示在下面的屏幕截图中:

The Windows Registry Adventure #1: Introduction and research results

Upcoming posts in this series will introduce you to the Windows registry as a system mechanism and as an attack surface, and will dive deeper into practical exploitation using hive memory corruption, out-of-bounds cell indexes and other amusing techniques. Stay tuned!
本系列即将发布的文章将向您介绍 Windows 注册表作为系统机制和攻击面,并将更深入地探讨使用蜂巢内存损坏、越界单元格索引和其他有趣技术的实际利用。敬请关注!

原文始发于Mateusz Jurczyk, Google Project Zero:The Windows Registry Adventure #1: Introduction and research results

版权声明:admin 发表于 2024年4月27日 下午9:51。
转载请注明:The Windows Registry Adventure #1: Introduction and research results | CTF导航

相关文章