One weekend I got inspired by this old article on slashdot,
http://slashdot.org/articles/99/01/10/173223.shtml, and so I decided
to write my own fuzz program.
Why is this a security concern?
The idea is to improve the overall security of Linux by fixing
bugs. Paraphrasing Theo DeRandt, the head of the OpenBSD project, If
you go about fixing bugs, then security is one of the benefits. This
only goes so far because you can concievably have the perfectly
implemented piece of code which provides a backdoor but I personally
am not interested in dealing with that. I will let the other folk
working on Bastille Linux take charge of making sure that there are no
backdoors or conceptual errors in linux. I will take up the mantle of
trying to ensure that each and every utility is as robust as it can
Also each one of these SEGVs could potentially be a root exploit if
you can get root run a boobie trapped script. Imagine the case where
root runs a script where a utility is tricked into seg faulting and
the buffer overflow is specially designed to leave a back door on your
The fuzz generator is designed to attack certain kinds of software and
expose one particular kind of bug common in software. This is the
situation where the programmer implicity makes some assumtions about
the data stream that the program will be parsing. If the data stream
is substantially different then the program might not be able to deal
with it. This approach has several limitiations. Fist of all since the
data stream is really and truly random, it is very likely that this
will throughly test out a very small percentage of the total
program. I have several ideas on how to improve this. The most
ambitious is to compile the programs with profiling support and then
use the information about the code coverage gathered from that as a
goodness measure to some genetic algorithms which mate the data to
achieve the greatest possible code coverage.
For programs that read from stdin and do something with it "fuzz
progname" usually works. Sometimes you need to specify some command
line arguments to make the program do what it should. For example,
"fuzz grep foo" would have grep look for the string foo in the random
data streams. However another test would be, "./fuzz --maxargs 1 grep"
which would pass one random parameter to grep.
Some programs don't read from stdin and only accept parameters. These
programs can be tested using a command like, "./fuzz --omitdata
--maxargs 2 basename". One way to test if the program reads from stdin
is to do something like:
strace program 2> /tmp/foobar
grep "read(0," /tmp/foobar
****The rest of this document is pretty much for Ben's use only. You
can stop reading here unless you are curious about my little notes to myself***
1) make it possible to make printable-only apply to args or datastream
2) have it output to a file when and then and then feed that in when necessary
3) permute known args
4) permute known env vars
5) add random stuff to the environment
6) allow root override
7) have chroot feature move the needed shared libs into place.
8) have the program look at what files the program reads and make it fill that
file with random data. Strace style.
9) build in a feature to guess version number.
10) add feature to catch what comes out of stderr or stdout for client
11) socket support
13) genetic testing.
consolechars - need to be able to generate a file and then have the file be read.
ex - this seems to have problems because for some reason ex's get left running
I suspect that this is due to ex forking somewhere in its execution.