内核 FUZZ 思路

内核 API  函数:是提供给 Ring3 调用,在 Ring0 完成最终功能的函数。这些函数接收 Ring3 传入的参数,如果处理参数的过程存在问题的话,很有可能成为一个内核漏洞。这样的内核 API 函数有很多,例如 SSDT、Shadow SSDT 等。
Hook API的代码:很多安全软件为了防御病毒木马,对很多内核 API 进行了 Hook/Inline Hook。然而这些 Hook 内核 API 的代码也存在安全问题。如果对参数的处理不当或内部逻辑的错误,也很有可能出现内核漏洞。
网络协议处理的内核代码:有一些协议的处理是在 SYSTEM 进程中的,也就是在内核模块中处理的,可以通过网络协议 Fuzz,构造畸形协议数据包,来挖掘这方面的漏洞。
IoControl:从已公布的漏洞来看,IoControl 类型的漏洞是最多的,可以作为内核漏洞挖掘的重点方向。IoControl 作为 Ring0/Ring3 缓冲区交互的重要方式,很有可能会出现参数处理不当的问题,或者内部逻辑甚至设计缺陷引发的问题。

既然 IoControl 类型的内核漏洞如此多,那么如何挖掘这种类型的漏洞呢?首先再来回顾下 Ring3和Ring0 通讯的重要函数 DeviceIoControl():

 BOOL DeviceIoControl(
HANDLE hDevice, //设备句柄
DWORD dwIoControlCode, //Io 控制号
LPVOID lpInBuffer, //输入缓冲区指针
DWORD nInBufferSize, //输入缓冲区字节数
LPVOID lpOutBuffer, //输出缓冲区指针
DWORD nOutBufferSize, //输出缓冲区字节数
LPDWORD lpBytesReturned, //返回输出字节数
LPOVERLAPPED lpOverlapped //异步调用时指向的 OVERLAPPED 指针
);

正常情况下,DeviceIoControl() 的参数都是自己程序指定的,不会是畸形的参数,驱动中也主要考虑功能的实现,对于畸形参数和处理逻辑缺陷方面的安全问题不够重视。因此可以通过构造畸形参数来 Fuzz 驱动程序的处理是否存在漏洞。

这种 Fuzz 称为“IoControl Fuzz”。关于 IoControl Fuzz,有2种方法:

IoControl MITM(Man-In-The-Middle)Fuzz

这种方法类似于“中间人攻击”,是在内核 Hook NtDeviceIoControlFile(),当识别到 IoControl 的对象为要 Fuzz 的对象对,获取该函数的参数,并按照预先的 Fuzz 策略对参数或参数指向的缓冲区数据进行篡改,然后将篡改后的参数传递给原始的 NtDeviceIoControlFile():

IoControl Driver Fuzz

MITM 方式虽然巧妙,但多数情况下,难以覆盖某驱动程序所有的 IoControlCode,就算覆盖所有的 IoControlCode,这种 Fuzz 也只是“一次性”的,不够全面。

为了能够对驱动程序中的某个 IoCodeCode 做全面的 Fuzz,需要对 DeviceIoControl() 的每个参数都进行畸形化,每个参数值可以畸形出很多不同的值,然后将各个参数值进行组合。这种方法称为 IoControl Driver Fuzz。

内核 FUZZ 工具介绍

