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 fuzzes a set of capture files using editcap, and runs TShark on them (recommended)
randpkt creates capture files with completely random data payloads
editcap can be used to introduce errors into normal capture files
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 ...
- Don't worry about the warning about ulimit.
- If you run into problems, try to manually create the 'tmp' folder in the wireshark-gtk2 directory.
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 ProtocolIf 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,radiusWhen 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:
- The byte can be replaced with a random byte value
- The byte can be replaced with a random letter or number
- The byte and the succeeding byte can be replaced with "%s"
- The rest of the packet can be filled with 0xAA
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
