mephi42: (Default)
mephi42 ([personal profile] mephi42) wrote2019-09-26 08:41 pm

Teaser Dragon CTF 2019 - PlayCAP

Given an on-screen keyboard and a Nintendo Switch Pro Controller USB traffic capture in pcapng format, determine what was typed.


Attempt #1: opening the pcapng file in Wireshark, skimming the HID spec and trying to understand what is going on. The capture consists of several GET DESCRIPTORs followed by tons of URB_INTERRUPTs.

According to the spec, the HID Report descriptor contains, among other things, the formats of reports sent via interrupt mechanism. The following observations confirm this:


  • All report identifiers are also the first bytes of URB_INTERRUPT payloads

  • Almost all URB_INTERRUPTs contain report 0x30, which is related to button states



Here the luck ends. According to the descriptor, report 0x30 should start with 10 bits corresponding to button states. In reality it starts with some kind of timestamp byte.

Attempt #2: dumping URB_INTERRUPT payloads using pyshark and trying to figure out what byte means what. No luck - bits appear to change randomly.

Attempt #3: googling for Nintendo Switch Pro Controller reversing topics, finally finding the proposed Linux Kernel patch, which contains:

> +struct switchcon_input_report {
> +       u8 id;
> +       u8 timer;
> +       u8 bat_con; /* battery and connection info */
> +       u8 button_status[3];


Hey, that's our goddamn timestamp. And the button statuses. Why doesn't this correspond to the HID Report?!

Writing a small python script that tracks bit flips and correlating its output with the keyboard confirms that switchcon_input_report does indeed correctly describe the packet format. It takes a few minutes to guess which bit corresponds to which button without looking at the spec (ain't trusting it no more).

Using this knowledge to update the script to also track x/y coordinates reveals the flag.

Other writeups:


Lessons learned:


  • Don't blindly trust what you think the spec is saying

  • Don't be shy to google a little bit more