Peach3 元素详细解析(一)
1. Peach Pits文件
Peach Pits是一些xml 文件,包含Peach执行fuzzing所需的所有信息。当你使用Peach进行fuzzing时,需要创建一个Peach Pits文件,它主要包含以下几项内容:通用配置,数据模型,状态模型,代理和监控以及测试配置。
容器类元素
Block:组合容器,把多个元素组合起来便于被引用
Flags:装载Flag元素的容器,以bit为单位的元素(flag)的集合
Stream: 除含有streamName和streamAttribute外和Block的形式相同;多用于zip、audio/video文件类的fuzz。
元数据类元素
String:字符串
Number:数字
Blob:主要用于包含非结构化的数据,如字节数组和原始二进制数据等
Flag:用于bit单位的元素数据,结合Flags形成标志位的数据建模
Padding:用0来填充数据以达到对齐或指定长度的效果
关系类元素
Size-of Relation:
Count-of Relation:
Offset-of Relation: Relative offset & Relative to offset
功能类元素
Fixups:其对其他数据做相应功能运算得出一结果值,如计算校验和或哈希值。
Transformers:对其父元素做相应功能运算得出特定格式的结果,如对数据加解密、压缩和解压缩、特定编码和解码等
2.通用配置
Peach Pits文件的第一部分是通用配置。这里是包含其他peach pits文件的位置,比如外部引用接口、默认属性设置、python模块路径配置和自定义代码导入等。
2.1 Include
Include元素允许把其他pit文件包含到当前pit文件的名称空间中使用。当引用被包含的Pits文件时,用命名空间前缀和冒号的格式来命名。格式:Foo:DataModel/StateModel块,如下所示:
属性:
ns------必须的。名称空间前缀
src-----必须的。源码URL,用“file:”前缀来命名文件名。
2.2 Defaults
Defaults—用来设置Data元素的默认属性,比如字节顺序。(注:目前该元素的详细内容,官网打不开)。
2.3 PythonPath
PythonPath元素是一个顶层元素,它添加一个被python模块搜索的路径,主要作用是延伸Peach和包含自定义代码的位置。
属性:
Path—必须的。要添加的路径。
2.4 Import
Import元素允许在pit文件中导入自定义的python模块来使用。它就像python的关键字import一样。(注意,目前Peach 3不支持from属性)
属性:
Import–必须的。和python的关键字import一样。
3.数据模型
Peach Pit文件包含至少一个DataModel元素,也可以更多。DataModel描述的数据包括类型信息、关系信息(大小、数目、偏移)和其他让模糊器执行智能变异的信息。DataModel能被其他的DataModel重用和引用,允许将复杂的定义分解为可读部分。
3.1 DataModel
DataModel是Peach根元素的子元素之一,它通过添加子元素(比如Number、Blob或者String)的方式定义了数据块的结构。
(1)属性
Name----必须的。当引用模型或者调试时,友好的DataModel名字是非常有用的。
ref--------可选的。引用一个DataModel模板。
(2)子元素:
Block、Choice、Custom、Flag、Flags、Number、Padding、String、XmlAttribute、XmlElement、Relation、Fixup、Transformer、Placement。
(3)例子:
一个Peach文件中可以指定任意多个DataModel元素,但每个DataModel的名字必须唯一。通过DataModel可以将复杂的格式按照逻辑分解为更小的模型,使数据模型更易阅读、调试和重用。
(4)引用(ref属性):
当一个引用(ref属性)被提供时,被引用DataModel元素的内容将被复制,并已次为基础来创建新的DataModel元素。新DataModel的任何子元素将覆盖具有相同名字的基础元素。一般的例子中,自定义的子模块中包含一个名字为Key的字符串,它的值将会覆盖没有值的父字符串“Key”。
当一个DataModel被解析时,自定义DataModel看起来像是两个数据模型的组合。
3.2 Blob
Blob元素是DataModel或Block的一个子元素。Blob元素常常用于代表缺少类型定义或格式的数据。
(1)属性
Name
Value
length-------Blob的大小,单位为字节
ref
valueType—值的表示格式,默认是string也可以是hex
minOccurs—该Blob元素必须发生变化的最小次数,默认为1
maxOccurs–该Blob元素能够发生变化的最大次数,默认为1
Token---------当解析时元素应该作为一个令牌来信任,默认是假。即是解析时的关键字
lengthType–长度的单位默认是byte
constraint----指定满足表达式的值是数据才会变异
Mutable-------Blob元素是否可变异,默认为真
(2)子元素:
anayzers
(3)例子
一个简单的Blob。这个Blob中,任何类型或长度的数据都会破解(carck into)到这个blob中
<Blob name="Unknown1" />
一个有默认值的blob
<Blob name="Unknown1" valueType="hex" value="AA BB CC DD" />
3.3 Block
Block元素是DataModel或Block的子元素。Blocks用于将一个或多个数据元素(例如Number或String)组合到一个逻辑结构中。 Block和DataModel非常相似,唯一的区别是它们的位置。 DataModel是顶级元素,Blocks是DataModel的子元素。 Block和DataModel元素都可以用作其他Blocks或DataModel的“模板”。
<Block name="HelloWorld">
<String value="Hello world!" />
</Block>
(1)属性(除非声明,所有的属性都是可选的):
Name—Block的名字。
Ref—引用一个数据模型来作为Block的模板。。
minOccurs—该Block必须发生变化的最小次数。
maxOccurs–该Block可以发生变化的最大次数。
Mutable—元素是否可变异,默认为真。
(2)子元素:
Blob、block、Choice、Custom、Fixup、Flag、Flags、Number、Padding、Placement、Relation、Seek、String、Transformer、XmlAttribute、XmlElement。
(3)例子
空block
最简单的block定义是一个空block。这种定义将不会产生输出。
<DataModel name="BlockExample1">
<Block>
</Block>
</DataModel>
嵌套Block
Block可以根据需要嵌套。 Block有助于创建逻辑结构,并且不会更改其中包含的数据。
<DataModel name="BlockExample2">
<Block>
<Block>
<Block>
<String value="1" />
</Block>
<Block>
<String value="2" />
</Block>
<String value="3" />
</Block>
<String value="4" />
</Block>
</DataModel>
这种嵌入式定义下的Block将会产生如下输出:
1234
Naming A Block
给Block一个友好的命名可使它们更容易理解和调试。
<DataModel name="BlockExample2">
<Block name="HeaderDef">
<String name="Header" />
<String name="Colon" value=":"/>
<String name="Val"/>
<Block>
<Block name="DataDef">
<Number name="Type" size="8" value="4"/>
<Number name="Data" size="8" value="32"/>
</Block>
</DataModel>
Referencing A Block
使用reference元素(ref属性)会把被引用的DataModel或者Block的内容复制过来以作为构建新Block的基础。新Block中的任何子元素将覆盖已存在的具有相同名称的元素。
<DataModel name="OtherDataModel">
<String value="Hello World"/>
</DataModel>
<DataModel name="ThisDataModel">
<Block name="MyName" ref="OtherDataModel"/>
</DataModel>
Block “MyName” 将被引用块“OtherDataModel”覆盖。 在解析它时,数据结构看起来像这样。
<DataModel name="ThisDataModel">
<Block name="MyName">
<String value="Hello World"/>
</Block>
</DataModel>
Reference允许构建功能强大的模板。 这是一个Key:Value \ r \ n的模板。
<DataModel name="Template">
<String name="Key" />
<String value=": " token="true" />
<String name="Value" />
<String value="\r\n" token="true" />
</DataModel>
引用此模板:
<DataModel name="OtherModel">
<String value="Before Block\r\n" />
<Block name="Customized" ref="Template">
<String name="Key" value="Content-Length" />
<String name="Value" value="55"/>
</Block>
</DataModel>
输出为:
Before Block\r\n
Content-Length: 55\r\n
这里发生了两件重要事情。 在分析时,”Customized Block”将用”Template”的DataModel替换它的结构。 添加“:”和“\ r \ n”的字符串值。
同时,“Customized”Block重写了Key和Value的String元素的值。 将它们替换为“Content-Length”和55.最终的DataModel将被解析为如此。
<DataModel name="OtherModel">
<String value="BeforeBlock" />
<Block name="Customized" ref="Template">
<String name="Key" value="Content-Length" />
<String value=": " token="true" />
<String name="Value" value="55" />
<String value="\r\n" token="true" />
</Block>
</DataModel>
3.4 choice
Choice元素是DataModel或Block的子元素。 Choice元素用于指示任何子元素都是有效的,但只能选择一个。 很像编程语言中的switch语句。
<Choice name="ChoiceBlock">
<Block name="Type1">
<!-- ... -->
</Block>
<Block name="Type2">
<!-- ... -->
</Block>
<Block name="Type3">
<!-- ... -->
</Block>
</Choice>
(1)属性(除非声明,所有的属性都是可选的):
Name—choice元素的名字。
minOccurs—该Choice必须发生改变的最小次数。
maxOccurs—该Choice能发生改变的最大次数。
Occurs—该choice能发生改变的迭代次数。
(2)子元素:
Block、Choice、String、Number、Blob、Flags、Fixup、Transformer、XmlAttribute、XmlElement。
(3)例子:
一个基本的Choice Block。 该Choice示例将破解或使用类型为1,2,3的数据。 就像常规的switch语句一样,需要在标记上做出决定。
如果前8位值为1,则剩余数据被视为一个32位的数。 如果前8位值为2,则剩余数据被视为一串长度为255个字节的二进制数据。 如果前8位值为3,则剩余数据被视为一个8字节的字符串。
当进行模糊化测试时Peach会选择三种类型之一,将其模糊为8位数字输出,并且接着输出相应的类型。 Peach将尝试全部三种类型。
<DataModel name="ChoiceExample1">
<Choice name="Choice1">
<Block name="Type1">
<Number name="Str1" size="8" value="1" token="true" />
<Number size="32"/>
</Block>
<Block name="Type2">
<Number name="Str2" size="8" value="2" token="true" />
<Blob length="255" />
</Block>
<Block name="Type3">
<Number name="Str3" size="8" value="3" token="true" />
<String length="8" />
</Block>
</Choice>
</DataModel>
An array of Choices
第一个例子适合做出单一选择,但如果有很多Type1 Type2和Type3块都相互连接,会怎么样呢? 设置minOccurs,maxOccurs或occurs以指定Choice应该被重复。
<DataModel name="ChoiceExample1">
<Choice name="Choice1" minOccurs="3" maxOccurs="6">
<Block name="Type1">
<Number name="Str1" size="8" value="1" token="true" />
<Number size="32"/>
</Block>
<Block name="Type2">
<Number name="Str2" size="8" value="2" token="true" />
<Blob length="255" />
</Block>
<Block name="Type3">
<Number name="Str3" size="8" value="3" token="true" />
<String length="8" />
</Block>
</Choice>
</DataModel>
3.5 Flag
Flag元素在Flags容器中定义了一个特定的位区域。
(1)属性:
Name—可选的。元素的名字。
Size—必须的。大小,以位为单位为
Position—必须的。Flag的开始位置(以0位基础)。
Value—带有Blob的默认值。
valueType—格式的默认值(hex,string,literal)。
Mutable—可选的。数据元素是否变异,默认为真(peach 2.3)。
(2)子元素:
Relation。
3.6 Flags
Flags定义了一组Flag的大小。
(1)属性:
Name—可选的。元素的名字。
Size—必须的。大小,以位为单位。
Mutable—可选的。元素是否可以变异,默认为真。
(2)子元素:
Fixup、Flag、Placement、Relation、Transformer。
3.7 Number
该元素定义了长度为8,16,24,32,或64位长度的二进制数。它是DataModel、Block或者Choice的子元素。
(1)属性:
Name—必须的。Number的名字。
Size—必须的。Number的大小,以位为单位。有效值为1到64。
Value—分配给Number的默认值。
valueType—可选的。value的表现方式。有效选项为string(字符串)和hex(十进制)。
Token—当解析的时候,该元素被视为一个令牌,默认值为假。有效选项为真和假。
Endian—Number的字节顺序。默认为小端。有效选项为大端、小端和网络。网络一样是大端。
Signed—Number是否为有符号数据。默认为真。有效选项为真和假。
Constraint—一个以Python表达式为形式的约束。用于数据破解。
Mutable—元素是否可改变(fuzzing时是否可变异),默认为真。有效选项为真和假。
minOccurs—Number必须发生改变的最小次数,默认为1。有效选项为正整数值。
maxOcuurs—Number能够发生改变的最大次数,没有默认值。有效选项为正整数值。
(2)有效子元素:
Anayzers、Fixup、Relation、Transformer、Hint。
(3)例子
一个简单的例子,它将产生一个32位(4字节)Number,默认值为5
为了只使用16位(2字节),改变size的值为16
有符号。为了表明这是一个无符号数据元素,设置signed属性等于“false”。默认为真。
ValueType。值类型定义了怎么解释Value的属性。有效选项为string和hex,默认为string。
将值1000分配给Hi5。
将43981以十六进制形式分配给Hi5。
大端。为了改变Number 的字节顺序,请设置endian属性。如下输出的字节顺序为:AB CD
小端,如下输出的字节顺序为:CD AB
3.8 Padding
padding元素用来填充大小变化的块或数据模型。
(1)属性:
Name—必须的。Number 元素的名字。
Aligned—将父元素对齐到 8 字节边界,默认为假。
Alignment—对齐到这个位边界,比如(8、16 等),默认为 8。
alignedTo—基于我们要填充的元素名字。 Lengthcalc—计算结果为整数的脚本表达式。
Constraint—一个以 Python 表达式形式的约束。用于数据破解。指定满足表达式的值是数据才会变异 。
Mutable—元素是否可变异,默认为真,有效选项为真和假。
(2)有效子元素:
Fixup、Relation、Transformer、Hint。
(3)例子:
3.9 String
该元素定义了一个单字节或者双字节的字符串,它是DataModel或者Block的子元素。如果为了指定这是一个数值的字符串,请用 NumericalString 元素。
<String value="Hello World!"/>
<String value="Null terminated string" nullTerminated="true"/>
(1)属性
Name—可选的,数据模型的名字。
Length—可选的,字符串的长度。
lengthType—可选的,Length 属性的单位。
Type—可选的。字符编码类型,默认为“ASCII”,有效选项为 ASCII、utf7、utf8、utf6、 utf6be、utf32。
nullTerminated—可选的。是否为以空字节结尾的字符串(真或者假)。
padCharacter—可选的。根据 length 参数填充字符串的字符,默认为(0x00)。
Token—可选的。当解析的时候,该元素应该被视为一个令牌,默认为假。
Constraint—一个脚本表达式形式的约束。用于数据破解。
Mutable—可选的。元素是否可变异,默认为真。
Minoccurs—可选的。这个块必须发生改变的最小次数,默认为 1。
Maxoccurs—可选的。这个块会发生改变的最大次数,默认为 1。
(2)有效子元素
Analyzer、Fixup、Relation、Transformer、Hint。
(3)NumericalString:
该元素只能用于String来说明它的值是一个数字。当使用这个提示时,它激活所有的数字突变以及标准的字符串突变。请注意:如果默认情况下一个字符串的值是数字,NumericalString元素会被自动添加。
3.10 XMLAttribute
该元素定义了XML元素的属性。只有当父元素是XmlElement时,才有效。
(1)属性
Name—可选的。数据模型的名字。 Minoccurs—可选的。这个块必须发生变化的最小次数。 Maxoccurs—可选的。这个块会发生变化的最大次数。 isStatic—可选的。当解析的时候,该元素被视为一个令牌,默认为假。 Token—可选的。当解析的时候,该元素被视为一个令牌,默认为假(Peach 2.3)。 Mutable—可选的。该元素是否可变异,默认为真(Peach 2.3)。 attributeName—必须的。XML 元素的名字。 Ns—可选的。XML 名称空间。
(2)有效子元素
Block、Choice、String、Number、Blob、Flags、Fixup、Hint。
3.11 XmlElement
定义一个XML元素,XML文档的基本块构建。这用来fuzzing一个XML文档的内容,但是不包含xml解析器。XmlElement 和 XmlAttribute 产生的所有输出都将被格式化。请注意, XmlElement 和 XmlAttribute 元素不支持数据破解。如果需要破解 Xmlelement 和 XmlAttribute 中的 XML,请用挂载到一个 String 元素的 XmlAnalyzer。
(1)属性
Name—可选的。数据模型的名字。 Minoccurs—可选的。这个块必须发生变化的最小次数。 Maxoccurs—可选的。这个块会发生变化的最大次数。 isStatic—可选的。当解析的时候,该元素被视为一个令牌,默认为假。 Token—可选的。当解析的时候,该元素被视为一个令牌,默认为假(Peach 2.3)。 Mutable—可选的。该元素是否可变异,默认为真(Peach 2.3)。 attributeName—必须的。XML 元素的名字。 Ns—可选的。XML 名称空间。
(2)有效子元素
XmlElement、XmlAttribute、Block、Choice、String、Number、Blob、Flags、Fixup、Hint
3.12 Hint
Hint是变异器的扩展。它能附加到数据元素上,为Peach引擎提供更多关于被解析数据的信息。例如,当字符串包含一个数字时,只有包含在字符串mutator中的数字测试才会执行。如果你添加一个 NumericalString 提示到 String,它将附加所有的数字变异器。
可用的 Hints:
NumericalString、ArrayVarianceMutator-N、DWORDSliderMutator、BitFlipperMutator-N、
NumericalVarianceMutator-N 、 Telecommunications-N 、 FiniteRandomNumbersMutator-N 、 SizedVaranceMutator-N、SizedNumericalEdgeCasesMutator-N、SizedDataVaranceMutator-N、 SizedDataNumericalEdgeCasesMutator-N、type、ValidValues。
3.13 Relation
Peach 允许构建数据间的关系。关系是类似这样的东西“X 是 Y 的大小”、“X 是 Y 的 数量”、或者“X 是 y 的偏移(字节单位)”。
(1)大小关系:
在这个例子中,Number 元素的值将确定名字为 TheValue 的 string 元素的大小。请注意, 这也适用于多字节字符,如 wchar。在 Peach 未来的版本中,这将会改变,或者将包括新的 类型长度关系,以便更好地支持 UTF-8 和其他 Unicode 编码。
在如下例子中,我们将提供两个 python 表达式,它允许在获取或设置 size 属性的时候 修改它的大小,有两个变量可用,分别为 self 和 size。Self 是 Number 元素的一个引用,size 是一个整数。获取操作和设置操作应该是彼此的数学逆操作。在破解过程中应用获取操作, 在发布过程中应用设置操作。
expressionGet—该表达式的结果用于内部,它确定名字为 TheValue 的 String 元素读取多 少字节。如果 Peach 取 10,它将在内部存储一个 5,然后 Peach 将读取 5 个字节到 String 中。
ExpressionSet—为 publisher 生成一个值。 在以下示例中,为 TheValue 存储的 Size 的值 “5”(TheValue 的长度),因此 Peach 通过 publisher 输出的值将为“5 * 2”或 10。
(2)数量关系:
在这个例子中,Number 将会说明 String 列表的数目。
在这个例子中,我们将提供两个 python 表达式,它允许在获取或设置 size 属性的时候 修改它的大小。有两个变量可用,分别为 self 和 count。Self 是 Number 元素的一个引用,count 是一个整数。这里的让 count 可用与前面的表达式不同。虽然 self 在表达式对中始终可用, 但其他可用的变量的名字是 Relation 元素 type 属性的值。
expressionGet—该表达式的结果用于内部,它确定 String 元素将扩展到多少项。 maxOccurs 是 Peach 循环计算中遇到的最大值,由于 maxOccurs = 1024 的限制,Peach 在 CountIndicator 元素中破解时遇到的最大值是 2048。
ExpressionSet—设置要生成的值。 以下示例中,count 根据读入的 String 元素数目确定。
(3)偏移关系:
偏移关系是 Peach 最新增加的,它允许需修改格式,这些格式需要偏移的改变和输出变 量元素的偏移。这里有一些元素,它们是各种 String 元素偏移量的 ascii 表示。
1、相对偏移量: 从 Peach 2.3 开始支持相对偏移的概念。 相对偏移来自附加到 relation 的数据元素。 请 考虑以下示例。当确定 StringData 的偏移量时,Peach 将根据需要,对 OffsetToString 的位 置进行加上/减去它的值,以确定正确的偏移量。
2、相对于偏移量: Peach 还支持相对于另一个元素的偏移。它用于以下情况,一个元素包含另外一个元素 的偏移,而被包含的偏移的元素是一个结构体的开头。 以下示例中,StringData 偏移量将通 过添加 OffsetToString 的值到 Structure 位置的方式来计算。
包含 expressionGet / expressionSet 当使用带有偏移关系的 expressionGet / Set 时,将提供两个变量:self 和 offset。 Self 引用了一个父元素的引用,offset 是一个整数。 包含 Placement 的偏移关系 这个模型中,将使用一个典型的模式。在这个模式中,一个偏移列表会给我们另一个元 素的位置。 使用 Placement 元素将创建的 Data 字符串移动到 Chunks 块之后。
3.14 Fixup
Fixup是一些代码函数,它通常操作另一个元素数据来产生一个值。校验和算法就是这样一个示例。Peach默认包含有以下fixups。
⚫Utility Fixups
◆ CopyValueFixup ◆ SequenceIncrementFixup ◆ SequenceRandomFixup
⚫ Check-sum Fixups
◆ Crc32DualFixup ◆ Crc32Fixup ◆ EthernetChecksumFixup ◆ ExpressionFixup ◆ IcmpChecksumFixup ◆ LRCFixup
⚫ Hashing Fixups
◆ MD5Fixup ◆ SHA1Fixup ◆ SHA224Fixup ◆ SHA256Fixup ◆ SHA384Fixup ◆ SHA512Fixup
3.15 Transformers
Transformers 在父元素上执行静态转换或编码。通常来说 Transformers 是两个方向:编 码和解码,但也不全是。 比如 ZIP 压缩,Base64 编码,HTML 编码等。与 Fixups 不同, Transformers 对父元素操作,而 Fixups 引用另一个元素的数据。
上述数据模型的输出为 0x01 <len(b64(Data))> <b64(Data)>
Peach3 中的默认Transformers:
⚫ Compression (压缩)
◆ Bz2CompressTransformer
◆ Bz2DecompressTransformer
◆ GzipCompressTransformer
◆ GzipDecompressTransformer
⚫ Crypto (加密)
◆ Aes128Transformer ◆ ApacheMd5CryptTransformer ◆ CryptTransformer ◆ CvsScrambleTransformer ◆ HMACTransformer ◆ MD5Transformer ◆ SHA1Transformer ◆ TripleDesTransformer ◆ UnixMd5CryptToolTransformer ◆ UnixMd5CryptTransformer
⚫ Encode (编码)
◆ Base64EncodeTransformer ◆ Base64DecodeTransformer ◆ HexTransformer ◆ HexStringTransformer ◆ HtmlEncodeTransformer ◆ HtmlDecodeTransformer ◆ HtmlEncodeAgressiveTransformer ◆ Ipv4StringToOctetTransformer ◆ Ipv4StringToNetworkOctetTransformer ◆ Ipv6StringToOctetTransformer ◆ JsEncodeTransformer ◆ NetBiosEncodeTransformer ◆ NetBiosDecodeTransformer ◆ SidStringToBytesTransformer ◆ UrlEncodeTransformer ◆ UrlEncodePlusTransformer ◆ Utf8Transformer ◆ Utf16Transformer ◆ Utf16LeTransformer ◆ Utf16BeTransformer ◆ WideCharTransformer
⚫ Type (类型转换)
◆ AsInt8Transformer ◆ AsInt16Transformer ◆ AsInt24Transformer ◆ AsInt32Transformer ◆ AsInt64Transformer ◆ IntToHexTransformer ◆ NumberToStringTransformer ◆ StringToFloatTransformer ◆ StringToIntTransformer
⚫ Misc (混杂)
◆ EvalTransformer
3.16 Placement
Placement元素告诉数据破解者,在输入流被解析之后,特定元素应该被移动。结合偏移关系是Peach支持的文件处理方式,它通过偏移来包含元素的引用。
属性:
以下其中之一是必须的:
After—元素移动到之后。
Before—元素移动到之前。