Thursday, February 9, 2012

Basic Sulley Fuzzing with Linux Host

Background

Recently, I wanted to perform some basic fuzzing against a target application.  I chose Sulley because it's Python-based and others on the project were already using it.  Unfortunately, Sulley is a finicky beast, and it's difficult to find clear instructions on how to install, configure, and get a basic fuzzing session started.  Even fewer places talk about using Sulley on Linux.  Hopefully, this post will fill that gap (in addition to being my online notebook). It will also document the changes I had to make to Sulley to get vmcontrol working on Linux.

Installation

In my case, I used two separate systems for my fuzzing work.  The target system (a Windows XP VM) executed the target application and Sulley monitoring agents.  The other system (my Linux host) executed the Sulley driver scripts. 

One of the clearest guides I found was over at the RosinCore blog: http://rosincore.wordpress.com/2011/09/18/setting-up-a-sulley-fuzzing-framework-on-windows-7/ .  I used his guide when configurging my target, with some changes.  I've listed my steps below - see RosinCore post for more details (i.e., svn commands, python build commands, etc).
  • Create a Windows XP VM in VMWare Workstation, including VMware tools in the guest
  • Configure the target VM to have a VMWare shared folder from the host
  • Install slikSVN (Slik-Subversion-1.7.2-win32.msi)
  • Install 7zip (7z920.exe)
  • Install minGW, but use an older version (mingw-get-inst-20110802.exe) to avoid gcc bug encountered by teammate
  • Check box for C++ compiler
  • Install winpcap (WinPcap_4_1_2.exe)
  • Install winpcap developer's pack (WpdPack_4_1_2.zip)
  • Install Python 2.7 (python-2.7.2.msi)
  • Install libdasm (svn co the trunk)
  • Install install pcapy (pcapy-0.10.5.zip)
  • Install install Impacket (Impacket-0.9.6.0.zip)
  • Install IDA Free 5.0 (ideafree50.exe)
  • Install idapython (idapython-1.5.3_ida6.2_py2.7_win32.zip)
  • Install PaiMei (svn co the trunk)
  • Fix pydasm libs (they get clobbered by paimei install)
  • del c:\python27\lib\site-packages\pydasm.pyd
    del c:\python27\lib\site-packages\pydbg\pydasm.pyd
    cd z:\install_files\libdasm-read-only\pydasm
    python setup.py install
  • NOTE: If you see an error message when running Sulley saying something like pdbg can't load pydasm module, try executing these steps again
  • Install Sulley (svn co the trunk) - this goes in the shared folder!
  • Install Process Hacker (processhacker-2.27-setup.exe)
  • Install Immunity Debugger (ImmunityDebugger_1_83_setup.exe)
  • Install WireShark (wireshark-win32-1.6.5.exe)
  • Test Sulley.  Once everything works, TAKE A SNAPSHOT.

Like I said, installing Sulley can be a bit of a PITA.  My host is running 64-bit Ubuntu.  I already had python 2.6.5 installed, so all I needed to add was pcapy.  I also used ipython when debugging the Sulley script (see below).

Prepping the Target


Now that we have the target VM ready to go, you'll need to install and execute your target application, with the Sulley monitors.  Just for grins, I chose to work against Poison Ivy.  The client (listener) part of PIVY is started using the GUI.  This meant that I could not just use the Sulley process_monitor.py script to restart the application if/when a crash occurred (because PIVY would not be put back into listen mode).  I executed the following steps to prep the target VM
  • Stop the Windows Firewall
  • Start Poison Ivy
  • Put PIVY into listen mode (start a client)
  • Open two command prompts (cmd.exe)
  • Command prompt 1, start the process_monitor.py from the shared folder
  • cd z:\sulley\sulley_read_only
    python process_monitor.py -c audits\pivy.crashbin -p "Poison Ivy 2.3.2.exe" -l 5
  • Command prompt 2, start the network_monitor.py from the shared folder
  • cd z:\sulley\sulley_read_only
    python network_monitor.py -d 0 -f "src or dst port 3460" -P audits\pivy -l 5
  • Take a snapshot, and give it a short name that you will remember

Modifying Sulley

