This is a tutorial on more advanced fuzzing with ansvif, in which we will fuzz a real application.
This page is a work in progress (more fuzzing examples will be added later, and things will be changed upon the addition of new features.
A Realistic Example of Fuzzing With ansvif
Fuzzing a real application
We’ll be using mogrify as an example in this test case. It is a command-line-driven image manipulation tool; part of the ImageMagick suite.
If you don’t have it, for this example you’ll need to install it with your distro’s package manager.
Let’s take this command as an example:
First off, we have
-c which specifies the command to be run. This is required.
Provided that in mogrify_t.txt (also known as our “template” file, or a very basic way of telling ansvif what flags are used to control a command-line driven program) denoted by
-t, we have a line-by-line list of the command-line flags, prepended with a space, and appended with a space to give some room. You’ll see why this isn’t exactly necessary but speeds things up if you look at how ansvif works. It takes the “flags” wholesale, as in, doesn’t change them at all before putting them randomly distributed throughout the fuzz, sometimes with another flag before or after, or a section of “buffer” Denoted by
-b passed to ansvif with an integer after it (this being many things… random data, lots of A’s, lots of numbers, negative numbers… you can see a full list near the bottom.)
Note: I used
-t here for a template, first because ansvif’s manpage parsing isn’t perfect and didn’t drag the options out of the manual as it does with most programs. The entire purpose of the
-t flag is to be used when
-m (sometimes in combination with
-p, also known as our “page section” if the manpage is not automatically located). If the parsing did work with ImageMagick’s manpage, we could have simply done
-m mogrify -p 1 instead of hand making the template. While we’re on the subject, there is a manpage dump option,
-D, that will tell ansvif to just spit out a parsed manpage and exit (which should obviously be combined with
-m and sometimes
A short slightly off-topic example of dumping command line options:
Back to fuzzing mogrify. As you can see, we also have a
-o option passed to ansvif, this is for logging. Turning logging on will generate two files; one will contain the STDOUT and STDERR of the program when it crashed, and the other will contain an XML file that has other crucial information, such as the PID of the process that crashed, the process name, the command line passed to the system (in two forms, one in plaintext, and the other being in printf compatible format so that you can easily feed binary data back into the terminal.) It should be noted that there is no need to append .log or anything after the name of your log file, as ansvif will automatically append the PID of the crashed process, as well as .log to the filenames.
-A options prepend and append (before, and after
-- respectively) things to the fuzz. This means that they should always be in the command sent to the system. In this case, we’re telling ansvif to tell mogrify to try to write to os.jpg and read from me_shades.jpg (which I will show is generated below.) The
-B options are most often used with
-y for several reasons.
-R option tells ansvif to run whatever is put within quotes or double quotes (yes, it matters which you use under certain circumstances… this isn’t a tutorial on /bin/sh though…) In this case, we are using
-R to run radamsa, a completely different project that has powerful file fuzzing attributes (where ansvif is a bit weak in that department as of right now.) We’re taking the original picture, pushing it into radamsa, then having radamsa push a slightly fuzzed version of the file back out, which is then copied for safekeeping; with the PID in the filename so it’s easier to find later, and doesn’t run over-top of itself with
-f on (we’ll get to
-f later), then just echo out what the PID of the process that made the picture’s run was.
Now we come to buffer sizes. This
-b option is always used, unless using
-y (which is just shorthand for
-b 0, or no random data at all, sort of like a dummy mode, however useful in some cases to turn ansvif into a crash wrapper), with an integer after it.
-z, which is easy; it randomizes the buffer size between 1 and whatever is specified by
-b (in this case a maximum of 8 bytes) so that we’re not always filling the options with the same number of bytes. This is useful in finding certain types of bugs, and when you wish to limit your fuzz a little.
Here we have the
-M option, which tells ansvif to limit the maximum number of flags to put within the fuzz. That’s pretty self-explanatory. It’s useful when you want to have a very large number of options, and don’t want ansvif “wasting cycles” by trying to use every option at once.
Last, in this fuzz test case, we have the
-f option, which denotes the number of forked processes that are spawned off to be fuzzed. This speeds things up quite a bit in some scenarios, threading the fuzz. Please note, use this option sparingly, as you could likely freeze your system if you don’t have your limits set properly and raise the value too large (if using
-R this value should be half of the number of threads you want running). Plus, to have it fuzz with tons of threads will just slow it down with overhead if you don’t have many cores. Also be aware that if used incorrectly, you can overwrite your files the trying to fuzz with while fuzzing, so when something crashes, you won’t be able to “look back” and see what exact file made the code crash, and will have to go off a core dump alone.
This ladies and gents, leaves us with this:
On my system, mogrify crashed with a SIGBUS error (signal 135).
More to come. Hope you enjoyed and learned something!