[一] 莫斯科一家公司的安全研究实验室 eSage Lab(http://www.esagelab.com)有一个开源工具 IOCTL Fuzzer,是 CLI 工具,功能如下

* 根据进程名称、驱动名称、设备名称、IoControlCode 进行 IRP 过滤
* IRP Fuzz
* 监视模式
* 通过控制台或文件输出日志

IOCTL Fuzzer 是在处理 IRP 的时候提取出满足配置文件中指定条件的 IRP,然后将该 IRP 的输入参数进行随机修改来进行 Fuzz,也即是 MITM Fuzz 方法。该工具使用 XML 文件来配置 Fuzz 对象和 Fuzz 策略。

其短板是,通过 XML 配置固然简单,但不够灵活,每次改变 Fuzz 对象和 Fuzz 策略都要重启 Fuzz 程序,使用不便。且 Fuzz 策略不够细致,可能会遗漏。

[二] 书中(工具及源码见随书光盘)给出一个 GUI 的 IoControl Fuzz 工具,能进行 MITM Fuzz 和 IoControl Driver Fuzz。其关键概念和概要设计如下:

Fuzz 对象:被 Fuzz 的对象或触发 Fuzz 的条件
Fuzz 策略:Fuzz 过程中对参数和数据畸形化的方案
Fuzz 项:Fuzz 对象和 Fuzz 策略合起来,称为一个 Fuzz 项。对于 Fuzz 程序来说,所有的 Fuzz 项就是其输入。Fuzz 程序支持多个 Fuzz 项同时工作,且能灵活地增删改,不发重启 Fuzz 引擎。

漏洞挖掘实战

书中展示了几个已经被修补了的漏洞的挖掘,利用的是上面提到的 IoControl Fuzzer 和 WinDbg 内核调试跟踪。

[一] 超级巡警 ASTDriver.sys 本地提权,影响 v4 Build0316 及以前的版本

超级巡警中有个恢复 Hook 的内核函数功能,在实现时没有对输入缓冲区进行检查,可导致向任意地址写 0。Fuzz 蓝屏后,可以在 WinDbg 中发现以下信息,进一步使用 !analyze -v 和反汇编追踪,可以发现漏洞代码位置,具体过程见书中内容。

[二] 东方微点 mp110013.sys 本地提权,影响东方微点防御软件 1.2.10581.0278 及以前的版本

mp110013.sys 对 0x8000012C 这个 IoControlCode 的处理存在问题,它会调用输入缓冲区的第一个 DWORD,如果用户在第一个 DWORD 填入错误的值,那么派遣例程会将这个值修改为 0。所以只要在 0 这个地址放入 shellcode,并且在输入缓冲区的第一个 DWORD 填入错误值,就能执行 Ring0 Shellcode。

[三] 瑞星 HookCont.sys 驱动本地拒绝服务漏洞,影响 23.0.0.5 及之前版本

HookCont.sys 驱动派遣例程中,对 IoControlCode 为 0x83003C07 的处理中,对 UserBuffer 检查使用 ProbeForWrite() 不当和 try 的位置使用不当,造成本地拒绝服务漏洞。

其对 UserBuffer 检查使用 ProbeForWrite() 的方法不正确,ProbeForWrite() 的第二个参数为 OutputBufferLength,驱动中没有任何检查就直接信任用户输入的 OutputBufferLength,只要 OutputBufferLength 为 0,这个 ProbeForWrite() 检查就毫无意义,也就是说 UserBuffer 可以是一个非法内存地址。

另外,在做 ProbeForRead() 和 ProbeForWrite() 检查时,使用了 try,但是在最后给 UserBuffer 写数据时没有使用 try。所以只要躲过前面的检查,后面由于内存访问错误,就会造成蓝屏崩溃。

OD: Windows Driver Fuzz的更多相关文章

  1. 驱动开发利器Microsoft Windows Driver Kit 7.1.0下载

    在Windows 2000 与Windows XP 系统采用是WINDDK来开发WINDOWS驱动程序,我手头也有WINDDK,可是从Windows Vista开始之后,一般采用Microsoft W ...

  2. 微软职位内部推荐-SDE2 (Windows driver)

    微软近期Open的职位: SDE2 (Windows driver) Job title: Software Development Engineer 2 Location: Shanghai, Ch ...

  3. 和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧。因为,很多PCI的例子都是对S5933,就连微软出版的《Programming the Microsoft Windows Driver Model》都提供了一个完整的S5933的例子。 在这篇有关DDK的开发论文里。

    和S5933比较起来,开发PLX9054比较不幸,可能是第一次开发PCI的缘故吧.因为,很多PCI的例子都是对S5933,就连微软出版的<Programming the Microsoft Wi ...

  4. Windows SDK DDK WDK (Windows Driver Kit) 区别

    首先,先从基础的东西说起,开发WINDOWS下的驱动程序,需要一个专门的开发包,如:开发JAVA程序,我们可能需要一个JDK,开发WINDOWS应用程序,我们需要WINDOWS的SDK,现在开发WIN ...

  5. Windows Driver Kit Version 7.1.0 ( 也就是 7600.16385.1 ) 下载地址

    Windows Driver Kit Version 7.1.0 ( 也就是 7600.16385.1 ) 下载地址 http://download.microsoft.com/download/4/ ...

  6. windows driver 简单的驱动和通信

    sysmain.c #pragma once #pragma warning(disable: 4100) #include <ntifs.h> #include <ntddk.h& ...

  7. Windows Driver Frameworks

    MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff557565(v=vs.85).aspx

  8. OD: Windows Kernel Debug

    内核调试入门 内核程序运行在内核态,因此不能像对用户态应用程序那样来调试.关于内核调试方面的知识请参考<软件调试>这本书.目前内核调试主要有以下三种方法. 一是使用硬件调试器,它通过特定的 ...

  9. OD: Windows Security Techniques & GS Bypassing via C++ Virtual Function

    Windows 安全机制 漏洞的万源之本在于冯诺依曼设计的计算机模型没有将代码和数据进行区分——病毒.加壳脱壳.shellcode.跨站脚本攻击.SQL注入等都是因为计算机把数据和代码混淆这一天然缺陷 ...

随机推荐

  1. Laravel框架——自己写的类找不到

    composer.json my model files are stored in directory of app\models, therefor "autoload": { ...

  2. cut 命令使用

    cut -d -f cut -c cut -d分隔符 -f分割后取的第几个字符串 cut -c从哪个字符开始取

  3. Oracle中数字格式的文本化处理

    Select TO_CHAR(123.0233,'FM999,999,90.09') FROM DUAL 1.小数点后面的0指示至少保留1位小数,9表示最多保留两位小数 2.小数点前面的0指示至少保留 ...

  4. [转]Windows Azure上安装SharePoint 2013

    基于Windows Azure 安装SharePoint 2013 前段时间写的基于Windows Azure安装SharePoint系列,由于Azure的体验账号过期了,所以不得不暂停.今天有幸参加 ...

  5. Count The Carries

    hdu:http://acm.hdu.edu.cn/showproblem.php?pid=4588 题意:给你 a,b两个数,然后让a到b之间的数做2进制的加法,问你与多少次进位.例如:1,3,1+ ...

  6. 关于用POI和EXCEL交互的问题

    废话不多说,直接通过例子来说明POI的使用: 1.一个创建excel并写入数据的小例子,参照网上的一个例子: public class CreateXL { /** * @param args */ ...

  7. vs2012 aps.net4.0/4.5尚未在web服务器上注册

    安装了vs2015后,vs2012 启动后报错: aps.net4.0/4.5尚未在web服务器上注册 解决办法: 下载微软补丁: http://blogs.msdn.com/b/webdev/arc ...

  8. bzoj2561

    对于新加入的边,必须要既可能在最小生成树上也可能在最大生成树上我们先对于最小生成树考虑根据kruskal的理论,不难发现,u--v 长度为L的边可能出现在最小生成树上就是说删边剩下的比L小的边一定不能 ...

  9. ZOJ-2008-Invitation Cards(dijkstra)

    题意: 在有向加权图中G(V,E),邮局要从起点S向其他n个节点发送邮件,于是派出n个邮递员,分别到达其他n个地点发送,然后回到起点S,求出所有邮递员所经过的总路程的最小值. 分析: 正向一次dijk ...

  10. 【转】Javabyte[]数组和十六进制String之间的转换Util------包含案例和代码

    原文网址:http://blog.csdn.net/caijunjun1006/article/details/11740223 Java中byte用二进制表示占用8位,而我们知道16进制的每个字符需 ...