Sploit Mutation Framework
User Guide
Version 0.2.4


Introduction
How to install Sploit
How Sploit works
Attack setup
Running Sploit from the command line
Graphical interface


Introduction

Sploit has been developed as a framework for testing network intrusion detection systems. The Sploit core is an engine that is able to automatically apply a number of transformation to an exploit script, generating an high number of attack mutants that can then be used to test the detection capabilities of a given NIDS.

How to install Sploit

The Sploit installation is just a matter of extracting the files from the tarball and move under the Sploit directory. There you can find a doc/ subdir (containing the documentation) and a code/ subdir (containing the framework code).
Since Sploit is written in Python, you need a Python 2.4 interpreter on your computer in order to be able to run the program. You can choose between two different interfaces: the traditional command line interface (sploit.py) and a nice Qt graphical interface (sploit-gui.py). For the second one, you need to install the python-qt libraries.
So far, Sploit have been tested only on a Linux machine.

How Sploit works

In this section we briefly sketch everything you need to know in order to use Sploit (for a more detailed description of individual components, please refer to the Developer Guide).


Sploit Framework Architecture


The attack template is written in a python script using the libraries provided by the Sploit framework. Each library provides a number of hooks where one or more transformation functions (implemented in what we call Mutant Operators) can be registered to modify the attack execution.
In order to allow the mutant operators to work at network and transport layers, Sploit provides a user-space TCP/IP stack that provides the necessary hooks. However, since this component is still highly experimental, the user can decide to enable the userland stack or to rely on the more stable network stack provided by the operating system (losing the ability to modify the attack at the packet layer).
An ordered list of mutant operators (with the possible values that each parameter can assume) defines the Mutation Space. The algorithm used to explore such a space is written in a mutant factory object. It is the mutant factory that decides which mutant operators (and with which parameters values) must be applied to generate a given mutant. After a mutant has been executed, the intrusion detection alerts should be collected and correctly correlated with the attacks. This action is performed by one or more alert Collectors.

The Sploit Engine takes care of putting everything together in a complete and easy to use testing environment.
We can briefly summarize the whole process as:

Attack setup

The first step in the setup phase consists in selecting the attack you want to execute. Sploit comes with some exploits scripts in the code/exploits directory. In this guide we assume that the user just want to execute a pre-existing exploit (if you are interested in developing your own attack or in translating an exploit to work with Sploit, please refer to the Developer Guide).
The exploit script contains both the attack and the oracle code. All the other configuration options (such as the list of mutant operators, the network setup, the mutant factory and so forth) must be saved in a different configuration file. There are three ways to generate a configuration file for an attack: load the exploit in the graphical interface and press the Save Configuration button, use the create-conf command line script, or simply using your favorite text editor to manually create the text file.
A configuration file must contain four sections: [Exploit], [Network], [Factory], and [Operators]. Every parts must be present, even if empty. Blank lines are ignored and comments can be inserted starting the line with a "#" character. There are two different kind of options: single line options and multi-line options. A single line option is a couple keyword-value separated by either a "=" or a ":" character. Any space at the beginning and at the end of the line are ignored.
Multi-line options provide a way to group together multiple single-line options between curly brackets in the following form:
 option-name = {
   sub-option-1
   sub-option-2
   ....
   sub-option-n
  }

Here is the complete keyword list:

Exploit Section
script mandatory single-line Tell the engine which python file contains the exploit.
It accepts both .py and .pyc files.
Example:
script = ./exploits/ping_of_death_.py
   
parameters optional multi-line Set one or more exploit parameter values.
Example:
parameters = { 
 parA = 'this is a string'
 parB = 55
}
   
Factory Section
script optional single-line Tell the engine which python file contains the mutant factory code.
It accepts both .py and .pyc files.
Example:
script = /usr/local/sploit/factories/one.py
Network Section
userland_stack mandatory single-line Enable or disable the userland TCP/IP stack.
Possible values are [On] and [Off].
Example:
userland_stack = Off
target mandatory multi-line Set the IP address of the target machine.
Example:
target = {
 ip = 10.10.10.2
}
source mandatory if the userland stack is enabled. Ignored otherwise. multi-line Set the IP and MAC address of the fake source machine.
Example:
source = {
 ip = 10.10.10.2
 mac = 44:55:66:77:88:99
}
  
