Spy my girl

Another pcap. This time it contains usb traffic. That’s a first for me. I had to gather information about it.

The way i understood is that whenever a usb device gets connected the host pc sends some GET DESCRIPTOR Request to the device be able to identify it.

The devices will respond with a GET DESCRIPTOR Response.

Get requests/responses
Descriptors

If we look at a Response packet, the text field DEVICE DESCRIPTOR gives us information about the device.

Responses
Respond packet with the device information

In the field USB URB -> Device we see that it’s the 6th device. We can also see in the source column that the source is 2.6.0. 6 being the 6th device.

Device DESCRIPTOR -> idProduct tells us that the device is a HP Webcam.

If we look at the rest of the pcap it’s pretty much only URB_INTERRUPT.

This website is the holy grail of understanding USB http://www.beyondlogic.org/usbnutshell/usb1.shtml

From that website i understood that URB_INTERRUPT is one of the 4 transfer/endpoint types. http://www.beyondlogic.org/usbnutshell/usb4.shtml#Interrupt

Quoting the website

The maximum data payload size for low-speed devices is 8 bytes.
Maximum data payload size for full-speed devices is 64 bytes.
Maximum data payload size for high-speed devices is 1024 bytes.

If we look at our packets we can see that there’s a differences of 7 bytes between the packets the usb device sends to the host and the packets the host sends to the usb device.

Device
Respond packet with the device information

If we look at the source column, we can see that the device communicating is the third one (2.3.1), if go back to the responses and look at the third device we get this.

Mouse
Device type and information*

USB URB -> Device: 3 and the idProduct is MX510 Optical Mouse.

Another device

If we look at the 195th packet, we notice that the length of the packet is not 71 but 72. The source is also different, it’s the 4th device communicating .

Second Device
Another device found*

A quick verification in the responses and we get the idproduct

Second Response
Idproduct value*

We got a keyboard communicating. Since it’s a URB_INTERRUPT, we know that it’s a transfer. There’s a difference of 8 bytes between the packets sent from the host to 2.4.1. That means it’s also a low-speed device.

The additional 8 bytes in the packet that the keyboard sends is found in the Leftover Capture Data.

We’ll filter the data to only see all the packets send by the keyboard.

usb.src == "2.4.1"

We’ll be using tshark (cli wireshark client) to retrieve all the Leftover Capture Data from 2.4.1.

tshark -r 4c27525e7a3d2e45495c6284386b4d5c.cap -Y 'usb.src == "2.4.1"' -T fields -e usb.capdata  > keyboardData

If we take a look at the data, most of the changes happen in the third byte.

00:00:2a:00:00:00:00:00
00:00:00:00:00:00:00:00
00:00:2a:00:00:00:00:00
00:00:00:00:00:00:00:00
00:00:2a:00:00:00:00:00
00:00:00:00:00:00:00:00
00:00:1a:00:00:00:00:00
00:00:00:00:00:00:00:00
...

If we look back at a packet from 2.4.1 the field bInterfaceClass is unknown (0xffff) but we know it’s a keyboard. I guess that was done in purpose ? But a quick google research tells us keyboards,mouse, joysticks are HID.

https://docs.mbed.com/docs/ble-hid/en/latest/api/md_doc_HID.html

The website has the information needed to know where to look exactly in all the data that we found.

The usual format for keyboard traffic is

[modifier, reserved, Key1, Key2, Key3, Key4, Key6, Key7]

That means that the third byte is the key that is being pressed.

We can redo our tshark command to only keep the third byte.

tshark -r 4c27525e7a3d2e45495c6284386b4d5c.cap -Y 'usb.src == "2.4.1"' -T fields -e usb.capdata  | cut -d ":" -f3 > keyboardData

The only thing left to do if find the corresponding letter to each byte. We can find the table at the page 53-59 in the following pdf file http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

Now we have everything we need. We’ll create a python script that will take the hex data and convert it to readable strings.

#!/usr/bin/python

