Friday, January 7, 2011

Fuzzing with Peach - The Peach Pit - Part 2

Originally Posted: SUNDAY, MAY 23, 2010 AT 3:21PM

In my last post I showed you how to install the peach fuzzing framework. The next step is to set up our configuration file called the peach pit. The peach pit is an XML files that lays out the protocol we are going to fuzz. In this case I am going to stick with TFTP. The author of peach, Michael Eddington, provides an auto complete library for use with Microsoft Visual Studio(free) which helps with the pit generation process immensely. I recommend you download and install it if you plan on working with peach pits on a regular basis.



Peach Pits are in a block based format. Each block is responsible for a different task and has its own set if instructions. The first block is the file header block, it defines the file as an XML document and imports some defaults. The best way to set this up is to copy the template.xml found in the peach root folder. This file will have the headers already setup as well as place holders for the other blocks needed for a complete pit file.

Next up is data model block. This block is where we set up the request. In the TFTP example this is where I defined the Read request. Below I have outline a TFTP read request as detailed in the RFC.

TFTP PACKET
----------------------------------------------

| \x00\x01 | Filename | 0 | Mode | 0 |

----------------------------------------------

Based on this information I know that my request starts with "\x00\x01" in hex followed by the filename and mode. I can also note both the file name and mode are null byte terminated. For this example I am not going to fuzz the "mode" variable just the filename. This request would look like this in peach:

<DataModel name="tftprrx">
    <Blob name="opcode" valueType="hex" value="00 01" token="true"/>
    <String name="filename" value="filename.txt" nullTerminated="true"/>
    <String name="mode" value="NETASCII" token="true" nullTerminated="true"/>  
</DataModel>
The "DataModel name" is user defined and does not matter to the fuzzer, you can name it as you wish. The next field is the "Blob" field which I use to define the opcode as a read request ("00 01"). I set the "token = true" so that peach knows this field is not included to be fuzzed. The following strings field is the field we are looking to fuzz. Again it starts with a name followed by a value. The nullTerminated is set to true because both the filename and mode fields are null terminated fields (Note: I'm not trying to insult your intelligence with this but this can be confusing so bear with me). Same thing with mode field but I define it as a token and therefor not a fuzzable(I think I just made that word up) field. For more info on the Data Model field refer to the documentation:http://peachfuzzer.com/DataModeling

Next up is the state block, this is used to define the state logic of the program. This TFTP fuzzers state is very simple in our example. We are only fuzzing one field of one data type so all we need to do is set the action to output the data model we defined earlier to our published(defined later as part of the "test" block). To read on the other action types: http://peachfuzzer.com/Action

<StateModel name="state1" initialState="Initial">
    <State name="Initial">
        <Action type="output">
            <DataModel ref="tftprrx"/>
        </Action>
   </State>
</StateModel>
Next up is my favorite part of peach, the agents. This is what sets peach apart from other fuzzers such as Spike and the Metasploit auxiliary fuzzers. The agents will monitor the application state and in the event of crash recored all of the details to a logfile as well as a pcap(if network based)of the request that caused the crash. Once this data has been logged(to a location defined later) it will restart the service/application and resume fuzzing. I will also use microsofts !exploitable plugin for WinDBG to classify the crash as Exploitable, Probably Exploitable, Probably Not Exploitable, or Unknown.

To set up an agent you will define where your agent resides (the client machine) and what you want it to monitor. In my case I was monitoring the service "SolarWinds TFTP Server" and all network traffic on UDP port 69 (the TFTP Port). The network filter is in BPF style, similar to the style used by tcpdump. My agents block looked like this:


<Agent name="RemoteAgent" location="http://192.168.239.128:9000">
       <Monitor class="debugger.WindowsDebugEngine">
              <Param name="Service" value="SolarWinds TFTP Server" />
        </Monitor>
        <Monitor class="network.PcapMonitor">
              <Param name="filter" value="udp port 69" />
        </Monitor>
</Agent>
Almost done. Now we need to start putting some of the blocks together and define a test. We only have one test to define, but you can define as many test as you see fit. Usually you will have one test for each data block you defined earlier. The publisher field is where you will define how the data sent to the application as well as the client information.

<Test name="tftprrx">
       <Agent ref="RemoteAgent"/>
       <StateModel ref="state1"/>
       <Publisher class="udp.Udp">
              <Param name="host" value="192.168.239.128" />
              <Param name="port" value="69" />
       </Publisher>
</Test>
The field here are more or less self explanatory. Fill in the name of the fields as you defined earlier on in the pit. The only new fields here are the publishers fields. This defines how the data is transmitted. In our case TFTP is UDP so we use the udp publisher. We give it the parameters it needs to operate and thats about it. For more options on the Publisher go to http://peachfuzzer.com/Publishers or http://peachfuzzer.com/docs/apidocs/Peach.Publishers-module.html

The last block you will need to modify is the "Run" block. This define where you want to log the results and which test you want to run. I didnt change the Logger info for any of my test because I liked how it did it by default. The path value is relative to your peach root folder(ie. c:\Peach\logs) so if you change it start there.

<Run name="DefaultRun">
       <Logger class="logger.Filesystem">
             <Param name="path" value="logs"/>
       </Logger>
       <Test ref="tftprrx"/>
</Run>
</Peach>
Thats it, thats a peach pit. It seems complicated, and it is. You will find as you add and modify your fuzzer it takes less time to add new methods (a TFTP write request for example). I will post my complete pit in the peach pit section for reference. As always the comments are open for questions or you can hit me up on twitter @nullthreat. I am also in IRC on Freenode in #offsec and #backtrack-linux most of the time.

More Resources:
http://www.peachfuzzer.com - The home of Peach Fuzzing Framework
http://groups.google.com/group/peachfuzz - Very active mailing list, I got a reply in less the 5 minutes
http://msecdbg.codeplex.com/ - The home of !Exploitable

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I've heard of this software before and it helped me in a lot of ways. I'm glad you shared this step-by-step procedure.

    document scanning services

    ReplyDelete