-
-
[原创] 学习笔记:CVE-2014-1767漏洞利用思路与我的理解
-
发表于: 2026-4-14 21:18 1991
-
CVE-2014-1767:Windows AFD.sys 双重释放漏洞,本地提权
写这篇博客之前我一直在想:因为我自己也是看别人的复现文章入手的,如果单纯再复述一遍漏洞,绝对是没有Hacksign大神的CVE-2014-1767 分析报告这篇文章好的。虽然我从零手写了 PoC 和 Exp,但还是感觉缺少一个独特的点。
于是,这篇文章我会着重分享自己对这个漏洞的思考,并尝试提炼出可举一反三的漏洞利用方法。
让我们开始吧。
漏洞调用链如下:
AfdReturnTpinfo函数主要错误:释放Mdl后,没有将指针清零。 
网上的绝大部分漏洞成因讲的都是Double Free漏洞,意思是同一块内核池内存被释放了两次,指针没有置零,触发蓝屏了
不知道读者看完简单的漏洞介绍后,会不会冒出这样一个想法:既然是双重释放,那我们直接调用两次 DeviceIoControl(0x1207F),或者把两次释放的顺序调换一下,不就行了吗?这样“应该”也能触发吧?
出于这个疑问,我写 PoC 的时候特地尝试了好几次:调换顺序、使用相同的 DeviceIoControl 参数。很遗憾,上面这些想法都行不通。为什么呢?我们先来看 AfdTransmitFile 函数。

这里的v34是每一次使用afd维护的变量,IoFreeMdl也是通过这个变量找Mdl指针的。
可以看到,AfdTransmitFile 函数先申请了一个Mdl,初始化了全局变量,然后再发生错误
再来看AfdTliGetTpInfo 函数:

发生错误的地方主要是我们提前消耗了内存,导致ExAllocatePoolWithQuotaTag函数失败,整个过程没有涉及Mdl
也就是说,我们真正的(或者说更底层一点的)漏洞是,我们调用了两次AfdReturnTpinfo,加上没有把Mdl指针清零。就会重复释放两次同一块池内存,导致蓝屏。
所以,完整的漏洞触发流程应该是这样的
这就解释了为什么只能按照这个顺序才能蓝屏。
因为这个漏洞利用已经被大神们讲的很清楚了,我会简单讲讲利用链,在利用中分析我的思考
我的思考
首先,往广了想,我们应该怎么利用Double Free漏洞?
有Double Free漏洞,说明ExFreePool的时候,没有一个合理的检查。我们可以利用Double Free漏洞实现一次超出常理的释放。
一次超出常理的释放能干什么?
我们可以将一块池内存(这里可能是对象、可能是内核结构体,可能是驱动私有数据)在恰到好处的时机释放,制造悬挂指针,转化为UAF漏洞。
什么是恰到好处的时机,很简单,别人内核对象正在用呢,你给人家释放了,那你这不是闹嘛
我们要控制内核,就需要在用户态申请一些对象,间接控制内核对象。
这个漏洞,我们选择了WorkFactory对象,我们通过NtSetInformationWorkerFactory和NtQueryInformationWorkerFactory就可以很方便地实现控制内核数据。
刚才上面提到,我们有一次超出常理的释放。所以,我们要把申请WorkFactory对象放在Double Free的第一次Free之后,把刚刚释放的内存申请出来,这样,我们就对这个池内存有一次在用户态违规释放的机会。
Exp代码片段
总结:从Double Free Mdl转化到拥有一次违规释放行为的WorkFactory对象.
如果我们在用户态释放WorkFactory对象。那么,我们就制造了一个悬挂指针,转化为了UAF漏洞!
我的思考