深入探究文件Fuzz工具之Peach实战

*本文原创作者:overXsky,本文属FreeBuf原创奖励计划,未经许可禁止转载

0×0 前言

本文旨在详细介绍文件Fuzz工具Peach的使用,涵盖了基于Python的2.3旧版本和基于C#的3.1新版本,讲求实践与语法并重,适合零基础和有一定其他Fuzz工具使用经验的人z作为学习参考。文中若有不当之处,还望不吝指正。

说明:本文中穿插对比了3版本较于2版本有较大改动的地方,并以“V3:”特意标注。

0×1 Peach介绍与安装

Peach是用python/C#写的开源Smart Fuzz工具,支持两种Fuzz方法:基于生长(Generation Based)、基于变异(Mutation Based)

1.基于生长:产生随机或启发性数据填充给定的数据模型

2.基于变异:在给定样本文件的基础上进行修改 

在32位win7上安装的具体步骤: 

1.Peach3安装指南 

2.下载安装.NET4运行环境 

3.下载安装Debugging Tools for Windows 

1.png

根据官网的提示,如果想要独立安装,那么在安装SDK的中途做出选择即可 

2.png

下载完后根据提示找到文件保存位置 

3.png 

4.png

4.在Peach Community上找到Peach 3的x86-release版本下载入口 

5.解压源码到任意文件夹 

6.运行以下命令,测试自带的HelloWorld能否正常运行。发现cmd开始不停滚动,成功! 

5.png

6.png 

0×2 定义Peach Pit

为了开始进行文件 Fuzz,首先必须创建一个该格式的 Peach Pit 文件。Peach Pit 文件使用XML语言定义数据结构,里面记录了文件格式的组织方式,我们需要如何进行 Fuzz,Fuzz 的目标等信息

Peach Pit,包含5个模块

1.GeneralConf(V3:General Configuration)

2.DataModel(V3:Data Modeling)

3.StateModel(V3:State Modeling)

4.Agents and Monitors(V3:不变)

5.Test and Run Configuration(V3:Test Configuration,去掉了Run) 

一个简单的XML框架:

V3:需要将以上包含…2008…的字段改为以下内容:

1.GeneralConf / General Configuration

定义基本配置信息,包括

1.Include——要包含的其他Peach Pit文件

2.Import——要导入的python库或自定义模块

3.PythonPath——要添加的python库的路径

4.所有的Peach Pit文件都要包含default.xml文件

在HelloWorld中:

V3:强制包含default.xml这一限制在版本3中已经去掉,改为Defaults属性包含,参考

2.DataModel

DataModel 元素是 Peach 根元素的子节点,常用属性主要是以下两个:

1.name——相当于起一个”变量名“

2.ref——引用标签,是否继承于某一个已定义的DataModel(这里继承的含义类似于面向对象中的继承,被引用的 DataModel 将为作为新的 DataModel 的基数据 ,可以重用或更新子元素)

DataModel定义了某一格式类型文件的数据模型,包括数据结构、数据关系等,常用的子元素有以下几种:

1.String——字符串型,包含了name,length等常用属性(V3:需要特别注意,在版本2中表示字符串不可变的isStatic属性在版本3中更名为token)

2.Number——数据型,可以是8、16、32或64字节的数据,并通过size属性来设定,同时也包含name属性作为名称

3.Blob——无具体数据类型,通常用来定义不明类型的数据,包含name、length、value等属性

4.Block——用于对数据进行分组,用来组合一个或者多个的其他元素 ,比如 Number 或者 String,有点类似于DataModel,只不过两者的位置不同。

小技巧:可以把一个复杂的数据结构拆成几部分,在一个 Peach Pit 文件里定义多个不同层级的 DataModel,并通过 ref 标签层层递进,从而增强可读性和可重用性。

举例如下:

在HelloWorld.xml中:

3.StateModel

• 描述如何向目标程序发送或接受数据

• 每个StateModel至少由一个State组成,第一个State由InitialState指定,并且State只有一个属性name

• 每个State至少由一个Action组成,定义StateModel中的各种动作,动作类型由type指定

• type包括start,stop,open,close,input,output,call等

举例如下:

在Helloworld中,只需要接收数据模型HelloWorldTemplate中的数据

4. Agents and Monitors

定义代理和监视器,可以调用Windbg等调试器来监控程序运行的错误信息等,目前已有的Agent包括Local Agent、TCP Remoting Agent、ZeroMQ和REST Json Agent

Agent下定义Monitor来监视

举例如下:

5.Test and Run configuration / Test Configuration

版本2中包括Test和Run两个元素,版本3中只要Test一个元素即可

