首页
社区
课程
招聘
[原创]HEVD池溢出系列
发表于: 2021-5-20 11:06 9860

[原创]HEVD池溢出系列

2021-5-20 11:06
9860

由于新接触到了一个知识点,花了些时间去学习windows7内核池的一些知识。

这个漏洞的复现过程实在是太过于精美,并且在这过程间补充到了不少的知识,打算就池溢出做一期笔记。

内核池实际上是windows中类似于堆的一种动态内存结构。两者的利用在我看来是十分相似的。

将池溢出之前,我们不妨先回顾以下堆溢出

有CTF经验的朋友们应该不陌生堆溢出

那么如何完成一次堆溢出利用呢?

可以做出如下的假设:

堆块是系统分配给程序的空间,堆块在系统中是连续的一段内存,那么如果我们可以为某个带函数指针的对象申请一段内存空间,并且通过堆溢出修改我们的函数指针指向shellcode,那么我们即可完成堆溢出利用。

hevd池溢出

但是理想和现实总是存在差距的,好在可以将理想照进现实

那么不妨从这个思路开始

按照我的思路,分析漏洞时需要有三个部分的思考

但是由于HEVD本身就是一个漏洞复现的靶场,由于存在源码,所以我们可以省去最后一步做分析。

但我认为,复现或者挖掘漏洞的过程中,从哪里来也是很重要且具有挑战性的工作

使用IDA定位到漏洞位置

image-20210511153023958

那么我们先简单的编制一个poc,证明漏洞的存在

在之前的分析中,我们已经知道了是由于HEVD!memcpy没有对size进行判断从而导致了漏洞的发生,那么我们首先通过windbg下断点到HEVD!memcpy

运行我们的poc

image-20210512130333268

查看池状态,当然,之前我们下了断点,此时记得执行p命令

查看当前池块内容

image-20210512130549097

试着多发送8个字节的内容

image-20210512131326451

我们发现后续的池块由于结构被破坏,导致了无法被识别

image-20210512131425613

此时系统也会发生蓝屏

image-20210512131609406

此时我们已经彻底明白了,漏洞“是谁”

但是,我们简单布置的poc,多溢出的字节会由于破坏的后续池块的结构而导致系统的BSOD

也就是,我们的“到哪去”并不顺利

那么,我们应该更具体地构想,这段内存应该到哪里去

根据之前所讲的,由于C++面向过程的特性,我们可以向申请的堆块(池)中为某些特定对象申请空间,进而通过溢出控制其函数指针从而执行shellcode

当然,对象的大小也必须是合适的,由于我们的池块大小为0x1F8+8=0x200

因此选择CreateEventA函数,CreateEventA申请出Event对象的大小为0x40,0x40 * 8 == 0x200

先申请大量的event对象,再释放掉部分的event,这将会在内存中造成一些空洞,从而得以在这段空间中申请到kernel buffer,此时再申请kernel buffer将会保证下一个位置是一个Event对象

利用思路

申请大量的event对象后

image-20210512162804191

那我们随便取出一个event对象查看内部结构,首先我们查看windows中object的结构

image-20210514150809834

index的值为0xC,所在obTypeIndexTable表中的偏移为0xC

image-20210512163719395

所谓obTypeIndexTable表是指,xp直接在OBJECT_HEADER里保存了POBJECT_TYPE指针,而Win7里把所有的对象类型放在了一个表里,这个表叫做obTypeIndexTable

查看该表内容,并定位到0xC的位置

image-20210512164344595

可见Event对象保存在此处

查看该对象结构

image-20210520110533734

这里我们选用CloseProcedure函数作为修改的函数,理由是,在之后的源码中,我们发现会有

image-20210514143221988

函数来释放这段空间

可是接下来的问题,怎么能够去修改到CloseProcedure函数的呢?我们并不能通过池溢出直接修改到这个函数的指针

但是我们能修改到index的索引

ObTypeIndexTable第0个索引指向0地址(0x00000000)

利用此思路,我们可以构建如下的利用思路

最终利用思路

exp写的不是很优雅,建议从参考链接中获取两位师傅的博客

image-20210514153916435

​ 拖了很久才完成这一部分的利用,emmmm,总体收获还是蛮大的,离不开50u1w4y师傅的帮助,exp也是参考了他的exp,故而就不张贴出来了。

当然复现的过程中也从这些师傅的博客中获取了很多知识,十分感谢他们

https://50u1w4y.github.io/site/HEVD/nonPagedpooloverflow/#0x00

https://bbs.pediy.com/thread-252665.htm

 
 
 
 
 
 
 
 
 
 
 
 
 
#include<stdio.h>
#include<windows.h>
 
int main() {
    ULONG bReturn = 0;
    HANDLE hevDevice;
    ULONG BytesReturned;
    hevDevice = (HANDLE)CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", 0xC0000000, 0, NULL, 0x3, 0, NULL);
    char buf[0x1f8] = { 0 };
    if (!hevDevice) {
        printf(" failed to get handle");
    }
    RtlFillMemory(buf, 0x1f8, 'a');
    DeviceIoControl(hevDevice, 0x22200f, buf, 0x1f8, NULL, 0, &bReturn, NULL);
 
    return 0;
}
#include<stdio.h>
#include<windows.h>
 
int main() {
    ULONG bReturn = 0;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

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