首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
二进制漏洞
发新帖
0
1
[原创] 学习笔记:CVE-2014-1767漏洞利用思路与我的理解
发表于: 2026-4-14 21:18
8715
[原创] 学习笔记:CVE-2014-1767漏洞利用思路与我的理解
AO031
1
2026-4-14 21:18
8715
# 前言 CVE-2014-1767:Windows AFD.sys 双重释放漏洞,本地提权 写这篇博客之前我一直在想:因为我自己也是看别人的复现文章入手的,如果单纯再复述一遍漏洞,绝对是没有**Hacksign**大神的<a href="elink@348K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2V1k6h3u0#2k6%4N6S2M7W2)9J5k6h3y4G2L8g2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6z5e0p5g2Q4x3X3c8m8L8X3q4D9P5i4A6W2i4K6u0V1b7#2k6q4i4K6u0V1x3U0l9I4y4q4)9J5k6o6p5%4y4U0M7`.">CVE-2014-1767 分析报告</a>这篇文章好的。虽然我从零手写了 PoC 和 Exp,但还是感觉缺少一个独特的点。 于是,这篇文章我会着重分享自己对这个漏洞的思考,并尝试提炼出可举一反三的漏洞利用方法。 让我们开始吧。 # 漏洞成因(PoC分析) 漏洞调用链如下: ``` DeviceIoControl(0x1207F) -> AfdTransmitFile -> MmProbeAndLockPages(error) -> AfdReturnTpinfo -> IoFreeMdl(First Time) ------------------------------------------------------------------- DeviceIoControl(0x120C3) -> AfdTransmitPackets -> AfdTliGetTpInfo -> ExAllocatePoolwithQutaTag(error) -> AfdReturnTpinfo -> IoFreeMdl(Second Time) ``` `AfdReturnTpinfo`函数主要错误:释放`Mdl`后,没有将指针清零。  网上的绝大部分漏洞成因讲的都是`Double Free`漏洞,意思是同一块内核池内存被释放了两次,指针没有置零,触发蓝屏了 ## 我的思考 不知道读者看完简单的漏洞介绍后,会不会冒出这样一个想法:既然是双重释放,那我们直接调用两次 `DeviceIoControl(0x1207F)`,或者把两次释放的顺序调换一下,不就行了吗?这样“应该”也能触发吧? 出于这个疑问,我写 PoC 的时候特地尝试了好几次:调换顺序、使用相同的 `DeviceIoControl` 参数。很遗憾,上面这些想法都行不通。为什么呢?我们先来看 `AfdTransmitFile` 函数。  这里的`v34`是每一次使用afd维护的变量,`IoFreeMdl`也是通过这个变量找Mdl指针的。 可以看到,`AfdTransmitFile` 函数**先申请了**一个Mdl,初始化了全局变量,**然后再发生错误** 再来看`AfdTliGetTpInfo` 函数:  发生错误的地方主要是我们提前消耗了内存,导致`ExAllocatePoolWithQuotaTag`函数失败,整个过程**没有涉及**`Mdl` 也就是说,我们真正的(或者说更底层一点的)漏洞是,我们调用了两次`AfdReturnTpinfo`,加上没有把`Mdl`指针清零。就会重复释放两次同一块池内存,导致蓝屏。 所以,完整的漏洞触发流程应该是这样的 1. 调用`DeviceIoControl(0x1207F)`初始化本次调用的`Mdl` 2. `MmProbeAndLockPages`发生错误,导致释放了刚刚申请的`Mdl`漏洞,并留下了一个悬挂指针 3. 调用`DeviceIoControl(0x120C3)`使用`AfdTliGetTpInfo`函数。 4. `ExAllocatePoolwithQutaTag`发生错误,导致又一次释放了悬挂的`Mdl`地址。内核检测到后发生错误 这就解释了为什么只能按照这个顺序才能蓝屏。 - 调用两次`DeviceIoControl(0x1207F)`:因为`AfdTransmitFile`函数释放时会申请一个新的`Mdl`,所以不会蓝屏。 - 调用两次`DeviceIoControl(0x120C3)`:因为`AfdTransmitPackets`函数没有使用`Mdl`,`Mdl`指针是NULL,所以不会蓝屏。 - 先调用`DeviceIoControl(0x120C3)`,后调用`DeviceIoControl(0x1207F)`。第一个函数没有申请`Mdl`,第二个函数正常释放了,只释放了一次。 # 漏洞利用(Exp分析) 因为这个漏洞利用已经被大神们讲的很清楚了,我会简单讲讲利用链,在利用中分析我的思考 `我的思考` 首先,往广了想,我们应该怎么利用`Double Free`漏洞? ## Double Free漏洞的利用 ### Double Free的含义 有Double Free漏洞,说明`ExFreePool`的时候,没有一个合理的检查。 我们可以利用Double Free漏洞实现**一次超出常理的释放**。 ### 利用思路 一次超出常理的释放能干什么? 我们可以将一块池内存(这里可能是对象、可能是内核结构体,可能是驱动私有数据)在恰到好处的时机释放,制造悬挂指针,转化为UAF漏洞。 什么是恰到好处的时机,很简单,别人内核对象正在用呢,你给人家释放了,那你这不是闹嘛 ### 具体到这个漏洞 我们要控制内核,就需要在用户态申请一些对象,间接控制内核对象。 这个漏洞,我们选择了`WorkFactory`对象,我们通过`NtSetInformationWorkerFactory`和`NtQueryInformationWorkerFactory`就可以很方便地实现控制内核数据。 刚才上面提到,我们有一次**超出常理的释放**。所以,我们要把申请`WorkFactory`对象放在`Double Free`的第一次`Free`之后,把刚刚释放的内存申请出来,这样,我们就对这个池内存有一次在用户态违规释放的机会。 Exp代码片段 ``` // Alloc Pool To Make Dangling Pointer DeviceIoControl(s, 0x1207F, (LPVOID)inbuf1, 0x40, NULL, 0, NULL, NULL); //AfdTransmitFile hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 4); st = NtCreateWorkerFactory( &hWorkerFactory, GENERIC_ALL, NULL, hCompletionPort, (HANDLE)-1, NULL, NULL, 0, 0, 0 ); if (st < 0) { printf("[-] NtCreateWorkerFactory Failed\n"); return; } ``` `总结:从Double Free Mdl转化到拥有一次违规释放行为的WorkFactory对象.` 如果我们在用户态释放`WorkFactory`对象。那么,我们就制造了一个**悬挂指针**,转化为了`UAF`漏洞! `我的思考` ## UAF漏洞的利用 ### 利用思路 `Free`池内存后,这块内存可以被别人使用。 可以让两个对象**同时**使用这块内存。出现未定义行为,使我们可以彻底控制这块内存、这个对象 ### 具体到这个漏洞 我们申请出来的这个`WorkFactory`对象,最好是直接控制对象的所有数据。 正好,Windows有个函数就可以做到这件事,`NtQueryEaFile`函数,也会申请内存,会把申请出来的内存拷贝用户态传递过来的数据。 ``` // Occur WorkerFactory NtQueryEaFile(INVALID_HANDLE_VALUE, &IoStatus, NULL, 0, FALSE, FakeWorkerFactory, FakeObjSize, NULL, FALSE); ``` 这里`FakeWorkerFactory`是我们构造的`WorkerFactory`对象的池块数据。 注:Windows 7 内核对象放在非分页内存池块上的,第一部分是可选对象头,第二部分是对象头,第三部分是对象数据。可以通过`!handle UserHandleVal 3 EPROCESS`命令直接在Windbg用用户态句柄查看内核对象数据。 控制内核对象数据后,接下来的利用就很简单了。使用`NtSetInformationWorkerFactory`任意写,使用`NtQueryInformationWorkerFactory`任意读。 先读`HalDispatchTable+8`的值,再将`HalDispatchTable+8`写为shellcode地址,执行`NtQueryIntervalProfile`实则执行`Shellcode`,最后在`Shellcode`恢复现场。这个常见的利用方法我这里就不讲了~ # 总结 以前学 CTF 的 User Pwn 时,也碰到过不少 UAF。 但那时候没怎么总结,加上 CTF 里的 UAF 通常比较“直接”—— 你`free`掉一块内存,马上就能自己申请回来,然后直接往里写 payload,简单粗暴。 到了内核态就不一样了: - 你不能直接分配一个“恶意对象”往里写 shellcode - 你得通过**用户态 API 创建合法对象**(比如 Mdl、WorkerFactory、EaFile) - 利用这些对象自身的内部结构、函数指针,来间接控制执行流 **绕了一个弯子。** 参考资料: <a href="elink@78bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2V1k6h3u0#2k6%4N6S2M7W2)9J5k6h3y4G2L8g2)9J5c8X3q4J5N6r3W2U0L8r3g2Q4x3V1k6z5e0p5g2Q4x3X3c8m8L8X3q4D9P5i4A6W2i4K6u0V1b7#2k6q4i4K6u0V1x3U0l9I4y4q4)9J5k6o6p5%4y4U0M7`.">CVE-2014-1767 分析报告</a> [[原创]凑个热闹: CVE-2014-1767 分析报告](https://bbs.kanxue.com/thread-273486-1.htm) [[原创]【EXP 编写与分析系列四】Windows本地提权漏洞CVE-2014-1767分析及EXP编写指导 ](https://bbs.kanxue.com/thread-271473.htm) 我自己从零编写了一个PoC和Exp,上传到Github了<a href="elink@762K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6m8e0K6l9K6x3g2)9J5c8V1E0W2M7X3&6W2L8q4)9J5k6q4k6#2L8r3&6W2M7X3q4T1K9h3I4A6N6s2W2Q4x3X3c8d9k6i4m8J5L8$3c8#2j5%4c8A6L8$3^5`."><mark class="encrypted">6cfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6m8e0K6l9K6x3g2)9J5c8V1E0W2M7X3&6W2L8q4)9J5k6q4k6#2L8r3&6W2M7X3q4T1K9h3I4A6N6s2W2Q4x3X3c8d9k6i4m8J5L8$3c8#2j5%4c8A6L8$3^5`.</mark></a>,同时我也放在附件了~ 内核浩瀚,漏洞如星。愿我们都能在这片星空下,找到属于自己的那颗。
登录后可查看完整内容
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
#漏洞分析
#漏洞利用
#UAF
#Windows
上传的附件:
CVE-2014-1767-PoC-Exp.zip
(5.16kb,5次下载)
收藏
・
0
点赞
・
1
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
wx_晨梦
这个讨论对我很有帮助,谢谢!
2026-7-16 06:48
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
AO031
1
8
发帖
2
回帖
80
RANK
关注
私信
他的文章
[原创][分享] 精简Windows内核漏洞驱动下载器
3258
[求助] Win10/11 环境下“任意地址写负数”原语的提权利用思路探讨
3806
[原创] HEVD03-07
5015
[原创] 只有一次任意写,高版本win内核提权
6136
[原创] HEVD 前三题分析
9302
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
谁下载
×
huangyalei
zhongdong
npc0vo
mb_kujsrqqv
mb_lthgjpwj
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部