CVE‑2019‑1132:利用Windows 0day的攻击活动

 

0x00 前言

2019年6月,ESET研究人员发现攻击者利用一个0day漏洞对东欧地区发起攻击。

攻击者滥用了Windows系统中的一个本地权限提升漏洞,更具体一点是win32k.sys组件中对NULL指针解引用(dereference)的一个漏洞。我们在发现并分析这个漏洞利用技术后,就第一时间反馈给MSRC,MSRC及时修复了漏洞并发布了安全补丁。

该漏洞影响如下Windows版本:

Windows 7 for 32-bit Systems Service Pack 1
Windows 7 for x64-based Systems Service Pack 1
Windows Server 2008 for 32-bit Systems Service Pack 2
Windows Server 2008 for Itanium-Based Systems Service Pack 2
Windows Server 2008 for x64-based Systems Service Pack 2
Windows Server 2008 R2 for Itanium-Based Systems Service Pack 1
Windows Server 2008 R2 for x64-based Systems Service Pack 1

本文重点关注该漏洞的技术细节及利用方式。在另一篇文章中,我们将深入分析这个恶意样本及其他相关信息。

 

0x01 漏洞利用

这几年来研究人员公布了Windows win32k.sys组件的几个漏洞,与这些漏洞类似,此次攻击者利用的也是弹出菜单对象。我们在2017年也分析过Sednit攻击组织利用过的本地提权漏洞,当时攻击者利用的也是菜单对象,与此次攻击方法非常类似。

漏洞利用过程中创建了两个窗口,分别用于第一及第二漏洞利用阶段。对于第一个窗口,漏洞利用程序会使用CreatePopupMenu以及AppendMenu函数来创建弹出菜单对象并追加菜单项。此外,利用程序还会设置WH_CALLWNDPROC以及EVENT_SYSTEM_MENUPOPUPSTART类型的hook。

随后利用程序会使用TrackPopupMenu函数来显示该菜单。此时hook EVENT_SYSTEM_MENUPOPUPSTART对应的代码会被执行。该代码会向目标菜单依次发送MN_SELECTITEMMN_SELECTFIRSTVALIDITEM以及MN_OPENHIERARCHY消息,尝试打开菜单中第一个可用项。

下一个步骤对触发漏洞来说非常重要。漏洞利用程序必须及时抓住初始菜单已创建、且子菜单即将创建的时机。为了完成该任务,利用程序专门包含某些代码,用来处理在WH_CALLWNDPROC hook中的WM_NCCREATE消息。当利用代码检测到系统处于该状态时,就会向第一个菜单发送MN_CANCELMENUS0x1E6)消息,取消该菜单。然而,该菜单对应的子菜单依然即将会被创建。

现在如果我们在内核模式中观察这个子菜单对象,可以看到tagPOPUPMENU‑>ppopupmenuRoot的值等于0。该状态允许攻击者在这个内核结构中使用该元素作为NULL指针执行dereference操作。利用代码会在0x00地址处分配一个新页,而该地址会被内核当成一个tagPOPUPMENU对象(如图1所示)。

图1. tagPOPUPMENU内核结构

此时攻击者会使用第二个窗口。这里漏洞利用的主要目标是翻转第二个窗口tagWND结构中的bServerSideWindowProc位,成功翻转后内核模式中就会执行WndProc过程。

为了完成该任务,攻击者会调用user32.dll库中未导出的HMValidateHandle函数,泄露第二个窗口tagWND结构的内核内存地址。随后利用程序会在NULL页构造一个虚假的tagPOPUPMENU对象,向子菜单发送MN_BUTTONDOWN消息。

完成该操作后,内核最终会执行win32k!xxxMNOpenHierarchy函数。

图2. win32k!xxxMNOpenHierarchy函数的反汇编代码

该函数会将NULL页面上构造的对象传递给win32k!HMAssignmentLock,而win32k!HMAssignmentLock函数在经过几次调用后,会调用win32k!HMDestroyUnlockedObject函数,后者会设置bServerSideWindowProc位。

图3. win32k!HMDestroyUnlockedObject函数的反汇编代码

现在一切准备就绪,利用代码会向第二个窗口发送特定的消息,以便在内核模式中执行WndProc

在最后一个攻击步骤中,利用代码会使用系统令牌替换当前进程的令牌。

微软已发布安全补丁,在win32k!xxxMNOpenHierarchy函数添加了针对NULL指针的检查过程。

图4. win32k.sys打补丁前(左图)后(右图)的代码对比

 

0x02 总结

这个漏洞利用技术只适用于老版本的Windows系统,因为从Windows 8开始,用户进程再也不能映射NULL页面。微软将这种缓解措施一并移植到了基于x64架构的Windows 7系统中。

如果大家还在使用32位的Windows 7 Service Pack 1,可以考虑更新到最新版的操作系统。Windows 7 Service Pack 1的扩展支持将于2020年1月14日结束,这意味着后续Windows 7用户无法获得关键安全更新,因此像这样的漏洞永远不会被官方修复。

 

0x03 IoC

SHA-1哈希 ESET检测特征
CBC93A9DD769DEE98FFE1F43A4F5CADAF568E321 Win32/Exploit.CVE-2019-1132.A
(完)