IE、Office 等软件有个共同点,即用文件作为程序的主要输入,但攻击者往往会挑战程序员的假定和假设。
文件格式 Fuzz 就是利用畸形文件测试软件的稳健性,其流程一般包括:
* 以一个正常文件作为模板,按规则产生一批畸形文件 * 将畸形文件逐一送往软件进行解析,并监视异常 * 记录错误信息,如寄存器、栈状态 * 进一步分析日志等异常信息,鉴定漏洞和利用性
Blind Fuzz
即盲测,在随机位置插入随机数据产生畸形文件。
现代软件往往使用非常复杂的私有数据结构,如 PPT、word、excel、mp3、rmvb、pdf、jpeg、zip、加壳 PE。数据结构越复杂,解析逻辑越复杂,就越容易出现漏洞。
复杂的数据结构通常具备以下特征:
* 有一批预定义的静态数据,如 magic、cmd id 等 * 数据结构的内容可以动态改变 * 数据结构之间嵌套 * 数据中存在多种数据关系(sizeof、point to、reference of、CRC) * 有意义的数据被编码或压缩,甚至用另一种文件格式存储,被挖掘出越来越多的漏洞
对于采用复杂数据结构的文件,Blind Fuzz 暴露出不足:测试用例缺少针对性,产生大量无效用例,难以发现复杂解析器的深层逻辑漏洞。
Smart Fuzz
针对 Blind Fuzz 的不足,Smart Fuzz 被越来越多地提出和应用。Smart Fuzz 有三个特征:面向逻辑、面向数据类型、基于样本。
面向逻辑,测试前明确要测试的目标是解析文件的程序逻辑,确定测试用例所试探的是哪一层解析逻辑,即明确“深度”以及畸形数据的“粒度”,这样在生成畸形数据时可以具有针对性的仅仅改动样本文件的特定位置,尽量不破坏其他数据的依赖关系。
面向数据类型,能够识别不同的类型,并且能够针对目标数据类型按照不同规则来生成畸形数据,可以生成算术类型 hex ascii unicode raw、指针型、字符串型、特殊字符型。这种方法产生的畸形数据通常都有效,能够大大减少无效用例。
基于样本:每次都从样本模板小幅度变异生成新的测试样本。但不能测试样本文件中没有包含的数据结构,所以需要有能包含所有数据结构的样本。
这三种 Fuzz 特性并不是相互独立的,可以同时使用。好的 Smart Fuzz 工具中,三种特性都会包含。
文件 Fuzz 工具 Peach 介绍
Peach 是用 Python 写的开源工具,支持基于生长(用随机或启发性的数据来填充给定的数据模型)和基于变异的两种文件生成方式。
Debug 系统需要安装 WinDbg,Debug 协议需要安装 Wireshark 或者 Winpcap。
Peach 有 EXE 和 Python 源码两种版本,可以跨平台。Peach 使用 XML 来定义数据结构,可以定义数据之间的依存关系如校验值等。
书中有个用 Peach 来 Fuzz PNG 格式文件的例子,可以参考。
010 脚本解析复杂文件
010 Editor 是一款非常强大的文本 / Hex 编辑器,包括文件解析、计算器、文件比较等功能。
010 Editor 真正强大之处在于文件解析功能,其官网提供了针对多种文件格式(avi bmp png exe 等)的解析脚本。脚本编写使用类似 C/C++ 的语法,灵活度很高。
书中有一个利用 010 Editor 触发 GdiPlus.dll 在处理 IHDR 时的整数溢出漏洞,造成拒绝服务攻击(CPU 100%)。(CVE-2006-7210?)
PPT 文件解析
Office 系列软件使用的文件格式可以分为两个系列:
* Office 97~Office 2003:使用基于二进制的文件格式,文件名后缀为doc、ppt、xls等 * Office2003及更高版本:使用基于XML的文件格式,文件名后缀为docx、pptx、xlsx等
这里主要讨论二进制 PPT 文件格式。
测试深度 |
解析逻辑 |
数据粒度 |
Fuzz 方法 |
Level1 |
OLE2 解析器 |
离散分布的 512 字节数据段 |
修改 OLE 文件头、FAT 区块、目录区块等位置的数据结构 |
Level2 |
PPT 记录解析器 |
流和信息库 |
修改流中的数据,破坏记录头和数据的关系 |
Level3 |
PPT 对象创建器 |
原子和容器 |
用负载替换原子数据 |
Level4 |
PPT 对象内部逻辑 |
原子记录内部的 integer、bool、string 等数据 |
用相关的负载集修改字节数据 |
PPT 的有效数据被组织在基于 OLE2 的二进制文件中。OLE2 文件把数据组织成流(Stream)进行存储。数据流在逻辑上连续存储,在硬盘上则离散存储。如果直接用十六进制编辑器打开一个 OLE2 文件,将会看到许多大小为 512 字节的离散的数据块,并且在文件的开头有一个存储了这些数据块索引的 FAT 表。OLE2 的 FAT 表跟 FAT32 文件系统的索引很相似。(书的附录有 OLE2 的 010 Editor 脚本)
PPT 的有效数据存储在 OLE2 的 stream 中,通常一个 PPT 文件包括以下几种 stream:
数据流 |
说明 |
Current User |
最近打开演示文档的用户信息 |
PowerPoint Document |
文档中的数据信息 |
Pictures(Optional) |
文档中的图像信息 |
Summary Information |
文档中的一些统计信息 |
Document Summary Information(Optional) |
文档中的一些统计信息 |
PowerPoint Document 数据流中包含了我们感兴趣的大部分信息,如 font、color、text、position 等数据结构。下面着重讨论 PowerPoint Document 数据流的解析。
PowerPoint Document 数据流中,数据以若干个"记录(Record)"的形式存储。每个记录都包含一个 8 字节的 header,根据 header 的不同,记录又可分为容器(Container)和原子(Atom)两种类型。其中,容器可以包含原子和其他容器,而原子则包含了 PowerPoint 对象的真正数据。
微软已经公布了 PPT 文件中所有记录(record)的格式说明,这就不难从 OLE2.bt 解析出的数据流中进一步解析出所有 PPT 的原子和容器结构。如果动手编程,不难发现这实际上是一个树的遍历问题。在随书资料中给出了一个简单的 010 解析脚本 ppt_parse.bt。执行ppt_parse.bt脚本,即可得到PPT的解析结果。
FTP Fuzzing
书中介绍了一款 infigo ftpstress fuzzer,配置选项很多,fuzz FTP 时可作首选。
SMTP、POP3、IMAP4、路径回溯、XSS
书中针对以上几个协议/主题都有 Fuzz 例子,总结经验如下:
* Python 测试确实方便,对于很多协议都有封闭包,非重点的地方直接使用包,需要自定义的地方(如匿名登录 POP3)稍修改即可
* 测试时要细致,不留死角。例如路径回溯,传入服务器等程序的参数中、客户端的内存中(直接调试修改)都可以作文章