CVE-2023-29336 Win32k提权漏洞分析(含POC)

admin 2023年6月16日17:11:24评论59 views字数 4147阅读13分49秒阅读模式
CVE-2023-29336 Win32k提权漏洞分析(含POC)

背景

最近的 Microsoft 安全补丁发现了 win32k 中的一个严重权限提升漏洞,该漏洞已在现实世界的攻击中被利用。虽然该漏洞在 Win11 系统版本上看似不可利用,但对更早的系统存在较大风险。利用此类漏洞的记录臭名昭著,在深入分析中,我们深入研究了威胁行为者利用此特定漏洞所采用的方法,同时考虑了不断发展的缓解措施。我们的综合分析是在 Server 2016 上进行的。


深入研究补丁,仔细检查会发现一个相当有趣的问题,最初无法立即识别。似乎特定对象的引用计数经历了多次递增:

CVE-2023-29336 Win32k提权漏洞分析(含POC)

然而,由于 win32k 代码的古老,我们发现了一些早期的源代码注释:

CVE-2023-29336 Win32k提权漏洞分析(含POC)

增强说明:

这一宝贵的见解使我们对根本问题有了更清晰的认识。前面的代码实现似乎只专注于锁定窗口对象,无意中忽略了锁定嵌套在窗口对象中的菜单对象。


POC实施

POC: 

https://github.com/numencyber/Vulnerability_PoC/blob/main/CVE-2023-29336/poc.cpp

为了理解此窗口中菜单对象的错误引用是如何发生的,我们对漏洞功能上下文进行了全面分析。在我们的调查过程中,我们发现了一个值得注意的问题。

CVE-2023-29336 Win32k提权漏洞分析(含POC)

虽然传递给 xxxEnableMenuItem() 的菜单通常锁定在更高级别的函数中,但在这种特定情况下准确确定应保护哪个菜单对象提出了一个需要澄清的关键问题。


继续我们在 xxxEnableMenuItem 函数中的深入分析,我们仔细检查了菜单对象的潜在处理。我们的持续调查揭示了一个重大发现:MenuItemState 函数返回的菜单不仅可以包含窗口内的主菜单,还可以扩展到子菜单,在某些情况下甚至可以扩展到子菜单。

CVE-2023-29336 Win32k提权漏洞分析(含POC)

为了在概念验证 (POC) 场景中演示漏洞利用,我们精心构建了一个由三个层次组成的定制菜单结构,每个层次包含四个不同的菜单。

CVE-2023-29336 Win32k提权漏洞分析(含POC)

菜单显示出父子关系,其中菜单 D 作为菜单 C 的子菜单。这些菜单具有与 xxxEnableMenuItem 函数内的检测和评估相关的特定特征,可深入了解此漏洞的根本原因。让我们详细检查这些特征:

  1. 菜单 D 需要与系统菜单类型之一对齐的 ID 类型,例如 0xf060(关闭菜单)。这种特定的 ID 类型对于 xxxEnableMenuItem 函数中的后续菜单遍历过程至关重要。

  2. 菜单 A 也需要是系统菜单,以便于在菜单 C 的子菜单中识别指定的系统菜单类型(0xf060)。菜单 A 中存在所需的系统菜单类型会提前终止菜单搜索过程。为保证准确检测,我们必须将菜单A对应的系统菜单类型(0xf060)去掉。

  3. 为了在返回用户层过程中实现菜单C的完全释放,必须消除菜单B中对菜单C的任何引用。此步骤对于确保正确的内存重新分配至关重要。

  4. 菜单 B 的必要性和基本原则仍不确定。然而,省略菜单B似乎阻碍了菜单C的顺利发布,暗示其在解决发布过程中遇到的困难方面的潜在作用。

在xxxRedrawTitle返回用户层的过程中,关键的一步是去掉菜单C和菜单B的引用关系,这个动作有效释放菜单C。菜单 C 对象变得无效。


利用实施

A. 总体方法

在着手利用此漏洞时,必须进行初步评估,以避免在可能无法绕过关键问题的解决方案上投入大量时间。在分析其他漏洞概念证明 (PoC) 或漏洞利用时,此过程很常见。在构建针对此特定漏洞的利用程序之前,我们主要考虑了两个方向:

执行 Shellcode

基于早期的 CVE-2017-0263 和 CVE-2016-0167 漏洞,一种方法涉及执行 shellcode。但是,由于在存在此漏洞的更高版本的 Windows 中执行 shellcode 入口点和安全机制(如 SMEP)相关的潜在挑战,我们决定不采用这种方法。

使用读写原语修改令牌地址

在过去两年中,公开可用的漏洞利用已证明能够使用读写原语修改令牌地址。这些漏洞利用在桌面堆内存布局和桌面堆中的读写原语方面显示出持久的普遍性。


主要挑战在于了解如何控制 cbwndextra 的值,尤其是在重用 UAF(释放后使用)内存时。因此,我们将整个漏洞利用分为两个不同的问题:

(1) 使用 UAF 漏洞控制 cbwndextra 的值,以及 (2) 在获得对 cbwndextra 值的控制后,为读写原语建立稳定的方法。

B. 写入第一个数据

最初触发漏洞时,系统可能不会总是崩溃。这是因为我们的触发方法消除了系统中重用漏洞的所有其他关联。只有在xxxEnableMenuItem的函数MNGetPopupFromMenu()和xxxMNUpdateShownMenu()中,系统可能会错误地使用我们控制的内存的窗口对象数据。


为了在漏洞触发期间占用释放的菜单对象,我们利用窗口类WNDClass中的窗口名称对象。第一次数据写入发生在这个过程中,我们在我们构建的地址结构中识别一个合适的位置。这个位置允许我们任意写入数据,即使它只是一个字节(可以写入cbwndextra的高位)。


