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 forfuzzinator.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 notNone
, change working directory before invoking AFL.env
: if notNone
, 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 notNone
, pass its value as the-t
timeout parameter to AFL.dictionary
: if notNone
, 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 thecommand
parameter).
Optional parameters of the fuzzer:
cwd
: if notNone
, change working directory before the command invocation.env
: if notNone
, 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