关于 CVE-2019-0808 内核提权漏洞的成因分析
作者:成都应急响应中心-360核心安全
博客:http://blogs.360.cn/post/RootCause_CVE-2019-0808_CH.html
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. 漏洞触发流程
下面对主要流程进行解释。 第一步:首先需要设置全局的消息钩子函数用于拦截xxxMNFindWindowFromPoint发出的MN_FINDMENUWINDOWFROMPOINT消息。
第二步:创建拥有拖拽功能的菜单项,以及一个特殊的窗口句柄hpwn留作备用。
第三步:通过拖拽菜单或直接调用相关系统调用,使程序流程进入NtUserMNDragOver函数。
第四步:调用关系如下NtUserMNDragOver -> xxxMNMouseMove -> xxxMNFindWindowFromPoint,xxxMNFindWindowFromPoint会向窗口发送MN_FINDMENUWINDOWFROMPOINT消息并接收返回的窗口句柄。由于设置了全局消息钩子函数,执行流程又回到了用户层。
第五步:由于前面替换了菜单窗口的窗口过程函数,全局消息钩子函数执行完后即会进入FakeWindowProc函数,这里直接返回先前备用的窗口句柄hpwn。
第六步: xxxMNFindWindowFromPoint函数获得窗口句柄后,直接将其对应的窗口对象返回并传入xxxMNUpdateDraggingInfo函数。需要注意的是,这里得到的窗口对象即是之前伪造的hpwn窗口对象,其内部成员tagPOPUPMENU没有设置完全,多数成员都为0!
第七步:xxxMNUpdateDraggingInfo函数获得窗口对象后,会通过MNGetpItem函数访问其成员tagPOPUPMENU对象。
MNGetpItem函数又会继续访问tagPOPUPMENU对象的spmenu成员,从而造成零指针解引用漏洞。
3. 漏洞补丁
在3月份的Windows7补丁当中,微软修复了窗口类型混淆(不是MENU类型则返回NULL),并且检查popupMenu对象的状态,代码对比如下
补丁前:
补丁后:
4. 结论
通过构造出的POC,发现漏洞成因是在特定情况下调用NtUserMNDragOver函数时,会造成 win32k!MNGetpItemFromIndex 中的零指针解引用。该漏洞利用Windows内核驱动模块win32k.sys可以执行本地提权,提权成功后可以突破普通用户权限的限制,用作安全沙箱逃逸,完全控制用户计算机系统。
以上是 关于 CVE-2019-0808 内核提权漏洞的成因分析 的全部内容, 来源链接: utcz.com/p/199268.html