CSAW 2012: Net300

Overview

For the Net300 challenge we are given a file named dongle.pcap. The first thing to do is open it in something like Wireshark. A quick peek with Wireshark shows that they have captured USB packets. Our goal will likely be to extract the flag from the data being transferred.

Step 0: Analysis

At this point, we’re not quite sure what data is being passed around in these USB packets. Based on the nature of the protocol, it could be many things, and the method of transferring that information does not often allow you to simply run strings to discover what it is. Let’s open it up with gallimaufry:

In [1]: from Gallimaufry.USB import USB

In [2]: pcap = USB("./dongle.pcap")
Expected 1 Descriptors. Found 0.

In [3]: pcap
Out[3]: <USB packets=2844>

So we’ve parsed the pcap file. There is a warning stating that we expected 1 Descriptor but didn’t find it. This is OK, but it’s a good thing to keep in mind. Basically, gallimaufry relies on parsing the same information that your USB device sends to your host. This allows us to know what type of device it is, and other useful information for proper parsing. The warning above means that the Descriptor told us we should expect 1 of them, but we found none. This could be for any number of reasons, mostly likely that the Descriptor we’re parsing came before our pcap. Even if you have no Descriptors, however, you can still use gallimaufry to parse the data, but you have to do a little more work yourself. This will be covered in the example of Pico 2017.

Now that we’ve loaded up the pcap, we should take a look at what’s inside it. With smaller pcap files, the easiest way is probably to use the summary property:

In [5]: print(pcap.summary)
PCAP: /home/user/opt/gallimaufry/examples/keyboard/csaw2012/dongle.pcap
Total Packets: 2844

Devices
-------

        Van Ooijen Technische Informatica - Teensyduino Keyboard+Mouse+Joystick
        -----------------------------------------------------------------------
        bus_id: 2
        device_address: 0
        device_version: 1.0.5
        bluetooth_version: 2.0.0
        packets: 4

        Configurations
        --------------

        Van Ooijen Technische Informatica - Teensyduino Keyboard+Mouse+Joystick
        -----------------------------------------------------------------------
        bus_id: 2
        device_address: 26
        device_version: 1.0.5
        bluetooth_version: 2.0.0
        packets: 2758

        Configurations
        --------------

                Configuration 1
                ---------------
                bNumInterfaces = 4
                self_powered = True
                remote_wakeup = False

                Interfaces
                -----------

                        Interface 0
                        -----------
                        Class: HID – Human Interface Device
                        SubClass: Boot Interface Subclass
                        Protocol: Keyboard

                        Endpoints
                        ---------

                                Endpoint 3
                                ----------
                                direction: In
                                transfer_type: Interrupt
                                packets: 2696

                        Interface 1
                        -----------
                        Class: HID – Human Interface Device
                        SubClass: Boot Interface Subclass
                        Protocol: Mouse

                        Endpoints
                        ---------

                                Endpoint 4
                                ----------
                                direction: In
                                transfer_type: Interrupt
                                packets: 20

                        Interface 2
                        -----------
                        Class: HID – Human Interface Device
                        SubClass: No Subclass
                        Protocol: None

                        Endpoints
                        ---------

                                Endpoint 1
                                ----------
                                direction: In
                                transfer_type: Interrupt
                                packets: 0


                                Endpoint 2
                                ----------
                                direction: Out
                                transfer_type: Interrupt
                                packets: 0

                        Interface 3
                        -----------
                        Class: HID – Human Interface Device
                        SubClass: No Subclass
                        Protocol: None

                        Endpoints
                        ---------

                                Endpoint 5
                                ----------
                                direction: In
                                transfer_type: Interrupt
                                packets: 0

Since we weren’t told ahead of time where the flag is, we should likely guess that it is from the stream that has the majority of the packets. Thus, simply trace down that list watching who is sending the most packets, and we find that it’s coming from Configuration 1, Endpoint 3, which is being described as a keyboard.

Step 1: Extract the Keystrokes

Here we can drill down into the object to extract the keystrokes. Let’s take a look at the devices:

In [6]: pcap.devices
Out[6]:
[<Van Ooijen Technische Informatica Teensyduino Keyboard+Mouse+Joystick v1.0.5 USB2.0.0 bus_id=2 address=0>,
 <Van Ooijen Technische Informatica Teensyduino Keyboard+Mouse+Joystick v1.0.5 USB2.0.0 bus_id=2 address=26>]

Looking at our summary, we know it’s the device with address 26. We can then drill down into the Configurations:

In [7]: pcap.devices[1].configurations
Out[7]: [<Configuration bNumInterfaces=4 bConfigurationValue=1>]

