Fuzzers: package fuzzinator.fuzzer

class AFLRunner

class fuzzinator.fuzzer.AFLRunner(afl_fuzz, input, output, sut_command, cwd=None, env=None, timeout=None, dictionary=None, master_name=None, slave_name=None, **kwargs)

Wrapper around AFL to be executed continuously in a subprocess. The findings of AFL are periodically checked and any new test cases are returned as test inputs to the SUT. (Thus, all AFL findings are processed, extended, and filtered by any and all SUT decorators, uniqueness is determined, etc.)

For AFL, it is best not to run multiple instances in parallel.

Mandatory parameters of the fuzzer:

  • afl_fuzz: path to the AFL fuzzer tool.
  • sut_command: the string to append to the command string used to invoke AFL, probably the same string that is used for fuzzinator.call.SubprocessCall’s command parameter (the {test} substring is automatically replaced with the @@ input file placeholder used by AFL).
  • input: the directory of initial test cases for AFL.
  • output: the directory that will store the findings of AFL (all occurrences of {uid} in the string are replaced by an identifier unique to this fuzz job).

Optional parameters of the fuzzer:

  • cwd: if not None, change working directory before invoking AFL.
  • env: if not None, a dictionary of variable names-values to update the environment with (AFL_NO_UI=1 will be added automatically to suppress AFL’s own UI).
  • timeout: if not None, pass its value as the -t timeout parameter to AFL.
  • dictionary: if not None, pass its value as the -x dictionary parameter to AFL.
  • master_name: the name of the master fuzzer instance which will perform deterministic checks.
  • slave_name: the name of a slave fuzzer instance which will proceed to random tweaks. For further details check: https://github.com/mirrorer/afl/blob/master/docs/parallel_fuzzing.txt

Example configuration snippet:

[sut.foo]
call=fuzzinator.call.SubprocessCall

[sut.foo.call]
command=./bin/foo {test}
cwd=/home/alice/foo
env={"BAR": "1"}

[fuzz.foo-with-afl]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.AFLRunner
batch=inf
instances=1

[fuzz.foo-with-afl.fuzzer.init]
afl_fuzz=/home/alice/afl/afl-fuzz
sut_command=${sut.foo.call:command}
cwd=${sut.foo.call:cwd}
env=${sut.foo.call:env}
input=/home/alice/foo-inputs
output=${fuzzinator:work_dir}/afl-output/{uid}

class ByteFlipDecorator

class fuzzinator.fuzzer.ByteFlipDecorator(*args, **kwargs)

Decorator to add extra random byte flips to fuzzer results.

Mandatory parameter of the decorator:

  • frequency: the length of the test divided by this integer number gives the number of bytes flipped.

Optional parameters of the decorator:

  • min_byte: minimum value for the flipped bytes (integer number, 32 by default, the smallest ASCII code of the printable characters).
  • max_byte: maximum value for the flipped bytes (integer number, 126 by default, the largest ASCII code of the printable characters).

Example configuration snippet:

[sut.foo]
# see fuzzinator.call.*

[fuzz.foo-with-flips]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.ListDirectory
fuzzer.decorate(0)=fuzzinator.fuzzer.ByteFlipDecorator
batch=inf

[fuzz.foo-with-flips.fuzzer.init]
outdir=/home/alice/foo-old-bugs/

[fuzz.foo-with-flips.fuzzer.decorate(0)]
frequency=100
min_byte=0
max_byte=255

class FileWriterDecorator

class fuzzinator.fuzzer.FileWriterDecorator(filename)

Decorator for fuzzers that create str or bytes-like output. The decorator writes the test input to a temporary file and replaces the output with the name of that file.

Mandatory parameter of the decorator:

  • filename: path pattern for the temporary file, which may contain the substring {uid} as a placeholder for a unique string (replaced by the decorator).

Example configuration snippet:

[sut.foo]
# see fuzzinator.call.*

[fuzz.foo-with-random]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.RandomContent
fuzzer.decorate(0)=fuzzionator.fuzzer.FileWriterDecorator

[fuzz.foo-with-random.fuzzer.decorate(0)]
filename=${fuzzinator:work_dir}/test-{uid}.txt

