Building

dizzy version 2.0 released

A new major version of our fuzzing framework dizzy has been released.

This blog post will cover the biggest changes and new features, as well as give you a short introduction into how to use them.

You can find the new version on github.

Installation

There are two supported ways of installing dizzy:

via pypi
$ pip install dizzy
via setup.py
$ git clone https://https://github.com/ernw/dizzy && cd dizzy && python setup.py install

Regardless which way of installation you choose, it should install a
script called `dizzy_cmd` in $PREFIX/bin ($PREFIX can be ~/.local/bin if
you run `pip install –user dizzy`) and you should be able to run that
script.

After the first start, two folders and a config file, as well as your std
string lib should be created in ~/.local/share/dizzy:

~/.local/share/dizzy $ ls -l
total 136
-rw-r--r-- 1 user user 96 Jun 25 11:55 dizzy.conf
drwxr-xr-x 2 user user 4096 Jun 25 11:55 local
drwxr-xr-x 2 user user 4096 Jun 25 11:55 modules
-rw-r--r-- 1 user user 123353 Jun 25 11:57 std_string_lib.txt

New file syntax

Syntax of dizz and act files changed just a little bit (;

For dizz files, you now have a new, optional field format that specifies if you want to use the new dizz file syntax (Yes we tried to build backward compatibility for the old packet specification files). If you do so, the new Field, List, Rand and Regex objects will be exposed. For further details, take a look at the README.

For act files, the footprint of your interaction functions changed, giving you more control to define which function is called when, and what values should be changed in the end. The details can also be found in the README.

Module support

dizzy now uses a modular approach to bundle packet descriptions, state generators, and config parameters. Instead of supplying a lot of parameters on the command line, all the connection specific configuration is now stored with the fuzzing protocol description.

The default module path is ~/.local/share/dizzy/modules.

Virtual paths

All files supplied in the modules are combined in a kind of virtual file system, so that cross references are possible.

$ dizzy_cmd -l
dizzy_cmd version 2.0 running on Linux
### global sessions ###
- session.ssl
- session.stdout-hex
- session.sctp
- session.tcp
- session.udp
- session.eth
- session.http
- session.stdout
### global probes ###
- probe.tcp
- probe.icmp
- probe.http
### module 'demo' loaded from '/home/user/.local/share/dizzy/modules/demo.zip' v0.1 ###
- demo/dizz/demo.dizz
- demo/act/demo.act
- demo/job/demo.conf

Local overlay

If you want to replace certain files in a module, you can put the modified copy in your local overlay. So if you want to replace the demo.dizz file in the demo module, put the new file in your overlay.

$ dizzy_cmd -l
Overwriting demo/dizz/demo.dizz from /home/user/.local/share/dizzy/local/demo/dizz/demo.dizz
dizzy_cmd version 2.0 running on Linux
...

Job configuration files

To cleanup the cmd invocation and also make certain tests more reproducible, the configuration of fuzzing jobs is now stored in a config file.

[job]
file = demo/act/demo.act
mode = std
delay = 0
verbose = 4

[output]
type = session.stdout-hex
timeout = 10

Some global parameters, like the dizz or act file and the fuzzing mode you want use, as well as the timing, are set in the [job] section of the file. The output section chooses one of the installed output modules and also configures the module.

Command line overwrite

Sometimes you just want to change a single parameter from the job configuration file and dont want to create a local overlay. In this case, you can use the -o command line parameter of dizzy_cmd. Say you want to target a different host, you can set the target_host parameter in your target section like this:

$ dizzy_cmd -o output.target_host=1.2.3.5 somemodule/job/job.conf

Target probes

Dizzy now features target probes, meaning a specific test can be performed after each injection approach to see if the target still responds in a correct manner.

To enable a probe, add a section [probe] to your job configuration file and configure the probe specific parameters:

[probe]
type = icmp
timeout = 1
pkg_size = 64
target_host = 1.2.3.4

This would enable the ICMP probe against the target 1.2.3.4, so after each fuzzing attempt, an ICMP ECHO Request will be sent to the target. If no ICMP ECHO Response is received, the target is considered dead and the fuzzing process will stop.

Global config values

Sometimes parts of the default values in your packet description is part of the target configuration as well. Take SMB for example: In some place of your fuzzing you will have to send the name of the share you try to connect to. This share name will vary depending on the target you are fuzzing, so putting it in the same place as the target description seems logical.

To add global values, add a [values] section to your job configuration file and set any values you want to use in your dizz or act files.

[values]
share_path = \\1.2.3.4\share

Values set in the job configuration file can be accessed with the config_value() function exposed to dizz and act files.

objects = [
#...
Field("path", config_value("share_path"), fuzz="std", encoding="utf-16-le"),
]

Extra encoding (ASN.1)

With dizzy 2.0, it is now possible to apply an extra encoding to your output data, e.g. DER encoding. To do this, the optional argument extra_encoding of your dizz file Field objects needs to be set to “DER”. The encoding also needs some extra data to correctly encode the output; In the case of DER this is a tuple containing the tag that should be applied to the data and the depth of the Filed in the ASN.1 data tree.

Given the two files der_test.dizz

name = "der_test"
format = 2

objects = [
Field("asd", "", extra_encoding="DER", extra_encoding_data=(b"\x30", 0)),
Field("asd1", "", extra_encoding="DER", extra_encoding_data=(b"\x30", 1)),
Field("asd11", "", extra_encoding="DER", extra_encoding_data=(b"\x30", 2)),
Field("asd111", "asd3", extra_encoding="DER", extra_encoding_data=(b"\x13", 3)),
Field("asd1111", "asd4", extra_encoding="DER", extra_encoding_data=(b"\x13", 3)),
Field("asd11111", "asd5", extra_encoding="DER", extra_encoding_data=(b"\x13", 3)),
Field("asd2", "fgh1", extra_encoding="DER", extra_encoding_data=(b"\x13", 1)),
Field("asd22", "", extra_encoding="DER", extra_encoding_data=(b"\x30", 1)),
Field("asd222", "fgh3", extra_encoding="DER", extra_encoding_data=(b"\x13", 2)),
Field("asd2222", "", extra_encoding="DER", extra_encoding_data=(b"\x30", 2)),
Field("asd22222", "fgh5", extra_encoding="DER", extra_encoding_data=(b"\x13", 3)),
List("test123", "listtest", extra_encoding="DER", extra_encoding_data=(b"\x13", 3))
]

functions = []

and der_test_dizz.conf:

[job]
file = test/dizz/der_test.dizz
mode = std
delay = 0
verbose = 0

[output]
type = session.stdout
send_lf = False
buffered = False

the output will be DER encoded. You can check that with the asn1parse function from openssl like so:

$ dizzy_cmd test/job/der_test_dizz.conf > /tmp/dertest
$ openssl asn1parse -inform der -i -dump -in /tmp/dertest
0:d=0 hl=2 l= 54 cons: SEQUENCE
2:d=1 hl=2 l= 20 cons: SEQUENCE
4:d=2 hl=2 l= 18 cons: SEQUENCE
6:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
12:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
18:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
24:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
30:d=1 hl=2 l= 24 cons: SEQUENCE
32:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
38:d=2 hl=2 l= 16 cons: SEQUENCE
40:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
46:d=3 hl=2 l= 8 prim: PRINTABLESTRING :listtest
56:d=0 hl=2 l= 46 cons: SEQUENCE
58:d=1 hl=2 l= 20 cons: SEQUENCE
60:d=2 hl=2 l= 18 cons: SEQUENCE
62:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
68:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
74:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
80:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
86:d=1 hl=2 l= 16 cons: SEQUENCE
88:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
94:d=2 hl=2 l= 8 cons: SEQUENCE
96:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
102:d=3 hl=2 l= 0 prim: PRINTABLESTRING :
104:d=0 hl=2 l= 47 cons: SEQUENCE
106:d=1 hl=2 l= 20 cons: SEQUENCE
108:d=2 hl=2 l= 18 cons: SEQUENCE
110:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
116:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
122:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
128:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
134:d=1 hl=2 l= 17 cons: SEQUENCE
136:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
142:d=2 hl=2 l= 9 cons: SEQUENCE
144:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
150:d=3 hl=2 l= 1 prim: PRINTABLESTRING :!
153:d=0 hl=2 l= 48 cons: SEQUENCE
155:d=1 hl=2 l= 20 cons: SEQUENCE
157:d=2 hl=2 l= 18 cons: SEQUENCE
159:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
165:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
171:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
177:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
183:d=1 hl=2 l= 18 cons: SEQUENCE
185:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
191:d=2 hl=2 l= 10 cons: SEQUENCE
193:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
199:d=3 hl=2 l= 2 prim: PRINTABLESTRING :!'
203:d=0 hl=2 l= 75 cons: SEQUENCE
205:d=1 hl=2 l= 20 cons: SEQUENCE
207:d=2 hl=2 l= 18 cons: SEQUENCE
209:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
215:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
221:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
227:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
233:d=1 hl=2 l= 45 cons: SEQUENCE
235:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
241:d=2 hl=2 l= 37 cons: SEQUENCE
243:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
249:d=3 hl=2 l= 29 prim: PRINTABLESTRING :!@#$%%^#$%#$@#$%$$@#$%^^**(()
280:d=0 hl=2 l= 72 cons: SEQUENCE
282:d=1 hl=2 l= 20 cons: SEQUENCE
284:d=2 hl=2 l= 18 cons: SEQUENCE
286:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd3
292:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd4
298:d=3 hl=2 l= 4 prim: PRINTABLESTRING :asd5
304:d=1 hl=2 l= 4 prim: PRINTABLESTRING :fgh1
310:d=1 hl=2 l= 42 cons: SEQUENCE
312:d=2 hl=2 l= 4 prim: PRINTABLESTRING :fgh3
318:d=2 hl=2 l= 34 cons: SEQUENCE
320:d=3 hl=2 l= 4 prim: PRINTABLESTRING :fgh5
326:d=3 hl=2 l= 26 prim: PRINTABLESTRING :!@#0%^#0##018387@#0^^**(()

 

So now, enjoy all the fancy new stuff, find (and please report) bugs and have a lot of fun fuzzing.

cheers

/daniel

P.S. In theory dizzy-2.0 also runs on Windows. You will need at least a python interpreter >= version 3.0 installed. I have not tested the installation, nor the execution on Windows, maybe some of you native Windows users might try/document that process.