Copyright 1998-2019 Gerald Combs <gerald@wireshark.org> and contributors.
License GPLv2+: GNU GPL version 2 or later <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiled (64-bit) with libpcap, with POSIX capabilities (Linux), without libnl,
with GLib 2.54.2, with zlib 1.2.8, without SMI, without c-ares, without Lua,
without GnuTLS, with Gcrypt 1.8.3, with MIT Kerberos, without MaxMind DB
resolver, without nghttp2, without LZ4, without Snappy, with libxml2 2.9.4.
Running on Linux 4.19.16-1rodete1-amd64, with Intel(R) Xeon(R) CPU E5-1650 v4 @
3.60GHz (with SSE4.2), with 64406 MB of physical memory, with locale
en_US.UTF-8, with libpcap version 1.8.1, with Gcrypt 1.8.3, with zlib 1.2.8,
binary plugins supported (0 loaded).
Built using clang 4.2.1 Compatible Clang 7.0.0 (tags/RELEASE_700/final).
Through fuzzing of the command-line tshark tool ("$ ./tshark -nVxr /path/to/file") compiled with AddressSanitizer, we have found that the NetScaler trace parser (wiretap/netscaler.c) is susceptible to a number of heap-based out-of-bounds reads of various sizes. An example ASAN report looks as follows:--- cut ---===================================================================240712==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6250000d4100 at pc 0x55d449026945 bp 0x7ffce6479e30 sp 0x7ffce64795e0READ of size 22 at 0x6250000d4100 thread T0 #0 0x55d449026944 in __interceptor_strncmp.part.298 (wireshark/run/tshark+0xff944) #1 0x7f3cf272f0c5 in nspm_signature_isv10 wireshark/wiretap/netscaler.c:819:1 #2 0x7f3cf272f0c5 in nspm_signature_version wireshark/wiretap/netscaler.c:847 #3 0x7f3cf272f0c5 in nstrace_open wireshark/wiretap/netscaler.c:695 #4 0x7f3cf26e9643 in wtap_open_offline wireshark/wiretap/file_access.c:978:13 #5 0x55d4490a1081 in cf_open wireshark/tshark.c:4022:9 #6 0x55d44909ad65 in main wireshark/tshark.c:2021:9 #7 0x7f3cf10ea2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0) #8 0x55d448f86af9 in _start (wireshark/run/tshark+0x5faf9)0x6250000d4100 is located 0 bytes to the right of 8192-byte region [0x6250000d2100,0x6250000d4100)allocated by thread T0 here: #0 0x55d449050e47 in __interceptor_malloc (wireshark/run/tshark+0x129e47) #1 0x7f3cf1af6588 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x50588)SUMMARY: AddressSanitizer: heap-buffer-overflow (wireshark/run/tshark+0xff944) in __interceptor_strncmp.part.298Shadow bytes around the buggy address: 0x0c4a800127d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a800127e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a800127f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a80012800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c4a80012810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00=>0x0c4a80012820:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a80012830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a80012840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a80012850: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a80012860: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c4a80012870: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa faShadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc==240712==ABORTING--- cut ---The list of different locations we have encountered crashes at is shown below:--- cut ---nstrace_read_v10 wireshark/wiretap/netscaler.c:1067nstrace_read_v10 wireshark/wiretap/netscaler.c:1092nstrace_read_v20 wireshark/wiretap/netscaler.c:1276nstrace_read_v20 wireshark/wiretap/netscaler.c:1288nstrace_read_v20 wireshark/wiretap/netscaler.c:1305:25nstrace_read_v30 wireshark/wiretap/netscaler.c:1449:14nstrace_read_v30 wireshark/wiretap/netscaler.c:1459:17nstrace_read_v30 wireshark/wiretap/netscaler.c:1475nstrace_read_v30 wireshark/wiretap/netscaler.c:1475:17nstrace_read_v30 wireshark/wiretap/netscaler.c:1485nstrace_read_v30 wireshark/wiretap/netscaler.c:1485:17nstrace_read_v30 wireshark/wiretap/netscaler.c:1492nstrace_set_start_time_v10 wireshark/wiretap/netscaler.c:921nstrace_set_start_time_v20 wireshark/wiretap/netscaler.c:922:1--- cut ---Attached is an archive containing up to three testcases for each of the unique stack traces we have seen.
Hi Mateusz
I've noticed that you opened multiple bug for crashing on malformed files.
Just out of curiosity: are you systematically fuzzing wireshark? Which kind of fuzzer/setup are you using?
Nice job, by the way!
Very interesting presentation. Are you fuzzing executables other than tshark? I know that there is another one that could take great benefits from your work. It's called dftest. It basically gives straight access to the display filter parsing engine. It is close to be usable (gives 0 in cas of success and != 0 in case of failure), but requires a small change for taking the actual filter from stdin. If you think this is a new and interesting attack surface I could push the required change on master.
So far I've only been fuzzing the tshark binary. This is mostly because I'm interested in finding bugs with potential security impact, and parsing pcaps/network traffic represents an attack surface. Is there any attack surface associated with the display filter engine, e.g. a situation where an attacker-controlled filter may be executed in a user's Wireshark session?
Well... I'm not sure, you tell me: what about copy/paste commands from the internet like tshark -Y "filter that causes a buffer overflow"It's not like network traffic, nor like an hyperlink, but still...
I see. From a security standpoint this doesn't seem like a very realistic attack scenario so I probably won't be fuzzing the filter parsing soon, but I might look into it in the future when I have some spare cycles.
Even with the fix I'm still able to reproduce a majority of the crashes reported in this bug. I suspect there might be more than one problem in the code, and each directory in the attached archive contains samples referring to a different stack trace. Could you please take another look at this?