Since XML is not the data format that will most likely be the target of fuzzing, this tutorial explains how Fuzzware converts an XML representation of a data format into an instance of the actual data format. This tutorial is not going to cover how to create the XML representation of the data format, that will be the subject of Create an XML Schema and Tutorial 3, so for now let's assume that we have created our XML representation manually. For this tutorial we are going to work with a real file format to make it very concrete. We will work with the Bitmap (BMP) image file format since it is relatively simple. Let's start out where we finished Tutorial 1, an input XML and XSD file with the output of Fuzzware being an XML file. <xs:schema id="BMP" targetNamespace="urn:Fuzzware.Examples.BMP" xmlns:bmp="urn:Fuzzware.Examples.BMP" xmlns="urn:Fuzzware.Examples.BMP" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="BITMAP"> <xs:complexType> <xs:sequence> <xs:element name="FileHeader"> <xs:complexType> <xs:sequence> <xs:element name="Signature" type="xs:string" fixed="BM" /> <xs:element name="FileSize" type="xs:unsignedInt" /> <xs:element name="Reserved" type="xs:unsignedInt" /> <xs:element name="DataOffset" type="xs:unsignedInt" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="InfoHeader"> <xs:complexType> <xs:sequence> <xs:element name="Size" type="xs:unsignedInt" /> <xs:element name="Width" type="xs:unsignedInt" /> <xs:element name="Height" type="xs:unsignedInt" /> <xs:element name="Planes" type="xs:unsignedShort" /> <xs:element name="BitCount" type="xs:unsignedShort" /> <xs:element name="Compression" type="xs:unsignedInt" /> <xs:element name="ImageSize" type="xs:unsignedInt" /> <xs:element name="XpixelsPerM" type="xs:unsignedInt" /> <xs:element name="YpixelsPerM" type="xs:unsignedInt" /> <xs:element name="ColoursUsed" type="xs:unsignedInt" /> <xs:element name="ColoursImportant" type="xs:unsignedInt" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="ColourTable" type="xs:hexBinary" /> <xs:element name="RasterData" type="xs:hexBinary" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
<?xml version="1.0" encoding="utf-8" ?> <bmp:BITMAP xmlns:bmp="urn:Fuzzware.Examples.BMP"> <bmp:FileHeader> <bmp:Signature>19778</bmp:Signature> <bmp:FileSize>1198</bmp:FileSize> <bmp:Reserved>00000000</bmp:Reserved> <bmp:DataOffset>1078</bmp:DataOffset> </bmp:FileHeader> <bmp:InfoHeader> <bmp:Size>40</bmp:Size> <bmp:Width>10</bmp:Width> <bmp:Height>10</bmp:Height> <bmp:Planes>0001</bmp:Planes> <bmp:BitCount>0008</bmp:BitCount> <bmp:Compression>00000000</bmp:Compression> <bmp:ImageSize>120</bmp:ImageSize> <bmp:XpixelsPerM>00000000</bmp:XpixelsPerM> <bmp:YpixelsPerM>00000000</bmp:YpixelsPerM> <bmp:ColoursUsed>00000000</bmp:ColoursUsed> <bmp:ColoursImportant>00000000</bmp:ColoursImportant> </bmp:InfoHeader> <bmp:ColourTable>00000….00FFFFFF00</bmp:ColourTable> <bmp:RasterData>FFFFFFFFFF….FFFF0000</bmp:RasterData> </bmp:BITMAP> Note, an image file contains a lot of binary data, this has been removed for brevity, but this file is the same as the one in the Examples\BMP directory, BMP.xml. Create a new project called Tutorial2 (in the Tutorial directory) and copy the XSD above into a file called BMP.xsd and copy BMP.xml from Examples\BMP\BMP.xml to the Tutorial2 directory. Set the input source for Tutorial2 to be these files (in the same way as we did in Tutorial 1). So if we ran Fuzzware on this input and output to a directory we would get an XML file as above, which is obviously nothing like a BMP file. The way to change how Fuzzware outputs XML is by adding special attributes to the XSD element definitions. These attributes are found in the file Schemas\SchemaAttributeCommands.xsd in the Schemas directory of the installation directory of Fuzzware and are also listed in the References section here. By adding a reference to this schema in the declaration of the xs:schema element we can now add these attributes to schema elements <xs:schema id="BMP" targetNamespace="urn:Fuzzware.Examples.BMP" xmlns:bmp="urn:Fuzzware.Examples.BMP" xmlns="urn:Fuzzware.Examples.BMP" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sac="urn:Fuzzware.Schemas.SchemaAttributeCommands">
The first step in the right direction is going to be to remove all the XML markup. The way Fuzzware treats markup is controlled by the 'markup' attribute, which can have one of the following values: remove | Remove the markup on this node
| removeIncludingChildNodes | Remove the markup on this node and all its descendants
| dontRemove
| Don't remove markup (and override any parent setting)
| dontRemoveIncludingChildNodes | Don't remove on this node and all its descendants
|
When applied to any given element in the XSD file, this will tell Fuzzware how to output the XML makrup for that node and potentially its child nodes. Note, the value assigned to an element will override any value that a parent element tries to assign. So by applying 'removeIncludingChildNodes' to the root node of our XSD file, Fuzzware will not output any XML markup. <xs:element name="BITMAP" sac:markup="removeIncludingChildNodes"> The Test Mode output of this is: BMP1198000000001078401010000100080000000012000000000000000000000000000000000000000000….FFF0000FFFFFF00FFFFFFFFFFF…...FFFFF0000 Which is what we expect, basically a string of numbers. Still this is still certainly not a valid BMP file, we need to convert the number strings into their binary equivalents and the hex strings into binary data. To output simple types (schema elements without children) in different formats we use the SchemaAttributeCommands 'outputAs' attribute. This attribute can have several different values but only has an affect when set to a value appropriate for the type of the element. So for all integer types (greater than 1 byte in size) the relevant values of outputAs are BinaryLittleEndian and BinaryBigEndian. For the BMP format we want all integer types, be they unsignedShorts or unsignedInts to be output as BinaryLittleEndian. For the hexBinary data type we simply want to output its binary equivalent value, for example the string "A1B2" would become the binary data 0xA1B2. To do this we use the outputAs value Decoded.
Adding the outputAs attribute to the XSD file gives the same XSD file found in the BMP examples folder. <?xml version="1.0" encoding="utf-8"?> <xs:schema id="BMP" targetNamespace="urn:Fuzzware.Examples.BMP" xmlns:bmp="urn:Fuzzware.Examples.BMP" xmlns="urn:Fuzzware.Examples.BMP" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sac="urn:Fuzzware.Schemas.SchemaAttributeCommands"> <xs:element name="BITMAP" sac:markup="removeIncludingChildNodes"> <xs:complexType> <xs:sequence> <xs:element name="FileHeader"> <xs:complexType> <xs:sequence> <xs:element name="Signature" type="xs:string" fixed="BM" /> <xs:element name="FileSize" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="Reserved" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="DataOffset" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="InfoHeader"> <xs:complexType> <xs:sequence> <xs:element name="Size" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="Width" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="Height" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="Planes" type="xs:unsignedShort" sac:outputAs="BinaryLittleEndian" /> <xs:element name="BitCount" type="xs:unsignedShort" sac:outputAs="BinaryLittleEndian" /> <xs:element name="Compression" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="ImageSize" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="XpixelsPerM" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="YpixelsPerM" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="ColoursUsed" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> <xs:element name="ColoursImportant" type="xs:unsignedInt" sac:outputAs="BinaryLittleEndian" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="ColourTable" type="xs:hexBinary" sac:outputAs="Decoded" /> <xs:element name="RasterData" type="xs:hexBinary" sac:outputAs="Decoded" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> To see the output when we use this XSD file you should change the output destination settings by changing the file extension of the output files from 'xml' to 'bmp'. Also, on the run fuzzer page select the SmallBitmap.bmp file from the Examples\BMP directory to compare against the output of the fuzzer. 00000000h: 42 4D AE 04 00 00 00 00 00 00 36 04 00 00 28 00 ; BM®.......6...(. 00000010h: 00 00 0A 00 00 00 0A 00 00 00 01 00 08 00 00 00 ; ................ 00000020h: 00 00 78 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ..x............. 00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 80 ; ............€..€ 00000040h: 00 00 00 80 80 00 80 00 00 00 80 00 80 00 80 80 ; ...€€.€...€.€.€€ 00000050h: 00 00 C0 C0 C0 00 C0 DC C0 00 F0 CA A6 00 00 20 ; ..ÀÀÀ.ÀÜÀ.ðʦ.. 00000060h: 40 00 00 20 60 00 00 20 80 00 00 20 A0 00 00 20 ; @.. `.. €.. .. 00000070h: C0 00 00 20 E0 00 00 40 00 00 00 40 20 00 00 40 ; À.. à..@...@ ..@ 00000080h: 40 00 00 40 60 00 00 40 80 00 00 40 A0 00 00 40 ; @..@`..@€..@ ..@ 00000090h: C0 00 00 40 E0 00 00 60 00 00 00 60 20 00 00 60 ; À..@à..`...` ..` 000000a0h: 40 00 00 60 60 00 00 60 80 00 00 60 A0 00 00 60 ; @..``..`€..` ..` 000000b0h: C0 00 00 60 E0 00 00 80 00 00 00 80 20 00 00 80 ; À..`à..€...€ ..€ 000000c0h: 40 00 00 80 60 00 00 80 80 00 00 80 A0 00 00 80 ; @..€`..€€..€ ..€ 000000d0h: C0 00 00 80 E0 00 00 A0 00 00 00 A0 20 00 00 A0 ; À..€à.. ... .. 000000e0h: 40 00 00 A0 60 00 00 A0 80 00 00 A0 A0 00 00 A0 ; @.. `.. €.. .. 000000f0h: C0 00 00 A0 E0 00 00 C0 00 00 00 C0 20 00 00 C0 ; À.. à..À...À ..À ... 00000440h: 00 00 FF F9 F9 F9 F9 F9 F9 FF FF FF 00 00 FF FF ; ..ÿùùùùùùÿÿÿ..ÿÿ 00000450h: F9 FF FF FF F9 F9 FF FF 00 00 FF FF F9 FF FF FF ; ùÿÿÿùùÿÿ..ÿÿùÿÿÿ 00000460h: FF F9 F9 FF 00 00 FF FF F9 FF FF FF FF FF F9 FF ; ÿùùÿ..ÿÿùÿÿÿÿÿùÿ 00000470h: 00 00 FF FF F9 FF FF FF FF FF F9 FF 00 00 FF FF ; ..ÿÿùÿÿÿÿÿùÿ..ÿÿ 00000480h: F9 FF FF FF FF F9 F9 FF 00 00 FF FF F9 FF FF FF ; ùÿÿÿÿùùÿ..ÿÿùÿÿÿ 00000490h: F9 F9 FF FF 00 00 FF F9 F9 F9 F9 F9 F9 FF FF FF ; ùùÿÿ..ÿùùùùùùÿÿÿ 000004a0h: 00 00 FF FF FF FF FF FF FF FF FF FF 00 00 ; ..ÿÿÿÿÿÿÿÿÿÿ.. The output should indicate that the output and the file it was compared against are identical.
|