There’s only one. Let’s look at the Interfaces:

In [8]: pcap.devices[1].configurations[0].interfaces
Out[8]:
[<Interface HID – Human Interface Device bInterfaceNumber=0>,
 <Interface HID – Human Interface Device bInterfaceNumber=1>,
 <Interface HID – Human Interface Device bInterfaceNumber=2>,
 <Interface HID – Human Interface Device bInterfaceNumber=3>]

From the summary, we know we want Interface 0. Finally, checkout the endpoints:

In [9]: pcap.devices[1].configurations[0].interfaces[0].endpoints
Out[9]: [<Endpoint number=3 direction=In transfer_type=Interrupt packets=2696>]

There’s only one of them. At this point, we have an Endpoint object. The library has identified that this endpoint is a keyboard, and has added a Keyboard object to it. Let’s pull that out.:

In [12]: keyboard = pcap.devices[1].configurations[0].interfaces[0].endpoints[0].keyboard

In [13]: keyboard
Out[13]: <Keyboard keystrokes=668>

Notice that the Keyboard object has identified 668 keystrokes for this endpoint. Let’s extract them:

In [14]: keyboard.keystrokes
Out[14]: '[RIGHT_GUI]rxterm -geometry 12x1+0+0\necho k\n[RIGHT_GUI]rxterm -geometry 12x1+75+0\necho e\n[RIGHT_GUI]rxterm -geometry 12x1+150+0\necho y\n[RIGHT_GUI]rxterm -geometry 12x1+225+0\necho {\n[RIGHT_GUI]rxterm -geometry 12x1+300+0\necho c\n[RIGHT_GUI]rxterm -geometry 12x1+375+0\necho 4\n[RIGHT_GUI]rxterm -geometry 12x1+450+0\necho 8\n[RIGHT_GUI]rxterm -geometry 12x1+525+0\necho b\n[RIGHT_GUI]rxterm -geometry 12x1+600+0\necho a\n[RIGHT_GUI]rxterm -geometry 12x1+675+0\necho 9\n[RIGHT_GUI]rxterm -geometry 12x1+0+40\necho 9\n[RIGHT_GUI]rxterm -geometry 12x1+75+40\necho 3\n[RIGHT_GUI]rxterm -geometry 12x1+150+40\necho d\n[RIGHT_GUI]rxterm -geometry 12x1+225+40\necho 3\n[RIGHT_GUI]rxterm -geometry 12x1+300+40\necho 5\n[RIGHT_GUI]rxterm -geometry 12x1+450+40\necho c\n[RIGHT_GUI]rxterm -geometry 12x1+375+40\necho 3\n[RIGHT_GUI]rxterm -geometry 12x1+525+40\necho a\n[RIGHT_GUI]rxterm -geometry 12x1+600+40\necho }\n'

In [15]: print(keyboard.keystrokes)
[RIGHT_GUI]rxterm -geometry 12x1+0+0
echo k
[RIGHT_GUI]rxterm -geometry 12x1+75+0
echo e
[RIGHT_GUI]rxterm -geometry 12x1+150+0
echo y
[RIGHT_GUI]rxterm -geometry 12x1+225+0
echo {
[RIGHT_GUI]rxterm -geometry 12x1+300+0
echo c
[RIGHT_GUI]rxterm -geometry 12x1+375+0
echo 4
[RIGHT_GUI]rxterm -geometry 12x1+450+0
echo 8
[RIGHT_GUI]rxterm -geometry 12x1+525+0
echo b
[RIGHT_GUI]rxterm -geometry 12x1+600+0
echo a
[RIGHT_GUI]rxterm -geometry 12x1+675+0
echo 9
[RIGHT_GUI]rxterm -geometry 12x1+0+40
echo 9
[RIGHT_GUI]rxterm -geometry 12x1+75+40
echo 3
[RIGHT_GUI]rxterm -geometry 12x1+150+40
echo d
[RIGHT_GUI]rxterm -geometry 12x1+225+40
echo 3
[RIGHT_GUI]rxterm -geometry 12x1+300+40
echo 5
[RIGHT_GUI]rxterm -geometry 12x1+450+40
echo c
[RIGHT_GUI]rxterm -geometry 12x1+375+40
echo 3
[RIGHT_GUI]rxterm -geometry 12x1+525+40
echo a
[RIGHT_GUI]rxterm -geometry 12x1+600+40
echo }

The [RIGHT_GUI] means that the person typing pressed the right GUI key, such as the Windows key. The rest of the challenge is simply interpreting those keystrokes as commands and finding the one of them is out of order.

Flag: key[c48ba993d353ca]

Resources