Test用来定义一个测试的配置,包括一个StateModel和一个Publisher(必需),以及including和excluding、Agent(可选)等信息 

例子:

Publisher用来定义Peach的IO连接,可以构造网络数据流和文件流等

HelloWorld中只需要把生成的畸形数据显示到命令行,所以Publisher用的是标准输出stdout.Stdout(版本2)/Console(版本3)

(以下一段Run是版本2)

Run元素定义运行哪些测试,包含一个到多个Test元素,(可选)用Logger配置日志来捕获运行结果 

举例

而版本3中,Logger作为Test的子元素,写在其中即可,如下所示:

在HelloWorld中:

0×3 HelloWorld.xml初体验

根据之前的分析介绍,不难写出一个简单的HelloWorld代码,各位读者不妨先自己动手写写看。 
给出示例——在2版本下能够运行的代码如下:

而对于3版本就需要改动一部分:

1. 在实际调试中,修改了几处,首先是把xmlns改成了http://peachfuzzer.com/2012/Peach,否则会出现更新提示

2. 删除了include,因为报错提示说找不到default.xml文件

3. Test name改为了Default,因为报错说找不到default

4. 删除了run元素,报错提示说在当前命名空间下子元素非法,应当出现的元素为:’Include, Import, Require, PythonPath, RubyPath, Python, Ruby, Defaults, Data, DataModel, Godel, StateModel,Agent, Test’ 

给出示例——在3版本下能够运行的代码如下:

官方给出的HelloWorld.xml如下,大家可以参考:

0×4 数据依赖关系

参考官方文档

Peach 允许数据间的关系建模。关系像“X 是 Y 的大小”,“X 是 Y 出现的次数”,或者“X是 Y 的偏移(以字节为单位)”。

Relation元素可以用来表示数据长度、数据个数以及数据偏移等信息,格式如下:

size-of Relation 

这个例子里,Number 会指定 Value 字符串的大小,以字节为单位。注意,这对多字节字符(wchar)同样适用。

count-of Relation 

这个例子里,Number 会指定 Strings 数组的个数。

参考官方文档

Fixup元素可以用来表示数据校验值,包括CRC32、MD5、SHA1、SHA256、EthernetChecksum、SspiAuthentication等,格式如下:

以如下数据模型为例:

Offset Size Description
0×00 4 bytes Length of Data
0×04 4 bytes Type
0×08 Data
after Data 4 bytes CRC of Type and Data

0×5 PNG格式文件Fuzz实战

目的:以版本3为例,了解如何具体使用peach来做一次完整的有针对性的Fuzz(现在互联网上流传的基本都是旧版或者不完整的片段,本文代码是经过作者亲自测试有效的) 

PNG文件格式如下图(图片来源于网络): 

7.png

这里先介绍一款文件格式解析神器:010Editor,大家可以自行在官网下载安装,完成之后用它打开本地的一个png图片,如下所示。 

8.png 

9.png

注意红框圈住的部分,可以很清楚的看到png文件内部区块的分区和含义,进而归纳出PNG的文件格式——

PNG格式如下:

1.文件头:由八个字节组成,0x89504e470d0a1a0a

2.数据块:每个数据块由四部分构成,他们的描述依次如下:

3.Length :占四字节,表示数据块data域占多少个字节。(注意这里不包括length自身)

4.Type :占四字节,表示当前块的类型。一般是英文大小写字母的ASCII码(65~90或者97~122)

5.Data:数据区。大小可以是0字节

6.CRC:占四个字节,整个chunk的CRC校验码(Length+Type+Data)

有了之前的经验,不难写出如下的PNG DataModel:

接下来就是StateModel部分,这里以一款名为pngcheck的轻量级可执行程序来打开png文件,下载链接

现在我们为Peach Pit加上测试:

到这里已经可以运行测试了,不过这样子只会生成畸形文件,对于实际应用并没有什么用处。只有加上Agent和Monitor,对分析结果进行监控和日志记录才是最终需要的。 
因为作者使用的是Win平台,所以调用的 class 就是 WinAgent了,其他平台的可以做出相应变换。

至此基本就大功告成了,运行一下看看: 
16339781.png

0×6 举一反三:WAV格式Peach Pit编写

为了更好地帮助大家巩固以上知识,再给出一个完整的WAV Peach Pit(基于版本3): 
WAV文件格式: 

10.png

Pit:

0×7 后记

文件格式复杂多变,良好的开端是成功的一半。PeachPit的编写通常是一个细致而又复杂的过程,只有耐心+经验,才能成功写出一个完美的Pit文件。

*本文原创作者:overXsky,本文属FreeBuf原创奖励计划,未经许可禁止转载