Loading...
Skip to Content

Hacking for Betterment - Analogue Pocket

Recently we received an amazing masterpiece of hardware, a tribute to portable gaming and a homage to all kids of the 80's & 90's - the Analogue Pocket. So, what is the best way to get familiar and have fun with such a device besides playing your favorite retro games on it? Right, hacking it.

Upon starting a new security analysis of a hardware device, we usually start by collecting all possible data in- and outputs the device offers to an enduser, without opening it or invasive altering of the hardware itself like soldering new wires to it or similar.

For the Analogue Pocket, we identified the cartridge port, a USB-C port, an IrDA interface, a microSD card slot, a GameBoy compatible link port, a 3.5mm headphone output and a JTAG port which we ignore during the necessity of opening the devices back cover to access it.

  • Cartridge
  • USB-C
  • IrDA
  • microSD
  • GameBoy Link-Cable
  • 3.5mm Headphone Jack
  • JTAG below back cover

The first thing we wanted to check out was the GameBoy compatible link port. It was unlikely to have any major flaws which would give us access to any crucial parts of the operating system since the Analogue Pocket is a extremely accurate FPGA based representation of it's supported cores and systems, so we might only have access to the loaded core system's functionalities like the GameBoy Advance multiboot feature anyway - nevertheless, curiosity won.

We ordered a third party GameBoy link-cable, cut it in 2 parts and used an Adafruit FT232H breakout board to connect the open end's wires to it which allowed us the direct communication from a desktop PC via Python. Using the fully documented protocol descriptions for the GBA's multiboot feature, we were able to quickly boot a small ROM on the Analogue Pocket via our setup, which ran in the Pocket's GBA core context - jailed. A RAM dump achieved via a small custom GBA ROM, verified our prior guess that at least the available memory is limited to the same memory map the original Nintendo GameBoy Advance has. Let's move to the next port...

Since the headphone jack, cartridge and IrDA port may be bound to functionality made available by the Pocket's cores aswell, we moved on to the USB-C and microSD ports. Those were obviously available to the Analogue Pocket's operating system since they were used within it's user interface to access openFPGA cores, transfer data via USB from PC and so on.

The feature to transfer files via the USB-C port was added in a beta firmware after it's launch. Originally the port was only used to charge the system and communicate with the Analogue Dock - an accessory used to make the Pocket's video output available on displays supporting HDMI and allowing to connect to third party controllers via Bluetooth and 2.4G WiFi. Therefore the assumption that a newly implemented feature may still have flaws, was quite possible.

To gather first information about the USB port and it's stack underneath, we used the libusb library to establish a connection with the device and request it's USB device descriptors. These typically include, besides others: the product name, the manufacturer name, USB limitations like the maximum packet size to be processed, and a dozen of more data.

Going further, we tested several fuzzing techniques via a simple libusb python application but quickly realized that if we wanted to go in-depth, the limitations of the common USB implementations offered by the major operating systems like Windows and Linux are not too easy to bypass and we wanted to avoid the complexity of USB Raw Gadgets.

Nevertheless, even tho this allows easy sniffing of the traffic for debugging purpose thanks to Wireshark aswell, the more comfortable approach was to switch the hardware we use to communicate with the Analogue Pocket to a more "basic" platform with an even more basic implementation of the USB host mode. Teensy 4.X + USB Host Cable or Arduino Mega 2560 + USB Host Shield Rev.2 seemed appropriate - we went with the latter.

First things first - removing the limitations of the standard USB protocol by patching the library used by the USB Host Shield was quite easy and opened way more room for testing. Since we want to know how the device USB stack reacts in cases which are normally out of scope to trigger unknown behaviors, we patched anything we can from allowing custom sizes for the USB SETUP packet, over unsupported length values, up to default flow breaking packets which the client stack does not expect.

More details...
Patching the USB Host Shield 2.0 library is as easy as follows:
  1. Install the library via Arduino IDE -> Manage Libraries
  2. Find Usb.c and Usb.h in your Arduino library folder (On Windows: %userprofile%\Documents\Arduino\libraries\USB_Host_Shield_Library_2.0)
  3. Copy and create a modified version of the default functions like uint8_t USB::ctrlReq
  4. Make sure to add your new function in the header file aswell
  5. Profit

Since the USB descriptors already gave us some info about the manufacturer of the USB stack; which luckily is open source, we had some initial targets to test, based on information gathered from the source and now possible of being tested thanks to removed limitations. This lead us to several abused behaviors, resulting in crashes of the Analogue Pocket's USB stack which also caused the whole system to panic and show us a nice "blinky screen".

Fuzzing our way through all possible tests and combinations of packet structures, at some stage we noticed that we were able to move data back and forth in memory, which was obvious during normally fixed USB descriptor strings being overwritten when we checked them. Calculating the movements in memory, adding some more grip to our tests brought us to very specific test cases with comparisons possible to evaluate what happens on client stack side.

The next logical step was trying to inject defined data into the Pocket's memory which would lead to either information disclosures by moving memory to visible area in the USB descriptors which we can output easily or modifying the system memory in a way which may unlock new functionalities to go further with. One of example of such an unlock was, that we were able to unlock hidden menu entries in the user interface of the Analogue Pocket.

Down the SCSI rabbit hole

While digging deeper into the Analogue Pocket's USB stack, we noticed that the device exposes itself as a USB Mass Storage device using the SCSI transparent command set — the same protocol layer that virtually every USB thumb drive, external hard disk and card reader relies on. This caught our attention: the SCSI command interface is notoriously complex, and many embedded implementations only cover the happy path.

We began systematically crafting malformed SCSI commands — manipulating Command Block Wrappers (CBWs), sending unexpected operation codes, lying about transfer lengths, and violating the Bulk-Only Transport state machine. The Analogue Pocket's firmware handled some of these gracefully, but others revealed interesting behaviors: buffer over-reads, stalled endpoints that could not recover, and inconsistent error handling between different SCSI operation codes.

This line of research made us realize that the attack surface was not unique to the Analogue Pocket at all — it was structural to how many devices implement USB Mass Storage. We started testing the same techniques against other consumer devices and found similar weaknesses. That broader investigation eventually led us to develop BlackLeak, our proof of concept for CVE-2024-30212, which demonstrates how a malicious USB device can exploit flaws in SCSI command handling to leak sensitive data from a host system. What started as curiosity about a gaming handheld's USB port turned into a CVE affecting a much wider class of devices.

We reported all identified bugs and vulnerabilities to Analogue Inc., which responded very professional and super kind. As a token of appreciation for our report, they sent us a extraordinary cool present package containing a Analogue Dock and a Analogue Developer Kit - free of charge. Being left with new hardware, we wonder what secrets the Analogue Dock might hold...

BlackLeak - CVE-2024-30212
Your Image Description
Further Resources:
  • http://problemkaputt.de/gbatek-index.htm
  • https://www.beyondlogic.org/usbnutshell/usb6.shtml#SetupPacket
  • https://www.analogue.co/support/pocket
  • https://github.com/felis/USB_Host_Shield_2.0/
  • https://github.com/akkera102/gba_01_multiboot
  • https://libusb.info/
  • https://github.com/Fehr-GmbH/blackleak
  • https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-30212
  • https://www.usb.org/document-library/mass-storage-bulk-only-10