Sulley Fuzzing Framework Intro
1. Sulley Fuzzing Framework
Sulley is python fuzzing framework that can be used to fuzz file formats, network protocols, command line arguments, and other codes. In this three-part series, we'll learn how to fuzz a threaded TCP server application called Vulnserver using a Sulley fuzzing framework. In this first article, we'll outline the correct steps for installing Sulley on a Linux and Windows OS. : http://grey-corner.blogspot.com/2010/12/introducing-vulnserver.html.
What should you learn next?
What should you learn next?
A more detailed explanation can be found in the user manual accessible here. Without going into all the details in the user manual, there are some basics that we need to know. When fuzzing with Sulley, we need to write a python script that defines all required objects that Sulley needs in order to fuzz specific target. Those objects are:
- a. Data Model: data model defines the properties of the network protocol that we're going to fuzz. Example of FTP protocol: data model should define the structure of all possible FTP commands.
- b. State Model: state model is used to define possible interactions between different states of the fuzzed network protocol. Example of FTP protocol: state model should state that at first, we're only allowed to enter a few commands to authenticate to the FTP server, like USER and PASS commands. After we're authenticated, more commands become available, therefore we're changing the state from non-authenticated to authenticated.
- c. Target: target defines what we're going to fuzz. Example of FTP protocol: here we should specify the IP and port of the FTP server we'll be fuzzing.
- d. Agents: agents are special programs running on the target computer, which do various things, amongst others are: monitoring the fuzzed process for crashes, intercepting the relevant network packets, restarting the crashed process, etc.
- e. Monitoring Interface: monitoring interface allows us to easily see the result of fuzzing process, how many of the test cases were already sent, how many of them caused a crash, etc.
2. Installing Sulley
Sulley depends upon a Paimei reverse engineering framework, which Sulley needs in order to debug the fuzzed application. Since Paimei has a lot of dependencies of its own, we have to install those first. But let's present all of the Paimei dependencies first:
- ctypes: provides C compatible data types and allows calling functions in DLLs or shared libraries.
- pydot: facilitates easy creation of both directed and non-directed graphs from Python.
- wxPython: GUI toolkit for Windows and Unix with native look and feel on each platform.
- MySQLdb: a thread-compatible interface to the popular MySQL database server that provides the Python database API.
- GraphViz: can be used to produce both directed and undirected graphs.
- Oreas GDE: provides a mechanism for editing and automatically laying out diagrams, which are represented in form of graphs and cluster graphs.
- uDraw: automates the task of creating flowcharts, diagrams, etc.
It's also worth mentioning that Paimei provides a really great library called PyDbg, which has a pure-python win32 debugger interface. It can be extended to provide a cross-platform debugging API across both Windows and Linux.
In addition to Paimei, Sulley depends upon the following libraries:
- pcapy: a python library that knows how to capture packets
2.1. Installing Sulley on Linux
We'll install Sulley on Ubuntu distribution of Linux system, more precisely on version 10.10. Other Linux users can follow the same instructions, as they are basically the same since we're performing most of the steps manually.
[bash]
# apt-get install python-ctypeslib python-pydot python-wxgtk2.8 python-mysqldb python-pygraphviz
If you want to install those dependencies on Gentoo, use the following command:
[bash]
# emerge dev-python/ctypesgen media-gfx/pydot dev-python/wxpython dev-python/mysql-python dev-lang
Then we need to download Paimei from: http://www.openrce.org/downloads/details/208 and extract it. After download, we need to run __install_requirements.py to check and install all needed requirements that are not already present. In the previous step we didn't actually install all the requirements, just some of the needed ones, so we'll have to do less manual work now. The __install_requirements.py script checks which requirements are missing from the system and tries to install them. Unfortunately this automated check is not always successful, so we will have to do some manual work.
[bash]
# python __install_requirements.py
looking for ctypes ... FOUND
looking for pydot ... FOUND
looking for wxPython ... FOUND
looking for MySQLdb ... FOUND
looking for GraphViz in default directory ... NOT FOUND
looking for Oreas GDE in default directory ... NOT FOUND
Want me to get it? y
downloading ... 100%
start: Unknown job: installers/gde-win.exe
looking for uDraw(Graph) in default directory ... NOT FOUND
Want me to get it? y
downloading ... 100%
start: Unknown job: installers/uDrawGraph-3.1.1-0-win32-en.exe
looking for PaiMei -> PyDbg ... NOT FOUND
looking for PaiMei -> PIDA ... FOUND
looking for PaiMei -> pGRAPH ... FOUND
looking for PaiMei -> Utilities ... NOT FOUND
Install PaiMei framework libraries to Python site packages:
: Unknown job: installers/PaiMei-1.1.win32.exe
Hit enter to exit installer.
[/bash]
We can see that some dependencies were found, while others were downloaded manually by the python script. The installation script is asking us to run the __setup_mysql.py script next, which is required by the Paimei, and I don't intend to skip it. First we need to install the mysql database, which we can do with the command below. The installation process will ask us to setup a root password, which we've set to adminpass:
[bash]
# apt-get install mysql-server
After that, the mysql is up and running and we can run the __setup_mysql.py command:
[bash]
# python __setup_mysql.py localhost root adminpass
At the end let's install the Paimei libraries to the system, so they'll be fully accessible by all system programs:
[bash]
# python setup.py build
# python setup.py install
This will also install ctypes into directory /usr/local/lib/python2.6/dist-packages/pydbg/. If you get any error when running Sulley regarding ctypes, you can find a resolution here: http://code.google.com/p/paimei/issues/detail?id=3. You probably need to change my_ctypes.py and recompile it, like this:
[bash]
# vim /usr/local/lib/python2.6/dist-packages/pydbg/my_ctypes.py
# python /usr/local/lib/python2.6/dist-packages/pydbg/my_ctypes.py
But we can also install ctypes manually with the command below—it depends on the version of ctypes whether this will work or not:
[bash]
# apt-get install python-setuptools
# easy_install ctypes
Afterwards, we can launch the Paimei GUI to check if everything is working:
[bash]
# python consolePAIMEIconsole.py
We also need to install pcapy, which facilitates the packet-capturing capability of the Sulley fuzzing framework. Pcapy is a python library that knows how to capture packets; it works with both LibPcap, on Unix, and WinPcap, on Windows. To install it, we need to run the following command:
[bash]
# apt-get install python-pcapy python-impacket
After the Paimei is installed and all other dependencies are installed, we can download the Sulley fuzzing framework by cloning the git repository and utilizing it, no additional installation is required. To download the Sulley fuzzing framework, issue the following command:
[bash]
# git clone https://github.com/OpenRCE/sulley.git
# cd sulley
To check whether Sulley is working we can issue the following two commands that are used for monitoring the process and intercepting the network traffic when fuzzing the target process. Note that those two commands should run without errors:
[bash]
# python process_monitor.py
ERR> USAGE: process_monitor.py
<-c|--crash_bin FILENAME> filename to serialize crash bin class to
[-p|--proc_name NAME] process name to search for and attach to
[-i|--ignore_pid PID] ignore this PID when searching for the target process
[-l|--log_level LEVEL] log level (default 1), increase for more verbosity
[--port PORT] TCP port to bind this agent to
[bash]
# python network_monitor.py
ERR> USAGE: network_monitor.py
<-d|--device DEVICE #> device to sniff on (see list below)
[-f|--filter PCAP FILTER] BPF filter string
[-P|--log_path PATH] log directory to store pcaps to
[-l|--log_level LEVEL] log level (default 1), increase for more verbosity
Network Device List:
[0] usbmon1
[1] eth2
[2] usbmon2
[3] any
[4] lo
We can also see the official help pages of both process_monitor.py and network_monitor.py python scripts.
2.2. Installing Sulley on Windows
As on Linux, we must first install the Paimei reverse engineering framework. To do this, we must follow the same instructions we used to install the Linux version. First, install the dependencies with __install_requirements.py python script. If we're not on a 32-bit Windows system and don't have Python 2.6 installed, this script won't work. That's why we'll do most of the work manually. First we must download Python 2.6 or Python 2.7, which version we choose depends totally upon us. Afterwards, we need to download a wx-Python from: http://wxpython.org/download.php and choose the appropriate version based on whether we have a 32-bit or 64-bit Windows system, and 2.6 or 2.7 Python installed.
Then we must download Paimei from: http://www.openrce.org/downloads/details/208 and extract it in the C: directory. After that, we need to navigate to the Paimei directory and execute the following commands, which will install ctypes, pydot, wxPython, MySQLdb, Graphviz, Oreas GDE and uDraw(Graph):
[bash]
# python __install_requirements.py
# python __setup_mysql.py localhost root adminpass
At the end, let's install the Paimei libraries to the system, so they'll be fully accessible by all system programs:
[bash]
# python setup.py build
# python setup.py install
But this command won't install all of the required dependencies, as some of them may fail. This is why we need to install them manually. First, we must download python-mysql from this site http://www.codegood.com/archives/4. Again, we must choose the right version from several possible selections. Of course, we must already have a mysql database setup, but we won't get into too much detail on how to do that here.
To install ctypes, we need to download and run ez_setup.py from: http://www.blogger.com/blogger.g?blogID=1379343792811810854#editor/target=post;postID=5754137995648109428. Then we need to run the script in order to install the easy_install.exe into the C:/Python2.7/Scripts/ subdirectory, which we must also add into the PATH environmental variable.
[bash]
C:/> python ez_setup.py
To actually install ctypes, run the following command:
[bash]
C:> easy_install ctypes
If we get an error about Msvcr71.dll not being found, we must download it and save it under C:/Windows/System32/ directory. This is a Microsoft C Runtime Library file, which must be present because the Paimei application uses it. We can download it from http://www.dll-files.com/. After the installation, Paimei will be installed into the C:/Python2.7/Lib/site-packages/ directory.
We also need libdasm, which we'll download from: http://code.google.com/p/libdasm/ and extract it to C: directory. But before we can compile it, we must install MinGW. We can do this with the mingw-get executable, which can be downloaded manually.
[bash]
C:MinGWbin> mingw-get install gcc g++ mingw32-make
This will download and install all the required libraries and programs to make MinGW fully functional. Afterwards, we'll be able to run commands like: gcc, g++, ming32-make, etc.
If we receive an error about an unrecognized command line option -mno-cygwin, we need to edit the file C:/Python2.7/Lib/distutils/cygwinccompiler.py and remove all occurrences of -mno-cygwin and recompile it with:
[bash]
C:Python2.7Libdistutils> python C:/Python2.7/Lib/distutils/cygwinccompiler.py
When MinGW is installed, we can begin compiling and installing libdasm. Be sure to also add C:/MinGW/bin/ directory into system PATH environmental variable, so that the gcc command can be found.
[bash]
C:> cd C:libdasm-1.5pydasm
C:> python setup.py build -c mingw32
C:> python setup.py install
This will install libdasm into the folder C:/Python2.7/Lib/site-packages. For other python scripts to be able to find the folder, we need to create another system environment variable called PYTHONPATH. This variable must be set to C:/Python2.7/Lib/site-packages/, so the python interpreter will also look into directories specified by that variable to find all required modules.
We also need to remove the pydasm.pyd module that was already installed by Paimei in the C:/Python2.7/Lib/site-packages/pydbg/pydasm.pyd. Otherwise python will try to use the original module, and this will result in an error. If we remove that module, python will skip from that directory to the next, finding our newly compiled libdasm.pyd module, which loads successfully.
If we want to capture packets on a network, we also need to install pcapy, which is a python library that knows how to capture packets. It works with both LibPcap on Unix and WinPcap on windows. We need to download and install winpcap and lmpacket, which pcapy depends upon. To install pcapy, download it from: http://breakingcode.wordpress.com/2010/04/02/using-impacketpcapy-with-python-2-6-on-windows/ and then execute the following commands:
[bash]
C:> cd pcapy-0.10.5
C:pcapy-0.10.5> python setup.py build
We'll receive an error that states: the file pcap.h cannot be included because it doesn't exist. This file is part of the WinPCAP's developer pack, which we can download here: http://www.winpcap.org/install/bin/WpdPack_4_1_2.zip. After unzipping it into C: directory, we can find the missing header file by rerunning the pcapy installation as outlined below:
[bash]
C:pcapy-0.10.5> python setup.py build_ext -I "C:WpdPackInclude" -L "C:WpdPackLib"
C:pcapy-0.10.5> python setup.py install
Now that all dependencies are installed, we only need to download, extract, and run Sulley. If an error occurs when running the following commands from the Sulley directory, we didn't correctly install one of the required dependencies:
[bash]
C:> cd C:sulley
C:sulley> python process_monitor.py
ERR> USAGE: process_monitor.py
<-c|--crash_bin FILENAME> filename to serialize crash bin class to
[-p|--proc_name NAME] process name to search for and attach to
[-i|--ignore_pid PID] ignore this PID when searching for the target process
[-l|--log_level LEVEL] log level (default 1), increase for more verbosity
[--port PORT] TCP port to bind this agent to
[/bash]
[bash]
c:sulley>python network_monitor.py
ERR> USAGE: network_monitor.py
<-d|--device DEVICE #> device to sniff on (see list below)
[-f|--filter PCAP FILTER] BPF filter string
[-P|--log_path PATH] log directory to store pcaps to
[-l|--log_level LEVEL] log level (default 1), increase for more verbosity
Network Device List:
[0] {6534DA26-C362-4A35-B745-4B315BD564A3} 192.168.1.126
What should you learn next?
What should you learn next?
We've seen that installing Sulley is not an easy task, but it's worth it. In the next article we'll get down to business—we'll download and install a specifically-built server application Vulnserver (accessible here: http://grey-corner.blogspot.com/p/vulnserver.html) and fuzz it with Sulley fuzzer.