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

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2014-10-23T08:48:00Z
Canonical: https://wepostx.com/topics/601

> 乌云历史资料归档
>
> **原始作者：** 百度安全攻防实验室
> **原始编号：** superkieran-wooyundrops:371
> **原始发布时间：** 2014-10-23 16:48
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

## 0x00 漏洞背景

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

![原文图片](/media/2016/06/9dfeebe3e4f6f2739085d9f486a25546)

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

## 0x01 漏洞分析

漏洞主要发生在win32k!xxxTrackPopupMenuEx函数中，该函数用于弹出一个菜单，是同步的，也就是说只有等菜单弹出并选择之后才返回的，漏洞发生的根本原因在于可以让该函数执行过程中中断一次并执行ring3代码再返回继续执行;
以下是来自win32k!xxxTrackPopupMenuEx函数中部分代码：
1.经过一系列的初始化工作后，调用win32k!xxxMNLoop进入菜单循环等待选择：

![原文图片](/media/2016/06/6af2708fd247554089ee34ea4ab7a574)

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

![原文图片](/media/2016/06/a2ab1e46784544f3912ff071473b7ddc)

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

![原文图片](/media/2016/06/4556b894a8e3e6e4d20da4939ada2bf1)

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

![原文图片](/media/2016/06/49da921c677727bc7e4045f339bfc8ef)

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

![原文图片](/media/2016/06/c16b093a4fbb38cfb7cfb3265c5174b2)

Wh_wnd_proc:

![原文图片](/media/2016/06/4bf3c62e651581b549a0baabd40a3fcc)

Wnd_proc_long:

![原文图片](/media/2016/06/91a61a68502f8d2533238c93d3ec1d2c)

之所以在钩子函数还要多一步通过SetWindowLong设置窗口函数，在窗口函数里再调用EndMenu是因为得在窗口处理函数线程的上下文空间中调用EndMenu才有意义(每个窗口都有与之关联的pti--tagTHREADINFO).
6.可以看到，由于win32k!xxxSendMessage是异步的，调用完应用层代码（即菜单窗口已经销毁）返回到win32k!xxxMNFindWindowFromPoint, 此时由于失败，win32k!xxxMNFindWindowFromPoint返回0xFFFFFFFB, 回到win32k!xxxHandleMenuMessages
7.回到win32k!xxxHandleMenuMessages之后，问题来了，原因就在于其在检查win32k!xxxMNFindWindowFromPoint函数的返回值ptagWnd的合法性时的不严谨，便直接调用win32k!xxxSendMessage(ptagWnd …….);

![原文图片](/media/2016/06/06b4f0c693f263673bb57910a9c0f946)

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

![原文图片](/media/2016/06/4a5d0503352689135966bccd662fb153)

![原文图片](/media/2016/06/5f5ab7c8f9949df261d246a3e4755abf)

至此，上面就是整个漏洞的流程分析了。
9.最后给出一份直观的流程图：

![原文图片](/media/2016/06/4c1300b514218d6f1e063a4b56a30b78)

下面通过调试来重现整个情景；
0x02 漏洞重现与调试

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

```text
win32k!xxxFindWindowFromPoint : bpwin32k!xxxFindWindowFromPoint ".if poi(poi(poi(fs:0x124)+0x50)+0xb4) = 0x130 {} .else {gc}" ----0x130为进程ID
```
应用层单步到分配0页面构造Fake TagWnd时，查看0页面：

![原文图片](/media/2016/06/8628030a1af2b9dfe9c93e29d3394697)

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

![原文图片](/media/2016/06/b3ea52ae231e3cd75713725e2aa695cc)

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

![原文图片](/media/2016/06/a1277c4a3aca318db5994fc74698c508)

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

![原文图片](/media/2016/06/0df7986648ab8f9f05b7db345c4e2565)

3.F10 步过call xxxSendMessage时，应用层Wnd_proc_long断下：

![原文图片](/media/2016/06/31de9c74d0cd6b058ecd6a407767fb2b)

如果是0x1EB(MN_FINDWINDOWFROMPOINT)消息，则进入到如下：

![原文图片](/media/2016/06/b38d6406f820c285149b9b437d37ecc3)

4.回到内核层单步从xxxMNFindWindowFromPoint返回到xxxHandleMenuMessages，此时：

![原文图片](/media/2016/06/08556213ea598d84ada2c669f79cf76c)

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

![原文图片](/media/2016/06/16b5b06d98dc9dfe064a04fd96cf857b)

6.此时查看patgWnd -00xFFFFFFFB:

![原文图片](/media/2016/06/ff26e44656fcf7f15d438c6d5e7a9b49)

![原文图片](/media/2016/06/ff7cf67550a5c61796261a5ab9cb5e57)

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

![原文图片](/media/2016/06/18a6269bfad1885df54aca9a88119a3f)

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

## 0x03 参考链接

- [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/)

- [微软 《Microsoft 安全公告 MS14-058 - 严重》](https://technet.microsoft.com/zh-CN/library/security/ms14-058.aspx)

- [MJ0011 《从Dump到POC系列一:Win32k内核提权漏洞分析》](http://blogs.360.cn/blog/dump-to-poc-to-win32k-kernel-privilege-escalation-vulnerability/)

## Replies
