欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

Windows内核池漏洞利用技术

来源:本站整理 作者:佚名 时间:2017-07-06 TAG: 我要投稿

本文将介绍如何利用HackSys Team Extremely Vulnerable Driver中的释放后重用和池溢出问题。为此我们需要对Windows内核内存管理有所了解。因此,本文将涵盖以下内容:
1. Windows内核内存分配概述
2. Windows内核池风水演练
3. 利用HackSys Team Extremely Vulnerable Driver的释放后重用
4. 通过两种不同的方法利用HackSys Team Extremely Vulnerable Driver的池溢出
本文专注于windows 7 sp1(32位)。
Windows内核池
了解内存管理的基础知识有所帮助,如果你不曾了解虚拟内存和分页,那么有必要快速阅读以下内容:
1. 内存程序剖析
2. 内核如何管理你的内存
Windows内核使用两种动态大小的“池”来分配系统内存,这些内核等同于用户模式下的堆。我只介绍理解利用方法原理所需的详情,更多信息请查看:
1.  Windows 7 内核池利用,作者:Tarjei Mandt
2. 《Windows Internals》第7版第1部分第5章或《Windows Internals》第6版第2部分第10章——内存管理
3.  Windows驱动程序的内存管理
Windows中有两种关键类型的池——非分页池和分页池。还有特殊池(我将在介绍释放后重用利用方法时介绍)和win32k使用的会话池(本文不作介绍)。
分页池对比非分页池
非分页池由保证总是存储在物理内存中的内存组成,而分页池中分配的内存可以被分页。这是必需的,因为某些内核结构需要在高于可满足缺页中断的IRQL可访问。有关IRQL的更多详细信息以及各级别支持的操作,请参阅“管理硬件优先级”。
这意味着非分页池用于存储进程、线程、信号量等关键控制结构。而分页池用于存储文件映射、对象句柄等。分页池实际上由几个单独的池组成,而在Windows 7中,只有一个非分页池。
为了分配池内存,驱动程序和内核通常使用ExAllocatePoolWithTag函数,其定义如下:

PoolType参数包含一个POOL_TYPE枚举中的值。这定义了正在请求什么类型的池内存,我们将主要看到其用0调用,这对应于非分页池。

第二个参数是所需的池内存的字节数,最后的PoolTag参数是一个32位值,其被完全视为用于标记内存用途的4个字符,这在调试时非常方便,并且也被大量内核内存instrumentation使用——跟踪使用某个标签进行了多少分配,当内存分配到某个标签时中断,等等。
为了释放分配的池内存,通常使用ExFreePoolWithTag函数。

这只需要一个指向有效池分配的指针,池元数据将给予所有其他所需的东西,在标准条件下,提供的池标签将不会被验证。但是,启用正确的调试设置后,标签将被验证,如果其不匹配,则会触发一个BSOD。现在我们来看看这些函数的工作原理。
分配内存
反编译器 ExAllocatePoolWithTag 乍看之下很吓人。

还好,Tarjei Mandt已经在其论文中将函数转化为伪代码,这可以作为一个很好的指导。我将使用他的伪代码和IDA中的一些检查等,并通过windbg来解释函数的工作原理。他的解释可能更好、更准确,本节中的所有代码片段都来自其论文。
首先,函数检查请求的字节数是否超过4080字节,如果是,则调用Big Pool 分配器。

此处,esi包含请求的字节数,如果高于0xff0,则转到nt!ExpAllocateBigPool。否则采取true分支,处理继续。


在这一点上,[esp+48h+var_20]持有末尾为1的PoolType。所以如果该值等于0,则其是一个非分页池,跳过上面的if语句并转到随即显示的else,同时,如果类型是用于分页池内存,则采取true分支。

在true分支上,其检查池类型是否用于会话池。

其随后立即检查请求的字节数是否高于32。

同时,在false分支上,其还检查分配是否高于32字节。

[1] [2] [3] [4] [5] [6] [7] [8] [9]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载