Strange PCAP

Strange PCAP

The Challenge

We managed to get all the data to incriminate our CEO for selling company secrets. Can you please help us and give us the secret data that he has leaked?

https://ctfx.hacktm.ro/

Challenge Overview

We received a pcap file, that on quick review, we see is a capture of USB communication

Solution Walkthrough

Realizing the challenge is asking to find a file, we try searching for a “flag” string


Wireshark-search-bingo

Bingo!

Looking more closely at this packet we see that it starts with the magic “PK” (50 4B), it usually marks a zipped file.

We will dump a hex stream into to a text editor and turn it into a binary file:

$ xxd -r -p hexstream flag.zip


Success! but this is a password protected zip file

This is a USB capture, meaning any USB connected device is recorded in the pcap file, including any USB connected keyboards. Googling around a bit on how USB keyboard communicate, you can find that they have a URB_INTERRUPT transfer type.


After identifying these packets in the PCAP, you can quickly find who is the source of these interrupts, and the set length of these messages, and write a filter

(usb.transfer_type == 0x01)&& !(usb.src == host)&&(frame.len == 35)

Now we just need to identify the part of the packet that delivers the keystroke information, which should be the only part of the packet that changes.


Besides an ID and time field, there is a Leftover Packet Capture field that keeps changing. We’ll add this column to wireshark and export it as a CSV file, isolate the Leftover Capture Data column.

$ cat usbkbinfo
0000240000000000
0000000000000000
[snip]
0000280000000000
0000000000000000

After some more googling we find “USB hid keys” dictionary (https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2) and use it to write a script to turn the numbers in usbkbinfo into actual keystrokes:

usb_codes = {
   0x04:"aA", 0x05:"bB", 0x06:"cC", 0x07:"dD", 0x08:"eE", 0x09:"fF",
   0x0A:"gG", 0x0B:"hH", 0x0C:"iI", 0x0D:"jJ", 0x0E:"kK", 0x0F:"lL",
   0x10:"mM", 0x11:"nN", 0x12:"oO", 0x13:"pP", 0x14:"qQ", 0x15:"rR",
   0x16:"sS", 0x17:"tT", 0x18:"uU", 0x19:"vV", 0x1A:"wW", 0x1B:"xX",
   0x1C:"yY", 0x1D:"zZ", 0x1E:"1!", 0x1F:"2@", 0x20:"3#", 0x21:"4$",
   0x22:"5%", 0x23:"6^", 0x24:"7&", 0x25:"8*", 0x26:"9(", 0x27:"0)",
   0x2C:"  ", 0x2D:"-_", 0x2E:"=+", 0x2F:"[{", 0x30:"]}",  0x32:"#~",
   0x33:";:", 0x34:"'\"",  0x36:",<",  0x37:".>", 0x4f:">", 0x50:"<"
   }
lines = ["","","","",""]

pos = 0
for x in open("usbkbinfo","r").readlines():
   code = int(x[4:6],16)

   if code == 0:
       continue
   # newline or down arrow - move down
   if code == 0x51 or code == 0x28:
       pos += 1
       continue
   # up arrow - move up
   if code == 0x52:
       pos -= 1
       continue
   # select the character based on the Shift key
   if int(x[0:2],16) in [2, 0x20]:
       lines[pos] += usb_codes[code][1]
   else:
       lines[pos] += usb_codes[code][0]


for x in lines:
   print (x)

output:

$ python scan_hid_codes.py
7vgj4SSL9NHVuK0D6d3F

We copy the password, and plug it in the flag.zip password box:

HackTM{88f1005c6b308c2713993af1218d8ad2ffaf3eb927a3f73dad3654dc1d00d4ae}

Success!