03月14, 2019

关于CVE-2019-0808内核提权漏洞的成因分析

By 成都应急响应中心 - 360核心安全

2019年3月微软发布的补丁修复了两个在野Windows零日漏洞,其中CVE-2019-0808是由谷歌威胁分析小组发现并向微软提交。 据微软称,这个影响Win32k组件的漏洞允许攻击者提升权限并在内核模式下执行任意代码。谷歌表示,该漏洞只影响Windows 7和Windows Server 2008,由于微软在最新版本的操作系统中引入了漏洞利用缓解措施,因此Windows 10不会受到影响。但是Windows 7仍然占有一定数量的用户比例,同时该漏洞结合Chrome RCE(CVE-2019-5786)已经被用于真实的APT攻击,因此极有可能被利用来执行大规模的攻击并构成现实的威胁,因此360核心安全技术中心通过编写代码构造出POC,对漏洞触发过程进行了一些还原,以便安全厂商可以增加相应的防护措施。

1. 漏洞成因

xxxMNFindWindowFromPoint函数在接收到窗口过程函数返回的菜单窗口对象后,未有效检验其成员tagPOPUPMENU的有效性,造成后续MNGetpItemFromIndex函数触发零指针解引用漏洞。

2. 漏洞触发流程

image.png

下面对主要流程进行解释。 第一步:首先需要设置全局的消息钩子函数用于拦截xxxMNFindWindowFromPoint发出的MN_FINDMENUWINDOWFROMPOINT消息。

image.png

第二步:创建拥有拖拽功能的菜单项,以及一个特殊的窗口句柄hpwn留作备用。

image.png

image.png

第三步:通过拖拽菜单或直接调用相关系统调用,使程序流程进入NtUserMNDragOver函数。

image.png

第四步:调用关系如下NtUserMNDragOver -> xxxMNMouseMove -> xxxMNFindWindowFromPoint,xxxMNFindWindowFromPoint会向窗口发送MN_FINDMENUWINDOWFROMPOINT消息并接收返回的窗口句柄。由于设置了全局消息钩子函数,执行流程又回到了用户层。

image.png

第五步:由于前面替换了菜单窗口的窗口过程函数,全局消息钩子函数执行完后即会进入FakeWindowProc函数,这里直接返回先前备用的窗口句柄hpwn。

image.png

第六步: xxxMNFindWindowFromPoint函数获得窗口句柄后,直接将其对应的窗口对象返回并传入xxxMNUpdateDraggingInfo函数。需要注意的是,这里得到的窗口对象即是之前伪造的hpwn窗口对象,其内部成员tagPOPUPMENU没有设置完全,多数成员都为0!

image.png

第七步:xxxMNUpdateDraggingInfo函数获得窗口对象后,会通过MNGetpItem函数访问其成员tagPOPUPMENU对象。

image.png

MNGetpItem函数又会继续访问tagPOPUPMENU对象的spmenu成员,从而造成零指针解引用漏洞。

image.png

image.png

3. 漏洞补丁

在3月份的Windows7补丁当中,微软修复了窗口类型混淆(不是MENU类型则返回NULL),并且检查popupMenu对象的状态,代码对比如下

补丁前:

image.png

补丁后:

image.png

4. 结论

通过构造出的POC,发现漏洞成因是在特定情况下调用NtUserMNDragOver函数时,会造成 win32k!MNGetpItemFromIndex 中的零指针解引用。该漏洞利用Windows内核驱动模块win32k.sys可以执行本地提权,提权成功后可以突破普通用户权限的限制,用作安全沙箱逃逸,完全控制用户计算机系统。

本文链接:http://blogs.360.cn/post/RootCause_CVE-2019-0808_CH.html

-- EOF --

Comments