这个错综复杂的过程可以比作在复杂的迷宫中导航,每一步都需要仔细考虑和分析。然而,由于涉及的复杂性和复杂性,在本次讨论的范围内深入研究该过程的细节是不可行的。

CVE-2023-29336 Win32k提权漏洞分析(含POC)

在 xxxRedrawWindow 函数中,我们确定了两种替代方法来解决相邻内存数据的操作问题。让我们更详细地探讨这些方法:

使用 GreCreateRectRgnIndirect 的方法

一种选择涉及使用 GreCreateRectRgnIndirect,但它提出了两个挑战。首先,控制 cbwndextra 的前 8 位被证明是困难的,因为它只会在特定的有限条件下短暂地变为 1。其次,当采用这种方法时,cbwndextra 的其他相对偏移量将指向前一个对象的最后 8 位(无论对象类型如何)。这最后 8 位通常表示堆链表末尾的安全字节,并且不易操纵。


依靠标志位的 AND 2 操作的方法

考虑到与第一种方法相关的困难,我们选择了一种替代方法,该方法涉及使用 AND 2 操作来操纵标志位。然而,控制堆链表末尾的安全字节仍然是一个挑战。为了克服这个障碍,我们修改了策略。我们没有写入窗口对象的 cb-extra,而是将写入操作指向了 HWNDClass 的 cb-extra。后者的cb-extra相对于前者的cb-extra有更小的偏移量,使得我们可以在xxxRedrawWindow函数中操作前一个对象的内存数据作为标志检查的参数。


C. 确保稳定的内存布局

为了实现稳定的内存布局,我们根据特定的考虑仔细设计内存结构。以下是所涉及的步骤:

  1. 连续的 HWND 对象:我们将内存布局安排为至少具有三个连续的 HWND 对象,每个对象的大小为 0x250。

  2. 释放和占用对象:我们释放中间的HWND对象,然后构造一个大小为0x250的HWNDClass对象。

  3. Flag Validation Parameter for Flag Validation:前面HWND对象的尾部数据,我们已经释放占用了HWNDClass对象,在xxxRedrawWindow函数中作为flag validation的参数。

  4. 读写原语:后续 HWND 对象的菜单对象及其相应的 HWNDClass 对象作为稳定读写原语的媒介。

  5. 大小调整和顺序验证:为了保持一致性和稳定性,我们的目标是使窗口对象和我们的 HWNDClass 对象具有相同的大小。窗口对象的扩展数据的大小应该足够大,以修改第一个窗口类对象的附加数据大小参数,如前所述。

  6. 验证对象顺序:为确保分配的窗口对象按预期顺序排列,我们利用堆内存中存在的泄漏内核句柄地址。


D. 修改读写原语

为了促进我们的利用,我们继续使用 GetMenuBarInfo() 作为任意读取原语,允许我们从我们选择的内存位置检索信息。对于任意写入原语,我们利用 SetClassLongPtr() 来执行内存写入。但是,重要的是要注意,实现我们的目标所必需的令牌写入操作的替换依赖于第二个窗口的类对象。


概括

Win32k 的状态: Win32k 漏洞的历史有据可查。不过,在最新的 Windows 11 预览版中,微软已经采取措施,使用 Rust 编程语言重构了这部分内核代码。这种重构工作有可能在未来减轻甚至消除此类漏洞,展示微软对增强系统安全性的承诺。


利用漏洞:利用此特定漏洞通常不会带来重大挑战。除了努力探索不同的方法来使用释放内存中重新占用的数据来控制第一次写入操作之外,通常不需要新的利用技术。这种类型的漏洞在很大程度上依赖于泄露的桌面堆句柄地址。虽然可能有一些修改,但如果这个问题没有得到彻底解决,它仍然是旧系统的安全风险。


漏洞发现:分析此漏洞使我们推测其发现可能取决于全面的代码覆盖测试。通过确保系统 API 沿着目标函数的执行路径到达最深的漏洞点,并考虑窗口对象的嵌套引用性质,可以通过模糊测试技术潜在地识别此漏洞。进行彻底的代码分析和测试在发现类似的此类漏洞方面起着至关重要的作用。


检测漏洞利用:除了识别漏洞触发函数中的关键点外,检测与内存布局、窗口对象或窗口类额外数据相关的异常偏移读写也是检测和缓解类似漏洞的有效方法。在漏洞利用检测工作中关注这些方面有助于主动解决此类漏洞。

这是我们实验室团队对该漏洞利用的演示:

参考

  • https://github.com/0x5bfa/NT5.1/blob/1b390dddff9fe017e9c11a7845c67a887c3483dc/Source/XPSP1/NT/windows/core/ntuser/kernel/mnsys.c#L511

  • https://github.com/L4ys/CVE-2022-21882/blob/main/CVE-2022-21882.cpp

  • https://github.com/KaLendsi/CVE-2022-21882/blob/main/ExploitTest.cpp

  • https://www.zerodayinitiative.com/blog/2023/5/8/the-may-2023-security-update-review

  • https://www.real-sec.com/2022/01/technical-analysis-of-cve-2021-1732/


感谢您抽出

CVE-2023-29336 Win32k提权漏洞分析(含POC)

.

CVE-2023-29336 Win32k提权漏洞分析(含POC)

.

CVE-2023-29336 Win32k提权漏洞分析(含POC)

来阅读本文

CVE-2023-29336 Win32k提权漏洞分析(含POC)

点它,分享点赞在看都在这里

原文始发于微信公众号(Ots安全):CVE-2023-29336 Win32k提权漏洞分析(含POC)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月16日17:11:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CVE-2023-29336 Win32k提权漏洞分析(含POC)https://cn-sec.com/archives/1809745.html

发表评论

匿名网友 填写信息