首页
社区
课程
招聘
[翻译]# Windows 内核 利用教程 4 池风水 -> 池溢出
发表于: 2018-1-3 11:32 7794

[翻译]# Windows 内核 利用教程 4 池风水 -> 池溢出

2018-1-3 11:32
7794

这一系列文章源于作者学习HackSystem开设课程--windows 内核利用训练课程的学习笔记,到目前为止作者已发布4篇:

1.环境搭建
2.栈溢出
3.任意内存覆盖
4.池溢出

我们已经在上一章探讨了任意内存覆盖漏洞,在本章我们讨论另一个漏洞,池溢出。简单来说,就是池缓冲区的越界。这部分可能会比较难,我们将深入探讨如何通过修改池,从而控制应用程序流,确保每次都可靠地指向我们的shellcode地址。所以花点时间好好理解我之前文章中的概念,之后再来尝试利用本文中的漏洞。

再次感谢hacksysteam的驱动程序。

在我们深入探讨池溢出这个主题前, 我们需要先了解下池的基本概念, 如何根据需要操纵它。 Tarjei Mandt写了一篇很好的关于这个主题的文章,强烈建议在继续阅读本文前先浏览Tarjei Mandt 的文章,因为你需要对池概念有一个扎实的理解。

内核池类似于Windows 中的堆, 因为它的作用也是用来动态分配内存。 就像堆喷修改正常应用程序的堆一样,我们需要在内核领域找到一种办法来修改内存池,以便在内存区域精确地调用我们的shellcode。 理解内存分配器的概念以及如何影响池分配和释放机制相当重要。

至于我们的 HEVD 驱动, 有漏洞的用户缓冲区被分配在非分页池,所以我们需要找到一种方法来修改非分页池。 Windows 提供了一种Event对象, 该对象存储在非分页池中,可以使用CreateEvent API 来创建:

在这里我们需要用这个API创建两个足够大的Event对象数组,然后通过使用CloseHandle API 释放某些Event 对象,从而在分配的池块中造成空隙,经合并形成更大的空闲块:

在这些空闲块中,我们需要将有漏洞的用户缓冲区插进去,以便每次准确地覆盖正确的内存位置。因为我们会破坏Event对象的相邻头部,以便跳转到包含shellcode的地址。下面用一个粗略的图表来展示下我们正要做的工作:

图片描述

在这之后,我们会把指针指向shellcode,这样就可以通过操纵损坏的池头部来调用它。 我们伪造一个OBJECT_TYPE头,覆盖指向OBJECT_TYPE_INITIALIZER中的一个过程的指针。

为了便于分析漏洞, 先看下PoolOverflow.c 文件:

似乎看起来有点复杂,但是这里的漏洞很明显,在最后一行开发人员直接传递值而没有验证大小,这导致了一个基于池的溢出漏洞。

我们将按照上一篇文章中的描述找到这个漏洞的IOCTL号:

计算得出 IOCTL 为 0x22200f。

用IDA分析一下驱动中的 TriggerPoolOverflow 函数:

图片描述

我们用标签“Hack”指代有漏洞的缓冲区标记,长度为0x1f8(504)。由于现在有足够的关于漏洞的信息,让我们直接跳到有趣的部分,利用它。

让我们从基本的框架开始, IOCTL 为 0x22200f。

图片描述

我们正在触发池溢出IOCTL,可以看到标签“Hack”,大小为0x1f8(504),尝试下赋给UserBuffer 0x1f8个字节的大小。

图片描述

我们现在不应该破坏相邻的内存块,因为现在UserBuffer的值为边界值,来分析一下池:

图片描述

可以看到用户缓冲区被完美地分配了,结束地址为下一个池块起始地址:

图片描述

溢出会是灾难性的,并且将直接导致系统蓝屏崩溃,破坏了相邻的池块头部。

图片描述

在这里很有趣的一件事是,我们如何能够通过溢出控制相邻的头部。我们利用的这个漏洞可以以修改池的方式来使得池不再随机化。那么我此前讨论的 CreateEvent API 可以胜任这个工作,它的大小为0x40个字节,正好可以匹配池的大小0x200个字节。

我们会喷射大量Event对象,把它们的句柄存储在数组中,看下如何影响我们的池:

图片描述

我们的Event对象被喷射到非分页池中,现在我们需要在这些内存块创造一些空隙,然后把我们有漏洞的Hack缓冲区重新分配到这些空隙中。在重新分配有漏洞的缓冲区后,我们需要破坏相邻的池头部,以指向我们的shellcode地址。Event对象的大小为0x40个字节(0x38+0x8),包括池头部。

来分析一下头部:

图片描述

由于Event对象被喷射到非分页池中,所以我们可以将这些值加到缓冲区末尾,来实现利用。但是,简单这样做是行不通的,我们来研究下头部的数据结构,再稍作修改:

图片描述

我们感兴趣的部分是TypeIndex ,它实际上是指针数组中的偏移量大小,它定义了Windows所支持的每个对象的OBJECT_TYPE,来分析一下:

图片描述

这看起来可能有点复杂,但我已经标记出了重要的部分:

我们的目标是把TypeIndex的偏移量从0xc改为0x0,因为第一个指针是空指针,在Windows 7 中有一个漏洞,可以调用 NtAllocateVirtualMemory来映射到Null页面:

然后调用WriteProcessMemory 覆盖0x60处的指针,指向shellcode地址:

把所有的内容整合一下,python脚本大体如下:

图片描述

有漏洞的缓冲区现在位于我们创建的Event对象之间的空隙中。

图片描述

TypeIndex由 0xc 修改为 0x0

图片描述

shellcode地址布置完成!

现在,只需要调用 Closeprocedure,在 虚拟内存中 加载shellcode, shellcode应该完美运行。最终版本的exploit如下:

图片描述

得到系统管理员权限:

原文地址:https://rootkits.xyz/blog/2017/11/kernel-pool-overflow/

本文由看雪翻译小组 fyb波编译

 
 

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

最后于 2019-2-1 15:32 被admin编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (9)
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
感谢!!正需要学习
2018-1-3 12:58
0
雪    币: 1319
活跃值: (1960)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
mark
2018-1-3 15:16
0
雪    币: 1101
活跃值: (158)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
感谢博主,二、三是不是还是没有?
2018-1-3 15:52
0
雪    币: 3302
活跃值: (1144)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
5
QuietBar 感谢博主,二、三是不是还是没有?
我打算过两天  翻一下第三篇
2018-1-3 23:10
0
雪    币: 3302
活跃值: (1144)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
6
地狱怪客 感谢!!正需要学习[em_3]
 

89f9f900 这个地址 是怎么得的的吗?

2018-1-4 19:03
0
雪    币: 3302
活跃值: (1144)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
7
你知道
2018-1-4 19:04
0
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不错!
2018-1-4 22:16
0
雪    币: 341
活跃值: (143)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
9
fyb波 你知道
利用方面我还没有时间学习,先标记过段时间才能看...这个地址感觉和上面的地址对不上
2018-1-5 12:37
0
雪    币: 1101
活跃值: (158)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
10
fyb波 我打算过两天 翻一下第三篇
我简单翻译了一下
2018-1-18 17:05
0
游客
登录 | 注册 方可回帖
返回
//