dizzy

dizzy is a fuzzing framework, written in python and capable of state-full and state-less fuzzing with a lot of output options.

usage

$dizzy_cmd version 2.0 running on Linux
usage: dizzy_cmd [-h] [-s START_AT] [-d SEC] [-l] [-o OPTIONS] [jobfile]

positional arguments:
  jobfile

optional arguments:
  -h, --help   show this help message and exit
  -s START_AT  Start at the given step
  -d SEC       Output status every SEC seconds
  -l           List all loaded modules and their contents.
  -o OPTIONS   Overwrite a config option

A jobfile is all that is needed. The -s START_AT option can be used to start the fuzzing process at a given step and skip all previous steps. The -d SEC option configures the output interval of progress messages and using the -o OPTIONS parameter, config values from the jobfile can be overwritten.

jobfile

The Job Configfile contains all information necessary to start a fuzzing job

The [job] section defines which interaction file (state-full fuzzing) or which dizz file (state-less fuzzing) to use, the fuzzing mode and other parameters, like verbosity or the delay between mutations.

The [output] section defines were to send the generated data. The only common parameter is the type parameter, defining which session module to use. All other parameters in this section are session module dependent.

In the optional [probe] section a target probe can be defined. The probe runs after each complete fuzzing step and checks if the target is still available.

In the optional [value] section, generic values can be defined. Those values will be available to .dizz and .act files via the config_value function.

[job]
file = smb2/act/smb2_tree_connect.act
mode = none
delay = 0
verbose = 4

[output]
type = session.tcp
server = False
auto_reopen = False
session_reopen = True
timeout = 5
target_host = 127.0.0.1
target_port = 445

#[probe]
#type = icmp
#timeout = 1
#pkg_size = 64
#target_host = 192.168.2.1

[values]
creds_file = ./creds
share_path = \\127.0.0.1\test

module structure

Modules are created from the modules_src folder. A Makefile is provided that generates the __init__.py index files and packs the module zip files. To update the modules run make in the modules_src folder:

~/dizzy/modules_src# make

to the generated index files, run make clean in the modules_src folder:

~/dizzy/modules_src# make clean

In the modules_src folder, every module has an own folder, named the same as the module. Each module folder has the following structure:

As a example the structure of the smb2 module is shown:

~/dizzy/modules_src# tree smb2
smb2
├── config.py
├── __init__.py
└── smb2
    ├── act
    │   ├── smb2_file_access_read.act
    │   ├── smb2_file_access_write.act
    │   ├── smb2_neg_setup_auth.act
    │   └── smb2_tree_connect.act
    ├── deps
    │   ├── nmb
    │   │   ├── ...
    │   ├── pyasn1
    │   │   └── ...
    │   └── smb
    │       ├── ...
    ├── dizz
    │   ├── smb2_close_request.dizz
    │   ├── smb2_create_request_read.dizz
    │   ├── smb2_create_request_write.dizz
    │   ├── smb2_negotiate_req.dizz
    │   ├── smb2_read_request.dizz
    │   ├── smb2_session_setup_req.dizz
    │   ├── smb2_tree_connect_req.dizz
    │   ├── smb2_write_request.dizz
    │   └── smb_com_negotiate_req.dizz
    ├── job
    │   ├── smb2_file_access_read.conf
    │   ├── smb2_file_access_write.conf
    │   └── smb2_tree_connect.conf
    └── probe
        └── smb2.py

wireshark plugin

In the wireshark folder, there is a lua plugin to export parsed packet in .dizz files.

Note, that it requires a lua version of 5.2.0 or newer.

To use it, run

$ cwd
~/dizzy/wireshark
$ wireshark -X lua_script:dizzy.lua

dizz file

So, now a short introduction to the dizzy packet and protocol specifications:

A single packet is described by a so called dizz file. Some example files can be found in the demo module folder that comes with dizzy. These files are python code so you need to write them in python syntax and format rules. They consist of 2 variables which need to be defined.

The first var is called objects and describes the fields of the packet. Its a python array of objects with a specific interface:

objects = [
    ...
    ]

The following list show the pre-defined classes which is has implemented the interface already and are imported in a dizz file:

The second var is called functions and is for execute some code to change the value of the fields. Its a python array of functions with a specific interface:

functions = [
    ...
    ]

The following list show the pre-defined functions which is has the interface already and are imported in a dizz file:

act file

Ok, that are the packet descriptions so far. Ones you want to get state full, you need to write interaction in act files. Some prepared can be found in the interactions folder that comes with dizzy. These file are python code as well. They consist of 2 variables which need to be defined.

The first var is called objects which is a python list of Dizz().
Dict() is a class, which have 6 arguments:

objects = [
    # define the first packet of the interaction and after the packet is send it have read at least 100 bytes from the 
    # session 
    Dizz("first_packet", "module_name/dizzes/first_packet.dizz", 100, fuzz="full"),
    Dizz("second_packet", "module_name/dizzes/second_packet.dizz"),
    ...
    ]

The second var is called functions, which is this case a python dict(). For more information about act functions see Interface. The following example takes the value of the field0 dizz object of the dizz packet Dizz0 and assigned it to the field0 of the dizz packet Dizz3:

def test(interaction_iterator, dizzy_iterator, response):
    buf0 = response[0:10]
    dizzy_iterator["field4"] = buf0
    buf1 = interaction_iterator["Dizz0"]["field0"]
    interaction_iterator["Dizz3"]["field0"] = buf1

Interface of Probe

This section describes the interface of the probe objects. A field object have mandatory attributes.

Mandatory

Example

A probe always succeeding:

class DizzyProbe(object):
    def __init__(self, section_proxy):
        pass

    def open(self):
        pass

    def probe(self):
        return True

    def close(self):
        pass

Interface of Session

This section describes the interface of the session objects. A field object have mandatory attributes.

Mandatory

Example

The following example takes the creates a session as stdin for input and stdout for output:

class DizzySession(object):
    def __init__(self, section_proxy):
        pass

    def open(self):
        pass

    def send(self, data):
        self.f.write(data + b"\n")

    def recv(self):
        return stdin.readline()

    def close(self):
        pass