iface mandatory if the userland stack is enabled. Ignored otherwise. single-line Set the network interface that will be used to simulate the fake source machine
Example:
iface = Eth1


The [Operators] section contains a list of options, one for each mutant operator that must be loaded. Each line can be either a single or a multi-line option. In the first case,it just specifies the name of the operator. If the user want to set one or more operator parameters, he can use a multi-line option. In this case, each sub-option has the form: PARAMETER_NAME = ACTUAL_VALUE. After the actual value it is possible to add, between square bracket, a comma separated list of available values.

The following example should clarify the idea.
prompt> ./cat conf/imap-lsub.cfg
[Exploit]
    script = ./exploits/final/imap-lsub.pyc
    parameters = {
        PASSWD = 'bar'
        PLATFORM = 'RedHat    6.2(ZooT) - IMAP4rev1 v12.264'
        CMD = 'cat /flag.txt'
        USER = 'foo'
        RESULT = 'well done'
    }

[Network]
    iface = vmnet8
    userland_stack = False
    target = {
        ip  = 10.10.0.103
    }

[Factory]
    script = ./factories/OneFactory.pyc

[Operators]
    IMAP-CmdSeparator 
    
    LongTag = {
        LEN = 40
    }
    
    IMAPCmd-ChangeCase
    
    WeirdTag = {
        CHAR = '\tNOOP'  ['\tNOOP', ',.', '"a"', '{12}']
    }
    
    LiteralLengthObfuscator

The IMAP-CmdSeparator mutant operator has been selected with the defaults values. LongTag has been selected with the parameter LEN equal to 40. And finally, the CHAR parameter of the WeirdTag operator has been set to "\tNOOP" while the other available values are ",.", "a", and "{12}".

Running Sploit from the command line

In order to avoid passing tons of parameters, the command line interface requires a configuration file as a mandatory parameter.
Let's try running Sploit with the following options:
prompt> ./sploit.py --info conf/imap-lsub.cfg

==================================================
Exploit name: Wu-imapd lsub bo
Target address: 10.10.0.103
Exploit Parameters:
  PASSWD = bar
  PLATFORM = RedHat    6.2(ZooT) - IMAP4rev1 v12.264
  CMD = cat /flag.txt
  USER = foo
  RESULT = well done
==================================================
Mutant Factory: One at the time
Number of mutants: 8
==================================================
Mutation space size: 80
Operators:
 [IMAP Layer] - IMAP-CmdSeparator
 [IMAP Layer] - LongTag
 [IMAP Layer] - IMAPCmd-ChangeCase
 [IMAP Layer] - WeirdTag
 [IMAP Layer] - LiteralLengthObfuscator
==================================================

Using the --info (or just -i) options Sploit prints all the attack details and configurations options. In this case, no mutant are actually executed. Anyway, as you can see, the current mutation factory is going to generate only 8 of the 80 mutants in the mutation space. Most of the configuration file options can be overwritten using some of the command line parameters. For instance, we can change the mutant factory and the target address using:
prompt > ./sploit.py --dest 10.10.10.101 --factory factories/NullFactory.pyc -i conf/imap-lsub.cfg 
==================================================
Exploit name: Wu-imapd lsub bo
Target address: 10.10.10.101
Exploit Parameters:
  PASSWD = bar
  PLATFORM = RedHat    6.2(ZooT) - IMAP4rev1 v12.264
  CMD = cat /flag.txt
  USER = foo
  RESULT = well done
==================================================
Mutant Factory: Null Factory
Number of mutants: 1
==================================================
Mutation space size: 80
Operators:
 [IMAP Layer] - IMAP-CmdSeparator
 [IMAP Layer] - LongTag
 [IMAP Layer] - IMAPCmd-ChangeCase
 [IMAP Layer] - WeirdTag
 [IMAP Layer] - LiteralLengthObfuscator
==================================================
Ok, now it is time to execute the mutants against the target and see what happens.
prompt > ./sploit.py -r 0 conf/imap-lsub.cfg 
 Mutant 0 (0/1)        -->    OK
The -r parameter followed by a number N tells the engine to execute the mutant number N. It is possible to launch all the mutant (using -r all) or just a subset of them specifying a range of values:
prompt > ./sploit.py -r 0:2 conf/imap-lsub.cfg
 Mutant 0 (1/3)        -->    OK
 Mutant 1 (2/3)        -->    OK
 Mutant 2 (3/3)        -->    OK
For each attack, Sploit prints the execution results and saves all the other details in a log file. By default, Sploit create a directory using the execution time-stamp in the current directory and place inside it a log file for each mutant. It is possible to change the root log directory using the --log option:
prompt > ./sploit.py --log ./logs/ -r 0:2 conf/imap-lsub.cfg
 Mutant 0 (1/3)        -->    OK
 Mutant 1 (2/3)        -->    OK
 Mutant 2 (3/3)        -->    OK

prompt > ls logs/25-Sep-2005_14.14.12/
0.log  1.log  2.log  

prompt > cat logs/25-Sep-2005_14.14.12/1.log
Mutant #1
TCP Port: 2001
Execution Date: Thu, 25 Sep 2005 12:14:15
Execution Time: 2
Attack Result: 1
-------------------[ Mutant Operators ]--------------------
o LongTag
    LEN = 40
----------------------[ Log Messages ]----------------------
The log files contain the mutant details, including the list of mutant operators with their parameters, and all the log messages generated during the attack execution. In the previous case the log section is empty because the default threshold is very high (only the error message are logged)
We can raise the log level using the -v option.
prompt > ./sploit.py -v DEBUG --log ./logs/ -r 0:2 conf/imap-lsub.cfg
-[ENGINE]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:13]-
Mutant Factory sets to: NullFactory.NullFactory
-[OP-MANAGER]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
24 mutant operators loaded
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
Loading configuration from file conf/nuovo2.cfg
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
./exploits/final/imap-lsub.pyc
exploit loaded
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
Target host: 10.10.0.103
-[ENGINE]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:13]-
Mutant Factory sets to: OneFactory.OneAtTheTimeFactory
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
Target host: 10.10.0.103
Mutant 0 (0/3)        -->    
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:13]-
Starting execution of imap-lsub.ImapLSUB instance at 0xb7b17a6c
(mutants from 0 to 3)
OK
Mutant 1 (2/3)        -->    OK
Mutant 2 (3/3)        -->    OK


prompt > cat logs/29-Sep-2005_14.14.12/1.log
Mutant #1
TCP Port: 2001
Execution Date: Thu, 29 Sep 2005 12:41:15
Execution Time: 2
Attack Result: 1
-------------------[ Mutant Operators ]--------------------
o LongTag
    LEN = 40
----------------------[ Log Messages ]----------------------
-[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Setting up mutant # 1
 -[ENGINE]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
1 mutant operators selected
 -[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Starting mutant execution (attempt 0)
 -[EXPLOIT]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Sending login...
 -[IMAP]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Open Connection to port 143
 -[Socket (python tcp)]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
connected to 10.10.0.103 port 143
 -[IMAP]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Banner: * OK [10.10.0.103] IMAP4rev1 v12.264 server ready
 -[IMAP]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Apply Imap Filters
 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
Sending...a2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LOGIN foo bar
 -[EXPLOIT]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Logged-in.
Sending the shellcode...
 -[IMAP]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Apply Imap Filters
 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
Sending...a3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LSUB "" {1064}
 -[EXPLOIT]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Resp:  + Ready for argument
 -[EXPLOIT]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Sending shellcode...
 -[EGG]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Base Egg: 919 nops - 45 shellcode len - 25 return address
 -[EGG]--[INFO]--------[Thu, 29 Sep 2005 12:41:15]-
Appling EGG Filters...
 -[EGG]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
NOP:
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90
\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90

 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
Sending 1064 byte of raw data
 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
Sending 1 byte of raw data
 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:15]-
Sending 1 byte of raw data
 -[EXPLOIT]--[INFO]--------[Thu, 29 Sep 2005 12:41:17]-
Sending shell command: cat /flag.txt
 -[IMAP]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:17]-
Sending 14 byte of raw data
 -[EXPLOIT]--[DEBUG]--------[Thu, 29 Sep 2005 12:41:17]-
Response:
' well done'
 -[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:17]-
Mutant execution terminated

Starting oracle interrogation...
 -[ENGINE]--[INFO]--------[Thu, 29 Sep 2005 12:41:17]-
Oracle result 1

Nice. Now we have all the information about every action performed during the attack. Each log message is preceded by an header that contains the log source, the log level and the time-stamp. It is also possible to set different verbosity level for different sources. For instance, if we are not interested in the messages generated by the engine but we want to log everything else we can use: -v DEBUG -v ENGINE:ERROR.

So far we have never collected the IDS alert. For the next example, we suppose to have snort properly configured and running on the local machine.
prompt > ./sploit.py conf/imap-lsub.cfg -r 0:2  --log ./logs/ 
 --collector collectors/snort-local.pyc
After the execution, the log directory contains some new files. For each mutant there is a .snort file that contains the alert generated by snort during the execution. If for some reason the alert collector find some alerts that it is not able to correctly correlate to a particular mutant, it places such messages in a file named uncorrelated.snort.
 
prompt > cat logs/29-Sep-2005_15.17.19/0.Snort

[**] [1:1902:9] IMAP lsub literal overflow attempt [**]
[Classification: Misc Attack] [Priority: 2] 
09/29-15:17:19.790286 10.10.0.1:2000 -> 10.10.0.103:143
TCP TTL:64 TOS:0x0 ID:36725 IpLen:20 DgmLen:71 DF
***AP*** Seq: 0x26DE9019  Ack: 0x967F4752  Win: 0x5B4  TcpLen: 32
TCP Options (3) => NOP NOP TS: 17047462 614922 
[Xref => http://cgi.nessus.org/plugins/dump.php3?id=10374][Xref =>
http://cve.mitre.org/cgi-bin/cvename.cgi?name=2000-0284][Xref =>
http://www.securityfocus.com/bid/1110]
Finally, suppose you want to execute the same attack fragmenting the IP packets in chunks of forty bytes each. First of all you need to enable the userspace TCP/IP stack, changing the [Network] section in the configuration file:
[Network]
 iface = vmnet8
 userland_stack = True

 target = {
   ip  = 10.10.0.103 
   mac = 00:0C:29:6E:D0:F9
 }

 source = {
   ip  = 10.10.0.107
   mac = 00:AA:BB:CC:11:A0
 }
The source block defines the virtual host parameters. When the userspace stack is enabled, Sploit needs to be able to control every single packets sent or received by the exploit script. This would not be possible due to conflicts with the operating system network stack. In order to avoid the problem, Sploit simulates a phantom host with IP address 10.10.0.107 (that must be an unused address to avoid collisions) and MAC address 00:AA:BB:CC:11:A0. Of course, creating and managing the virtual host requires root privileges on the attacker machines.

The next step consists in enabling the IpFragmenter mutant operator in the [Operator] section:
[Operators]
  IPFragmenter = {
    size = 40
 }
And now you can execute Sploit from a root prompt:
root prompt > ./sploit.py --log ./logs/ -r 0 conf/imap-lsub.cfg
Important Note: if you execute multiple time in a row the same exploit, to avoid possible conflicts you need to change the TCP port used to initiate the connection (by default it starts from 2000). The source port can be set through the --port option (it is also possible to tell the engine to choose any time a random number using --port random)

The Graphical Interface

The Qt-based graphical user interface provides a nice point-and-click way to control the Sploit engine. It can also be useful to create configuration files that can then be used with the command line interpreter. To launch the graphical interface move to the code directory and run ./sploit-gui.py. The left side of the window contains an icon bar where each icon represent one of the 5 program section: (1) exploit configuration window, (2) network configuration window, (3) mutant operators window, (4) alert collectors window, and (5) execution window.

Let's start with the exploit window. The three buttons at the bottom allows the user to load an exploit script or load and save a configuration file. When an exploit script is loaded, the main part of the window shows the exploit description and the bottom part displays the list of attack parameters. Each parameter value can be modified just clicking on it.

Sploit Main


Clicking on the network icon will show the network configuration window. Here you can set up the IP address of the target machine.
In case you want to use the userspace TCP/IP stack, you need to tick the check-box (you must be root since it must be able to sniff the network in promiscuous mode) , configure the IP and MAC address of the fake host, and press the "Create Virtual Host" button to start the daemon.

Sploit Main


The mutant operators and alert collectors windows are very similar. Both have a main list view where you can check which components you want to enable. On the bottom part, a grid control allows you to configure the selected operator (or alert collector).

Sploit Main


Finally, the execution window provides

Sploit Main


Clicking on one of the row, shows a windows that summarize all the execution details:

Sploit Main