Sulley includes a script called vmcontrol.py that it can use to start and reset a target VM.  Unfortunately, the script failed to run on my 64-bit Linux system right out of the box. However, I only needed to make the minor changes listed below to get things up and running:

vmcontrol.py diff
340c340
<     if not os.name == "nt" and interactive:
---
>     if not os.name == "nt":
sulley/pedrpc.py diff
13,14c13
<         #self.NOLINGER         = struct.pack('HH', 1, 0)
<         self.NOLINGER         = struct.pack('ii', 1, 0)
---
>         self.NOLINGER         = struct.pack('HH', 1, 0)
Once those changes were made, I was able to execute the following to get vmcontrol.py to control the target VM:

./vmcontrol.py --vmrun=/usr/bin/vmrun --snapshot=sulley-pivy --vmx=/vmware/xp.vmx --log_level=5

Sulley Fuzzing Files

Finally, I created a fuzzing request file and a fuzzing controller file.  Since the target was the network daemon for PIVY, I chose to start by just fuzzing a block of 256 bytes.  I ran into an issue with documentation at this point - many of the documents out there for Sulley indicate the s_binary() primitive is fuzzable.  However, for my installation of Sulley, s_binary() is NOT fuzzable.  I had to switch to s_random() and set the min and max parameters the same.  I determined s_binary() was not fuzzable by looking at the Python help docs in ipython:
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
Type "copyright", "credits" or "license" for more information.

IPython 0.10 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: from sulley import *
sulley/blocks.py:7: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha

In [2]: help(s_binary)

Help on function s_binary in module sulley:

s_binary(value, name=None)
    Parse a variable format binary string into a static value and push it onto the current block stack.
    
    @type  value: String
    @param value: Variable format binary string
    @type  name:  String
    @param name:  (Optional, def=None) Specifying a name gives you direct access to a primitive
The fuzzing controller script needs to setup the vmcontrol member of the target object and then set the VM to the proper snapshot before starting the fuzzing session.  The two files I used are listed below:

requests/pivyreq.py
from sulley import *

s_initialize("main")

s_random("187ad46c3d78cd68b54994a93f5a153bfce2e92ebab84688ecde05bb49bb70f91de3796e08a3514994c96fda1e61160e6659a2152f0f1452042b5620c685142603a12321d4cd20babb016680e725c5b6b478a235e56628607b50a84d7e3437053e7cc7f9dd9b51bc539787ea10e075de58a5cec089270a8b0a7e7814f280ad7206eb0f27dda946cd87f15a11a79119f1a578f9b3a5edd06eac5b078b0a794798bfecf3afe250082d96c181474ac49366e54ec2acbc4f6e46898006596544b8b5b7cb3abc09a8ef1860877e182787911c0cd3fc0a36eeeb34ded41a1c9a9efcd648a7fa5ee7e5d337e8052a86e729ff6ce2fffbb3fb40936a8615ecb20bc84772",256,256)
pivy.py
from sulley import *
from requests import pivyreq

print "Instantiating session"
sess = sessions.session(session_filename="pivytest.session")

print "Instantiating target"
target = sessions.target("172.16.147.128", 3460)
target.netmon = pedrpc.client("172.16.147.128", 26001)
target.procmon = pedrpc.client("172.16.147.128", 26002)
target.vmcontrol = pedrpc.client("172.16.147.1",26003)

target.procmon_options =  {
 "proc_name" : "Posion Ivy 2.3.2.exe",
}

target.vmcontrol.restart_target()
print "Virtual machine up and running"

sess.add_target(target)

sess.connect(sess.root, s_get("main"))

print "Starting fuzzing now"
sess.fuzz()
After you have all the agents running, just run pivy.py from the sulley directory and watch the magic. Now, if you actually replicate this test, you'll see the fuzzing does not accomplish much. Andrzej Dereszowski wrote a nice paper explaining an effective way to fuzz PIVY, which you can download at http://www.signal11.eu/en/research/articles/targeted_2010.pdf

List of Resources

No comments:

Post a Comment

Installing Older Versions of VeraCrypt on Linux: A Step-by-Step Guide

Introduction: During some house cleaning I had an old external drive that was encrypted with an old version of truecrypt. I wanted to mount...