内核 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. vim操作命令-笔记

    显示行号:在vim命令行模式下输入 :set nu 或 :set number 取消显示行号:在vim命令行模式下输入 :set nonu 或 :set nonumber 查看文件编码格式: :set ...

  2. App适配iPhone 6/ Plus和iOS 8:10条小秘诀

    App适配iPhone 6/ Plus和iOS 8:10条小秘诀   iPhone 6iOS 8适配   (原文:raywenderlich 作者:Jack Wu 译者:@TurtleFromMars ...

  3. Tornado的一个开源社区

    https://link.zhihu.com/?target=http%3A//www.tornadoweb.org/en/stable/ 基于Tornado的一个开源社区 GitHub - shiy ...

  4. GNU project C

    gcc - GNU project C and C++ compiler   gcc [option] file...            preprocessing         compila ...

  5. 【转】近百个Android优秀开源项目

    近百个Android优秀开源项目   Android开发又将带来新一轮热潮,很多开发者都投入到这个浪潮中去了,创造了许许多多相当优秀的应用.其中也有许许多多的开发者提供了应用开源项目,贡献出他们的智慧 ...

  6. 【转】常见 jar包详解

    转载自:http://www.cnblogs.com/xusir/archive/2013/05/19/3086878.html   jar包 用途 axis.jar SOAP引擎包 commons- ...

  7. javascript下用ActiveXObject控件替换word书签,将内容导出到word后打印第1/2页

    由于时间比较紧,没多的时候去学习研究上述工具包,现在用javascript操作ActiveXObject控件,用替换word模板中的书签方式解决. 最近有需求将数据导出到word里,然后编辑打印. 想 ...

  8. 常见的HTTPS攻击方法

    0x00 背景 研究常见的https攻击方法 Beast crime breach,并针对https的特性提出一些安全部署https的建议. 针对于HTTPS的攻击,多存在于中间人攻击的环境中,主要是 ...

  9. python PIL except: IOError: decoder jpeg not available

    今天在Python运行环境的服务器弄一个有关图像处理的程序时报这样的错: 1 NameError: global name 'Image' is not defined import Image 了下 ...

  10. 怎样在delphi中实现控件和窗体的拖拽

    下面这2种方法都能实现对控件和窗体的拖拽 方法1 procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift ...