/wireshark-fuzztools

Tools to assist in fuzzing (or triaging from oss-fuzz)

Primary LanguagePython

oss-fuzz helper tools for Wireshark

The current oss-fuzz integration with Wireshark uses a special binary (see tools/oss-fuzz/ in the Wireshark source tree) to generate a binary file reflecting the data that is passed to a dissector. This data could for example be passed to the DNS dissector or TCP dissector (with some port number).

The limitation of that approach is that some of the reported issues can not be reproduced with normal tshark since the file is not a packet capture file. Therefore another tool is needed to add the packet capture header. This project contains some tools to assist in automating oss-fuzz triaging.

The oss-fuzz-report.py script creates a pcap and runs tshark against it in order to reproduce it. If issues are found, it will show a report (and report issues automatically as needed). The grab-monorail.py script relies on this script to automate triaging even further, taking care of downloading the reproducer file too.

Data to pcap

Usual packet capture files have an encapsulation method like LINKTYPE_ETHERNET. The oss-fuzz-report.py script creates a pcap file with a single packet using the "Exported PDU" dissector method (link type 252). This approach is used rather than using LINKTYPE_ETHERNET to closer reflect how the fuzzer is invoked: it bypasses the IP dissector and directly calls into TCP.

Setup

To test out-of-memory, timeout (possible infinite loop) reports and report better call traces for g_error, build additional tools with:

cc -shared -fPIC -o libmemlimit.so memlimit.c
cc -shared -fPIC -o libtimeout.so timeout.c
cc -shared -fPIC -o libtrapabort.so trapabort.c

The script has some protocols headers built-in, but for some others it needs the samples_to_pcap binary from the tools directory in https://bitbucket.org/jwzawadzki/wireshark-fuzzdb (I plan to remove this requirement later and incorporate all supported protocols in the script). Build and move the binary in your $PATH:

cc tools/samples_to_pcap.c -o ~/bin/samples_to_pcap

Optionally install symlinks for oss-fuzz-report.py and grab-monorail.py in your $PATH to make reproduction easier.

Wireshark must be built with ASAN/UBSAN (Address Sanitizer and Undefined Behavior Sanitizer). Debug mode is recommended to get meaningful stacktraces. Using CMake, this is what I would use:

mkdir /tmp/build && cd /tmp/build
cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=1 -DENABLE_UBSAN=1 \
    /path/to/sources/for/wireshark

The ENABLE_UBSAN option was added in Wireshark 2.4 while ENABLE_ASAN was added in Wireshark 2.0. In older (and newer) versions you can replace those options with:

-DCMAKE_C_FLAGS=-fsanitize=address,undefined \
-DCMAKE_CXX_FLAGS=-fsanitize=address,undefined

Note that in this way, you must disable memleak detection via an environment variable or the build fails with Lemon:

ASAN_OPTIONS=detect_leaks=0 ninja

Setup - automatically file Bugzilla issues

Once an issue has been reproduced, it is possible to automatically file a bug. This is totally optional, you could also manually fill in the bugs form if you prefer.

To get started, generate a new token at https://bugs.wireshark.org/bugzilla/userprefs.cgi?tab=apikey and save the Bugzilla API key to ~/.cache/wireshark-bugzilla-apikey.txt. Then install the python-bugzilla library in this project:

git clone https://github.com/python-bugzilla/python-bugzilla

The version I currently tested with is v2.1.0 (commit 44045cbbb70b6777d3c8803459abac90c8799449 from 2017-03-30).

Usage

Requirements:

  • Setup this project and build Wireshark as above
  • Ensure that PATH contains tshark (e.g. PATH=/tmp/wsbuild/run:$PATH).

Assuming a mail like:

Subject: Issue 3535 in oss-fuzz: wireshark: Global-buffer-overflow in dissect_gtpv2_ie_common

...
wireshark: Global-buffer-overflow in dissect_gtpv2_ie_common
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3535

Detailed report: https://oss-fuzz.com/testcase?key=5241250057814016

Project: wireshark
Fuzzer: afl_wireshark_fuzzshark_ip_proto-udp
Fuzz target binary: fuzzshark_ip_proto-udp
Job Type: afl_asan_wireshark
Platform Id: linux
...
Reproducer Testcase:
https://oss-fuzz.com/download?testcase_id=5241250057814016

The key part is ip_proto-udp which says that this issue was found by calling the UDP dissector within an IP packet. The next important value is the issue ID (3535 in this case), this is used to credit oss-fuzz and provide a reference for more information.

The next step is to download the Reproducer Testcase and run it:

oss-fuzz-report.py --proto ip_proto-udp clusterfuzz-testcase-minimized-5241250057814016 3535

If it reports an error, add the --report option so it will automatically file a Bugzilla entry (of course do not do this if there is an existing report). This requires a valid Bugzilla API key.

Further automation

Since downloading the packet, configuring the protocol and providing the oss-fuzz issue ID is repetitive and error-prone work, I have further automated this.

First login to https://oss-fuzz.com/ and https://bugs.chromium.org/p/oss-fuzz/issues, then copy the SACSID cookies using Cookie Manager extension by Rob W (for Firefox and Chrome). Select the two SACSID cookies, use the "Export cookies" option from the menu in the bottom, select output format "Netscape" and press the Export button. Save it to a temporary file, e.g. /tmp/mc. The file looks like:

#HttpOnly_bugs.chromium.org	TRUE	/	TRUE	1552926226	SACSID	~...
#HttpOnly_oss-fuzz.com	TRUE	/	TRUE	1564357360	session	...

These session cookies expire quite fast, so if you get unexpected errors and have specified a correct Issue ID, try to refresh the cookies manually.

Grab a file with:

grab-monorail.py -c /tmp/mc 3535

Use grab-monorail.py --help for more options. In particular, --report automatically reports a bug to Bugzilla, similarly to oss-fuzz-report.py.

Userscripts

After confirming the bug above (and reporting it via the --report option), you could inform the oss-fuzz project. To help automating this, install userscripts/oss-fuzz_monorail_helpers_for_Wireshark.user.js (tested with GreaseMonkey in Firefox). It will automatically populate the comment form with a comment linking to the Wireshark bug and include its status.

There is also userscripts/Wireshark_oss-fuzz_bugzilla.user.js which is used to convert the Link columns in Bugzilla search queries into the Issue ID. Two named queried shared by me (unfortunately this requires a Bugzilla account with canconfirm permissions):

Links

List of bugs:

Where to find oss-fuzz stuff related to Wireshark:

Alternative way to actually reproduce the exact issue reported by oss-fuzz:

If you have further questions, feel free to contact me (https://lekensteyn.nl/) or the wireshark-dev mailing list.