letters = {
        '04':"A",
        '05':"B",
        '06':"C",
        '07':"D",
        '08':"E",
        '09':"F",
        '0a':"G",
        '0b':"H",
        '0c':"I",
        '0d':"J",
        '0e':"K",
        '0f':"L",
        '10':"M",
        '11':"N",
        '12':"O",
        '13':"P",
        '14':"Q",
        '15':"R",
        '16':"S",
        '17':"T",
        '18':"U",
        '19':"V",
        '1a':"W",
        '1b':"X",
        '1c':"Y",
        '1d':"Z",
        '1e':"1",
        '1f':"2",
        '20':"3",
        '21':"4",
        '22':"5",
        '23':"6",
        '24':"7",
        '25':"8",
        '26':"9",
        '27':"0",
        '28':"\n",
        '2c':" ",
        '2d':"-",
        '2e':"=",
        '2f':"[",
        '37':".",
        }

flag = ""

hexdata = open('keyboardData')
for i in hexdata:
    try:
        flag += letters[i.rstrip()]
    except:
        pass
hexdata.close()

print flag

Result :

WWW.GOOGLE.CA 
LITLLE CALITLE CAT IIN THEE WORLD
GMAIL.COOM
CHALLENGE2GMAAIL.COOM
FLAG-11234ETEH
HHI MOM
I LOVVEE YOOU .
BBYEE 

We got what we were looking for. I tried the “FLAG-11234ETEH” but it didn’t work. I had to take out one of the “1” to make it work.

The right flag

After looking back at the Leftover Capture Data, the two “1” looked like this

00:00:1e:00:00:00:00:00
00:00:1e:1f:00:00:00:00

That means that the second keystroke was two keys at the same time. If we assume that simultaneous gives us nothing ( For some reason, key rollover at 0/1 ? ) we’ll get the right answer.

I redid it taking the full hex data from tshark then passing it to a modified python script.

Tshark command:

tshark -r 4c27525e7a3d2e45495c6284386b4d5c.cap -Y 'usb.src == "2.4.1"' -T fields -e usb.capdata  > hex

Modified python script:

#!/usr/bin/python

letters = {
        '04':"A",
        '05':"B",
        '06':"C",
        '07':"D",
        '08':"E",
        '09':"F",
        '0a':"G",
        '0b':"H",
        '0c':"I",
        '0d':"J",
        '0e':"K",
        '0f':"L",
        '10':"M",
        '11':"N",
        '12':"O",
        '13':"P",
        '14':"Q",
        '15':"R",
        '16':"S",
        '17':"T",
        '18':"U",
        '19':"V",
        '1a':"W",
        '1b':"X",
        '1c':"Y",
        '1d':"Z",
        '1e':"1",
        '1f':"2",
        '20':"3",
        '21':"4",
        '22':"5",
        '23':"6",
        '24':"7",
        '25':"8",
        '26':"9",
        '27':"0",
        '28':"\n",
        '2c':" ",
        '2d':"-",
        '2e':"=",
        '2f':"[",
        '37':".",
        }

flag = ""

hexdata = open('hex')
for i in hexdata:
    try:
        if (i.split(':')[3] == "00"):
            flag += letters[i.split(':')[2]]
            
    except:
        pass
hexdata.close()

print flag

Result :


WWW.GOOGLE.CA 
LITLLE CALITLE CAT IN THE WORLD
GMAIL.COM
CHALLENGE2GMAIL.COM
FLAG-1234ETEH
HI MOM
I LOVE YOU .
BYE 

That looks a little bit better ? I guess, at least the flag is right.

Also for the sake of understanding everything well the 2 in challenge2gmail.com is suppose to be a @ character.

The data is :

40:00:1f:00:00:00:00:00

The first byte starts with a 4 that means that the shift button is being held down.

From the hid pdf file

31 1F Keyboard 2 and @ 4 

I guess that’s it.

The flag is FLAG-1234ETEH