class ListDirectory

class fuzzinator.fuzzer.ListDirectory(pattern, contents='True', **kwargs)

A simple test generator to iterate through existing files in a directory and return their contents one by one. Useful for re-testing previously discovered issues.

Since the fuzzer starts iterating from the beginning of the directory in every fuzz job, there is no gain in running multiple instances of this fuzzer in parallel. Because of the same reason, the fuzzer should be left running in the same fuzz job batch until all the files of the directory are processed.

Mandatory parameter of the fuzzer:

  • pattern: shell-like pattern to the test files.

Optional parameter of the fuzzer:

  • contents: if it’s true then the content of the files will be returned
    instead of their path (boolean value, True by default).

Example configuration snippet:

[sut.foo]
# see fuzzinator.call.*

[fuzz.foo-with-oldbugs]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.ListDirectory
instances=1
batch=inf

[fuzz.foo-with-oldbugs.fuzzer.init]
pattern=/home/alice/foo-old-bugs/**/*.js

function RandomContent

fuzzinator.fuzzer.RandomContent(*, min_length='1', max_length='1', **kwargs)

Example fuzzer to generate strings of random length from random ASCII uppercase letters and decimal digits.

Optional parameters of the fuzzer:

  • min_length: minimum length of the string to generate (integer number, 1 by default)
  • max_length: maximum length of the string to generate (integer number, 1 by default)

Example configuration snippet:

[sut.foo]
# see fuzzinator.call.*

[fuzz.foo-with-random]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.RandomContent
batch=100

[fuzz.foo-with-random.fuzzer]
min_length=100
max_length=1000

class SubprocessRunner

class fuzzinator.fuzzer.SubprocessRunner(outdir, command, cwd=None, env=None, timeout=None, contents='True', **kwargs)

Wrapper around a fuzzer that is available as an executable and can generate its test cases as file(s) in a directory. First, the external executable is invoked as a subprocess, and once it has finished, the contents of the generated files are returned one by one.

Mandatory parameters of the fuzzer:

  • command: string to pass to the child shell as a command to run (all occurrences of {uid} in the string are replaced by an identifier unique to this fuzz job).
  • outdir: path to the directory containing the files generated by the external fuzzer (all occurrences of {uid} in the path are replaced by the same identifier as described at the command parameter).

Optional parameters of the fuzzer:

  • cwd: if not None, change working directory before the command invocation.
  • env: if not None, a dictionary of variable names-values to update the environment with.
  • timeout: run subprocess with timeout.
  • contents: if it’s true then the content of the files will be returned
    instead of their path (boolean value, True by default).

Example configuration snippet:

[sut.foo]
# see fuzzinator.call.*

[fuzz.foo-with-bar]
sut=sut.foo
fuzzer=fuzzinator.fuzzer.SubprocessRunner
batch=50

[fuzz.foo-with-bar.fuzzer.init]
outdir=${fuzzinator:work_dir}/bar/{uid}
command=barfuzzer -n ${fuzz.foo-with-bar:batch} -o ${outdir}

class TornadoDecorator

class fuzzinator.fuzzer.TornadoDecorator(port, **kwargs)

Decorator for fuzzers to transport generated content through http. The decorator starts a Tornado server at the start of the fuzz job and returns a http url as test input. The SUT is expected to access the returned url and the decorated fuzzer is invoked on every GET access to that url. The response to the GET contains the generated test input prepended by a html meta tag to force continuous reloads in the SUT (or a window.close() javascript content to force stopping the SUT if the decorated fuzzer cannot generate more tests). Useful for transporting fuzz tests to browser SUTs.

Mandatory parameter of the fuzzer decorator:

  • port: first port to start binding the started http server to (keeps incrementing until a free port is found).

Example configuration snippet:

[sut.foo]
# assuming that foo expects a http url as input, which it tries to access
# afterwards

[fuzz.foo-with-bar-over-http]
sut=sut.foo
#fuzzer=...
fuzzer.decorate(0)=fuzzinator.fuzzer.TornadoDecorator
batch=5

[fuzz.foo-with-bar-over-http.fuzzer.decorate(0)]
port=8000