首页
社区
课程
招聘
[原创] 学习笔记:CVE-2014-1767漏洞利用思路与我的理解
发表于: 9小时前 122

[原创] 学习笔记:CVE-2014-1767漏洞利用思路与我的理解

9小时前
122

前言

CVE-2014-1767:Windows AFD.sys 双重释放漏洞,本地提权

写这篇博客之前我一直在想:因为我自己也是看别人的复现文章入手的,如果单纯再复述一遍漏洞,绝对是没有Hacksign大神的CVE-2014-1767 分析报告这篇文章好的。虽然我从零手写了 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函数没有使用MdlMdl指针是NULL,所以不会蓝屏。
  • 先调用DeviceIoControl(0x120C3),后调用DeviceIoControl(0x1207F)。第一个函数没有申请Mdl,第二个函数正常释放了,只释放了一次。

漏洞利用(Exp分析)

因为这个漏洞利用已经被大神们讲的很清楚了,我会简单讲讲利用链,在利用中分析我的思考

我的思考

首先,往广了想,我们应该怎么利用Double Free漏洞?

Double Free漏洞的利用

Double Free的含义

有Double Free漏洞,说明ExFreePool的时候,没有一个合理的检查。我们可以利用Double Free漏洞实现一次超出常理的释放

利用思路

一次超出常理的释放能干什么?

我们可以将一块池内存(这里可能是对象、可能是内核结构体,可能是驱动私有数据)在恰到好处的时机释放,制造悬挂指针,转化为UAF漏洞。

什么是恰到好处的时机,很简单,别人内核对象正在用呢,你给人家释放了,那你这不是闹嘛

具体到这个漏洞

我们要控制内核,就需要在用户态申请一些对象,间接控制内核对象。

这个漏洞,我们选择了WorkFactory对象,我们通过NtSetInformationWorkerFactoryNtQueryInformationWorkerFactory就可以很方便地实现控制内核数据。

刚才上面提到,我们有一次超出常理的释放。所以,我们要把申请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)
  • 利用这些对象自身的内部结构、函数指针,来间接控制执行流

绕了一个弯子。

参考资料:

CVE-2014-1767 分析报告

[原创]凑个热闹: CVE-2014-1767 分析报告

[原创]【EXP 编写与分析系列四】Windows本地提权漏洞CVE-2014-1767分析及EXP编写指导

我自己从零编写了一个PoC和Exp,上传到Github了d7dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6m8e0K6l9K6x3g2)9J5c8V1E0W2M7X3&6W2L8q4)9J5k6q4k6#2L8r3&6W2M7X3q4T1K9h3I4A6N6s2W2Q4x3X3c8d9k6i4m8J5L8$3c8#2j5%4c8A6L8$3^5`.,同时我也放在附件了~

内核浩瀚,漏洞如星。愿我们都能在这片星空下,找到属于自己的那颗。


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回