0202-Windows内核提权漏洞CVE-2014-4113分析报告

# Windows内核提权漏洞CVE-2014-4113分析报告

0x00 漏洞背景
———

* * *

近日CrowdStrike团队发现Win64bit2008 R2服务器系统上存在可疑攻击行为,并捕获到相关样本。百度安全攻防实验室根据外界放出的poc进行了研究,漏洞成因和利用细节如下。 此类提权漏洞曾经出现在2011年的8个CVE中(CVE-2011-1878~CVE-2011-1885),由挪威安全公司Norman的内核漏洞达人TarjeiMandt(@kernelpool)报告的(微软公告编号MS11-054),其相关的细节未被公开。 2013年,MJ0011曾经因分析蓝屏崩溃dump文件,重现了此类漏洞并编写了poc和分析文章。

此次漏洞poc运行后的截图如下:

![](http://drops.javaweb.org/uploads/images/8dfc020043a6d72537f5e691ffc7d558176126c5.jpg)

以普通用户权限运行poc成功后,一个system权限的cmd进程被创建出来,说明提权成功,已从普通用户权限提升到了系统system最高权限。

0x01 漏洞分析
———

* * *

漏洞主要发生在win32k!xxxTrackPopupMenuEx函数中,该函数用于弹出一个菜单,是同步的,也就是说只有等菜单弹出并选择之后才返回的,漏洞发生的根本原因在于可以让该函数执行过程中中断一次并执行ring3代码再返回继续执行;

以下是来自win32k!xxxTrackPopupMenuEx函数中部分代码:

1.经过一系列的初始化工作后,调用win32k!xxxMNLoop进入菜单循环等待选择:

![](http://drops.javaweb.org/uploads/images/75baef582f96c3348cd58720984ddd0332cf965d.jpg)

2.跟进win32k!xxxMNLoop ,win32k!xxxMNLoop在进入真正的while循环之前会调用win32k!xxxHandleMenuMessages :

![](http://drops.javaweb.org/uploads/images/0f16d3d954b8fa885518d0a62ee5938e7f11e401.jpg)

3.继续跟进win32k!xxxHandleMenuMessages ,其会事先调用win32k!xxxMNFindWindowFromPoint来得到菜单窗口对象指针ptagWND,之后再调用win32k!xxxSendMessage给菜单窗口发送消息:

![](http://drops.javaweb.org/uploads/images/9046f00835d2ed85de20cbe9a2f6278d2cfc1b44.jpg)

4.继续跟进win32k!MNFindWindowFromPoint,其会调用win32k!xxxSendMessage给句柄窗口发送消息来确定菜单窗口坐标,可以看到消息值为:0x1EB(MN_FINDWINDOWFROMPOINT)

![](http://drops.javaweb.org/uploads/images/c26f7a732e92da2a08916995d6c0972c74700584.jpg)

5.POC在应用层安装了一个WH_WNDPROC钩子,将这个消息(MN_FINDWINDOWFROMPOINT)给拦截下来,并在其窗口处理线程上下文中调用了EndMenu让菜单窗口销毁,下面是样本中的应用层代码:

![](http://drops.javaweb.org/uploads/images/c76ddd9370be0d10e6b9bd2d100c108139cd5c15.jpg)

Wh_wnd_proc:

![](http://drops.javaweb.org/uploads/images/f30b8c6ae9da353a5cf5af5e61c93743f05ddf33.jpg)

Wnd_proc_long:

![](http://drops.javaweb.org/uploads/images/b11689d97eb3fa04a12543bef526b2c5a67e8c4d.jpg)

之所以在钩子函数还要多一步通过SetWindowLong设置窗口函数,在窗口函数里再调用EndMenu是因为得在窗口处理函数线程的上下文空间中调用EndMenu才有意义(每个窗口都有与之关联的pti–tagTHREADINFO).

6.可以看到,由于win32k!xxxSendMessage是异步的,调用完应用层代码(即菜单窗口已经销毁)返回到win32k!xxxMNFindWindowFromPoint, 此时由于失败,win32k!xxxMNFindWindowFromPoint返回0xFFFFFFFB, 回到win32k!xxxHandleMenuMessages

7.回到win32k!xxxHandleMenuMessages之后,问题来了,原因就在于其在检查win32k!xxxMNFindWindowFromPoint函数的返回值ptagWnd的合法性时的不严谨,便直接调用win32k!xxxSendMessage(ptagWnd …….);

![](http://drops.javaweb.org/uploads/images/d174f2afe3ec0b5b1dc79e4268efa59419b4455e.jpg)

8.由于调用xxxSendMessage(ptagWnd ,….)的参数ptagWnd为0xFFFFFFFB, 在函数内会取tagWND.lpfnWndProc字段,并调用该函数,该字段的偏移为: 0x60 , 即地址0Xfffffffb+0x60=0x5B,所有在样本中事先申请了0页面内存,并向0x5B处写入了shellcode地址,从而实现了exploit.

![](http://drops.javaweb.org/uploads/images/955ea35f329491c62b0184ab8e25cdbe08bef126.jpg)

![](http://drops.javaweb.org/uploads/images/02f204654d73962c1b07eb3992d53cbed819ffb2.jpg)

至此,上面就是整个漏洞的流程分析了。

9.最后给出一份直观的流程图:

![](http://drops.javaweb.org/uploads/images/0643f79b520b0ed3a8c0e3a2420d0bbacf394604.jpg)

下面通过调试来重现整个情景;

0x02 漏洞重现与调试

* * *

1.应用层与内核层同时进行调试,内核层下条件断点

“`
win32k!xxxFindWindowFromPoint :
bpwin32k!xxxFindWindowFromPoint “.if poi(poi(poi(fs:0x124)+0x50)+0xb4) = 0x130 {} .else {gc}” —-0x130为进程ID

“`

应用层单步到分配0页面构造Fake TagWnd时,查看0页面:

![](http://drops.javaweb.org/uploads/images/bb490eafbe2ece0914d9defbd76fd941da20cde3.jpg)

2.应用层继续单步到call TrackPopMenu时.

![](http://drops.javaweb.org/uploads/images/322f4bac88462d1fca12e6ef5e1d232c45ae70ad.jpg)

1.应用层F8单步步过call TrackPopMenu时, 内核层win32k!xxxFindWindowFromPoint断下,可以看到其调用栈如下

![](http://drops.javaweb.org/uploads/images/75e33a1479d0dd2ba800fdfee050c609f452faed.jpg)

2.win32k!xxxFindWindowFromPoint单步到调用xxxSendMessage(MN_FINDWINDOWFROMPOINT)时,并在应用层的窗口函数Wnd_proc_long下断点:

![](http://drops.javaweb.org/uploads/images/f08254fa32fdfd6cd65a0e574fc9149d3e5cbb66.jpg)

3.F10 步过call xxxSendMessage时,应用层Wnd_proc_long断下:

![](http://drops.javaweb.org/uploads/images/a09afc7f627ca7c50f637066f65ebd5d590f6317.jpg)

如果是0x1EB(MN_FINDWINDOWFROMPOINT)消息,则进入到如下:

![](http://drops.javaweb.org/uploads/images/8dbfc350be69f178311e9e8380341892693ad01e.jpg)

4.回到内核层单步从xxxMNFindWindowFromPoint返回到xxxHandleMenuMessages,此时:

![](http://drops.javaweb.org/uploads/images/03470f5099fcd010a01259958a9d39d82ed5a357.jpg)

5.xxxHandleMessages继续执行,单步到调用xxxSendMessage()时:窗口对象ptagWnd为xxxMNFindWindowFromPoint()返回值:0xFFFFFFFB :

![](http://drops.javaweb.org/uploads/images/531216a49816a81ed625030f6315794c6bb0787d.jpg)

6.此时查看patgWnd -00xFFFFFFFB:

![](http://drops.javaweb.org/uploads/images/4d1759dc4cd12ec3b44bf38af730cbabe1eb4506.jpg)

![](http://drops.javaweb.org/uploads/images/b7dc0273eda484791c2d0b0693407babe8fe871c.jpg)

7.下断点“ba r4 0x5c“ ,”bp 0x00d21830” , g运行 ,来到断点处:

![](http://drops.javaweb.org/uploads/images/9eafd9815f103a13b69d405e63617f93b0d75c34.jpg)

至此可看到,ShellCode已执行成功~~~~~;

0x03 参考链接
———

* * *

1. [crowdstrike 《CrowdStrike Discovers Use of 64-bit Zero-Day Privilege Escalation Exploit (CVE-2014-4113) by Hurricane Panda》](http://blog.crowdstrike.com/crowdstrike-discovers-use-64-bit-zero-day-privilege-escalation-exploit-cve-2014-4113-hurricane-panda/)
2. [微软 《Microsoft 安全公告 MS14-058 – 严重》](https://technet.microsoft.com/zh-CN/library/security/ms14-058.aspx)
3. [MJ0011 《从Dump到POC系列一:Win32k内核提权漏洞分析》](http://blogs.360.cn/blog/dump-to-poc-to-win32k-kernel-privilege-escalation-vulnerability/)

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容