The challenge begins with 2 files, a USB packet capture and memory dump. Analysing the memory dump with Volatility shows it’s a Windows image, most likely Windows 7 SP1 64-bit based on the suggested profiles. Applying the Win7SP1x64 profile, and running the pslist module successfully extracts the list of the running processes at capture time. Analysing the list of processes for anomalies showed two processes, not present in a standard Windows 7 installation. The first was FTK Imager.exe which is a program used to capture memory contents, probably used to create the RAM dump. The second is osk.exe (On Screen Keyboard), this hints that the USB packet capture data is likely mouse movements. Using the screenshot plugin within Volatility, we can get a visual representation of the desktop at the time of the memory dump. The pseudo screenshot shows the on-screen keyboard running, in fullscreen, at a resolution of approximately 800 by 600. These values will be useful when decoding the mouse data.

Opening the USBCapture.pcap file in Wireshark shows approximately 15 hundred USB interrupts frames. These could be keyboard or mouse interrupts, but given the number of frames and fact onscreen keyboard is running, I’m leaning towards mouse movements. The most interesting aspect of these frames is the leftover capture data that Wireshark could not interpret. The leftover capture data is the only data, consistently changing within the frames, and that currently has no meaning. After inspecting the headers and finding no useful information, I decided to extract the leftover capture data for further analysis. This can be achieved using tshark.

Researching the USB protocol and URB interrupts, I couldn’t find any useful information online. So, I decided to have a crack at reverse engineering the 8 bytes myself. The first noticeable pattern I observed was that the 3rd  and 4th bytes appeared to variate as a couple, this is also noticeable on the 5th and 6th bytes. This suggests two 16-bit integers, which would make sense as mouse movements would contain X and Y properties.

When attempting to decode these numbers as unsigned integers, I found large jumps occurring between each frame. I also attempted other encoding schemes such as one complements, two complements, and signed magnitude. None of these encoding schemes represented sane mouse movement patterns. My next thought was to swap the endianness, and this did the trick. The hex values represented two unsigned integers in little endian.  Decoding the numbers in the above example gave:


The two sequences of integers ranged between 0 and approximately 32,767 (maximum 16-bit signed integer). The mouse coordinates needed to be normalized within the bounds of the screen. A simple function to perform this normalization would be:

This function could be used to normalize the X and Y coordinates into the screen bounds. Lastly, I needed to overlay the mouse movements onto an on-screen keyboard of similar dimensions to that found in the memory dump screenshot. Given we know all flags starts with BSIDES_CTF, this can be used to help calibrate the mouse movements. This last step was a bit tedious, and I chose the native method of simply taking a photo of osk.exe from the Internet, stretching it to the required dimensions and replaying the mouse movements on top of the photo, pausing when a click was detected.

The final solution written in Golang: