Introduction

Fuzz testing Wireshark will create random or semi-random capture files, fed them into Wireshark/TShark and observes the "response".

Why would you do this? The vast majority of Wireshark's code base handles data that has been read directly from a live network or a capture file. It's important to make sure that it handles this data safely. One convenient way to do this is through fuzz testing.

Get involved!

We need as many people fuzz testing as possible. Everyone has its own valuable set of capture files and preferences. If possible, please use a SVN version of Wireshark for the fuzz testing and report any bug(s) you find. Please include the fuzzed capture file to the bug report, so the bug can be easily reproduced by others.

Available Tools

Wireshark comes with three tools that let you perform fuzz testing:

fuzz-test.sh

A convenient and effective way to do fuzz tests is to run fuzz-test.sh on your personal collection of capture files.

fuzz-test.sh is a bash script which can be used for large-scale batch processing. Running

        ./tools/fuzz-test.sh ~/captures/*

would test all of the files in ~/captures/. The script uses editcap to create errors in each capture file (described below), and runs TShark on the file. It assumes that you're running it from the Wireshark source directory. This behavior can be changed by modifying a few variables at the top of the script.

The script will check all the specified capture files on and on until a bug is found.

If a bug is found, the script will stop and the file causing trouble will be in the directory where you've started fuzz-test.sh, named something like: editcap.out.1234567890. Please attach this file if you report the bug. If this file is large (> 1MB) you may try to reduce the file size by removing packets (e.g. using editcap) and see if the problem still remains.

You can directly get fuzz-test.sh from the SVN repository, it's also shipped together with the Wireshark sources.

fuzz-test.sh on Cygwin (Win32)

Open a Cygwin shell, and move to the directory containing your built Wireshark binaries (if you wanted to test an installed version of Wireshark, you would use the installation location, usually "/cygdrive/c/Program Files/Wireshark").

~$ cd /wireshark/development/directory/wireshark-gtk2

Now run fuzz-test.sh from that directory, using the Cygwin-style path to your test files:

/c/Development/Wireshark/wireshark-gtk2$ bash -o igncr ../tools/fuzz-test.sh ~/Desktop/file1.cap ...

randpkt

randpkt creates capture files containing random data. It uses the following arguments:

        randpkt [-b maxbytes] [-c count] [-t type] filename

where 'maxbytes' is the maximum packet size, 'count' is the number of packets to create, and 'type' is the payload type, which can be one of:

        arp     Address Resolution Protocol
        bgp     Border Gateway Protocol
        bvlc    BACnet Virtual Link Control
        dns     Domain Name Service
        eth     Ethernet
        fddi    Fiber Distributed Data Interface
        giop    General Inter-ORB Protocol
        icmp    Internet Control Message Protocol
        ip      Internet Protocol
        llc     Logical Link Control
        megaco  MEGACO
        nbns    NetBIOS-over-TCP Name Service
        ncp2222 NetWare Core Protocol
        sctp    Stream Control Transmission Protocol
        syslog  Syslog message
        tds     TDS NetLib
        tcp     Transmission Control Protocol
        tr      Token-Ring
        udp     User Datagram Protocol

If you want to test a protocol that's not listed above, you can force decoding using the -d flag, e.g.

    ./randpkt -c 5000 -t dns /tmp/port53.pcap
    ./tshark -nVr /tmp/port53.pcap -d udp.port==53,radius

When randpkt is run with "-t dns" it generates UDP packets with a destination port 53, and with a random payload. Aside from the port number they aren't specific to DNS in any way. Running TShark with "-d udp.port==53,radius" forces the packets to be decoded as RADIUS.

editcap

editcap can be used to "fuzz" a capture file using the '-E' flag. For example,

        editcap -E 0.02 infile.pcap fuzzfile.pcap

would read infile.pcap and fuzz its contents, writing them to fuzzfile.pcap. There would be a 2% chance that any given payload byte would be fuzzed. There are four different fuzzing methods, chosen at random:

editcap is built together with Wireshark and is also shipped with the releases.

How to reproduce a bug

How to fix bugs found through fuzz testing?

Most bugs can easily be reproduced by both Wireshark and TShark, simply load the fuzzed capture file and wait for the crash in your favourite debugger.

However, it's worth to note that some bugs are hard to reproduce using Wireshark, for some reasons, e.g. tshark will output a complete hexdump of each packet while Wireshark only displays the packet details and the hexdump of the current packet, so a lot of the source code won't be used / tested. If you cannot reproduce a bug in Wireshark while it's easy in TShark, try to set a simple display filter that still displays all packets (like: frame.number != 0), this will create the packet details for all packets - a lot more code will be used / tested.

It's also worth noting that there are bugs that will only appear on some platforms, on other platforms the Wireshark code works pretty well.

Discussion

Concerning fuzz-test.sh on CygWin (Win32): one has to be sure not to save the script with line feed commands as this would break the script in Cygwin. At least it DID break it on my Win2000 machine. Furthermore I had to use normal slashes "/" for the capture file path. Has anyone made the same experience? --Lars2B

I addressed this problem by installing CygWin with "Dos / test" Text file type rather than the recommended default "Unix / binary". That made it work on Windows. --Peter

Did also run into this on my XP machine running Cygwin. Edit the script using vi, vim, etc.. Editing from within windows will often insert 0d 0a into the script, breaking it. I also ran into a hard error (not warning) on xygwin re: the cpu time limit. Commenting out line 52 "ulimit -S it $MAX_CPU_TIME -v $MAX_VMEM" fixed this problem. After making that edit and changing the TMPDIR to "TMPDIR=tmp" the current script (0997 Wireshark) worked as intended from cygwin. --Kevin

To run the script on my XP machine on Cygwin, I had to run the dos2unix utility in cygwin/bin on fuzz-test.sh. --Vincent

FuzzTesting (last edited 2008-12-12 11:44:26 by UlfLamping)