For this challenge, we were given a PCAP file containing USB captures. Our goal was to analyze the captures and extract the flag — the description is as follows.
My friend said that he kept trying to message me the flag but it wouldn't work. He sent me a packet capture of his USB Bus to prove he was typing the flag, can you help me figure out what the flag is?
With our click.pcapng
file in hand, we can fire up Wireshark to look through the USB Bus capture.
Filtering our search to devices we can see three devices, a Logitech G502 SE Hero Gaming Mouse, a Logitech G815 Mechanical Keyboard, and a USB hub.
From that and the challenge description of "message me the flag," we can safely deduce that our flag will be in the data stream from the keyboard and not any other device.
And this is where I hit a road block, my knowledge of USB captures and USB HID in general at the time of the challenge was zero. It is still close to zero, so that meant it was time to research how to actually read the data.
After a fair amount research I came across this ctf-usb-keyboard-parser from TeamRocketIST.
gh repo clone teamrocketist/ctf-usb-keyboard-parser
So following along with their README I was able to extract the keystrokes using tshark
by filtering for only the USB data from the keyboard.
tshark -r click.pcapng -Y 'usb.src == "7.2.1"' -Tfields -e usbhid.data > keystrokes.txt
Now we have a keystrokes.txt
containing a list of bytes, but the keyboard parser expects a different format than what tshark
returned, so as the README suggested, we can use sed
to format the data.
cat keystrokes.txt | sed 's/../&:/g' > hid.txt
We can save the formatted data to hid.txt
for later use. While formatting from this sed
pattern isn't 100% correct, we have a trailing colon at the end of each line, it is nothing we have to worry about.
Our last step is to run usbkeyboard.py
against hid.txt
and fetch our flag. We aren't interested in anything other than our flag and we can use grep
to only fetch that.
python3 usbkeyboard.py hid.txt | grep -o "flag{[[:alnum:]]*}"
And violá, we have now analyzed, researched, formatted and parsed a USB capture file to receive our message and fetch our flag.
flag{a3ce310e9a0dc53bc030847192e2f585}
This was a really fun forensic challenge, it felt overwhelming at first not being that familiar with Wireshark, only ever used it a few times with HTTP requests and had no knowledge of the USB protocol.
Despite that I managed to finish the challenge it time, I hope I retain something from this challenge. Only time will tell, maybe for Fetch the Flag 2026.
Comments (0)