Decoding Mixed Case USB Keystrokes from PCAP

During a recent assessment, I captured USB keystrokes as a part of a larger set of data from a system.  I spent a few hours fussing over the packet capture in Wireshark, trying to make sense of it, only to figure out later that I didn't need that data to complete the assessment.  However, the spark of curiosity was lit, and I had bookmarked the HID usage tables, and two different writeups on it.

Later, I was presented with a fun CTF-style challenge where I was again presented with a USB packet capture, and instructed to find the flag in the pcap.

The relevant packets I was looking for in the pcap were the "URB_INTERRUPT in" packets from the source keyboard, which can be isolated with the filter usb.transfer_type == 0x01.  Looking at the Leftover Capture Data, there will be a series of 8 bytes strung together.  That third byte is the Usage ID for the key pressed (note this is not the same code as the ASCII hex value for the letter)

With that, I could add the Leftover Capture Data as a column (by right-clicking on one of the entries, and selecting "Apply as Column") then File -> Export Packet Dissections -> As CSV, open the resulting file, cut the capture data column out and the double-quotes, and the first line that says "Leftover Capture Data"
I learned a much easier way when researching this write-up was to use tshark to extract the leftover capture data (be sure to pipe to tr -d : to get rid of the colons in the output.  Redirect output to a text file, once you've confirmed it looks good.

I followed the steps in the writeups that I found, and after some trial and error I realized that they both left out a step in their decoding of the key map, which I needed in order to solve my case-sensitive flag. The first byte in each line is a modifyer, which can tell if Shift, Alt, or Ctrl are held while typing the key.

In the example below, the Left Shift key presents as 0x02 in the first byte (the Right Shift presents as 0x20).  You can see that the Left Shift was held down while the Usage ID 0x2D key "-" was pressed on the keyboard, meaning that the resulting letter should be "_" instead.  CapsLock is handled in a completely different way beyond the scope of this writeup, but just remember that the reverse is true when Shift is held while CapsLock is on.

So, with that, I made a new python script that will detect the shifted keys.  Instead of specifying a filename within the script, I wrote it to expect the name of the text file with the output created from the step above.

The script: