Design Solutions Research & Design Hub

USB Attacks and More with GreatFET

Written by Colin O'Flynn

Facedancer Fun

A new open-source hardware tool has been released, called the GreatFET. It can be used for a variety of purposes, including performing all sorts of low-level work on the USB protocol. Beyond just raw USB, it also works as an interface for SPI, UART, I2C and other protocols. In this article, Colin discusses how you can get started using the tool.

This month I’m looking at a new(ish) open-source tool useful for embedded security research. This particular tool is called GreatFET One, and is made by Great Scott Gadgets. The main board is shown in Figure 1. You might be more familiar with this company—or its founder Michael Ossman—because it produces the popular HackRF Software Defined Radio (SDR).

FIGURE 1 – Photo of the GreatFET One main board

GreatFET is an extension of a tool started by Travis Goodspeed, called the GoodFET. The original tool was an open-source JTAG programmer for Texas Instruments (TI) MSP430 microcontrollers (MCUs). Later iterations become something called Facedancer, which is used for working with USB devices. Facedancer enabled interesting research into what happens if a USB device misbehaves. For example, what if the USB drive plugged into a public photo printing kiosk could exploit flaws in the USB stack of that kiosk to take control of it?

GreatFET extends the hardware that made Facedancer possible by having a platform that provides two USB ports that can serve as host or device and then lots of I/O. The general architecture of the platform is shown in Figure 2. For a general-purpose “hacking tool” you might notice there is no specific connectors in this platform such as an IR interface, a CAN interface or a SPI flash connector. The idea of GreatFET is that “neighbors” can be added on top, giving this tool an ability to interface with almost anything out there.

FIGURE 2 – The base GreatFET board has a simple architecture that allows access to many features of the NXP LPC4330 MCU.

But just telling you the tool can do “anything” sounds more like a bullet-point on a marketing slide than useful content. So, I’m going to walk you through a few examples of specific interesting work you could accomplish with this tool, and what to look forward to in later firmware and software releases

The first examples I’ll discuss are actually part of the Facedancer project. Facedancer refers to the project on GitHub [1] that uses the GreatFET as a backend. Much of the USB functionality actually applies across multiple devices (not just the GreatFET), but the GreatFET is one of the easier options to get if you want Facedancer functionality. Although you can build your own GreatFET One from scratch—being fully open-source hardware)—it’s also available in stock worldwide if you are lazy (like me) and don’t want to build your own.

USB DEVICE EMULATOR
The GreatFET can serve as a USB emulator. If you’ve done USB development you know that getting a simple USB device up—such as a serial port, USB mass storage or similar—often requires diving into the specific USB stack on the MCU you are using. With Facedancer, this is all done through Python instead. You can easily change the functionality of the USB device you are emulating using just simple high-level Python changes.

— ADVERTISMENT—

Advertise Here

An example of a snippet of the mass storage configuration is shown in Listing 1. You’ll notice things like the size of USB endpoints and what happens on reads or writes is all configured over Python. Having such a flexible USB device has many uses. You’ll find it useful for embedded research (what if we request too much data?) Meanwhile, as a developer, you’ll find it useful for validating whether you’ve properly handled invalid conditions.

LISTING 1 – All the USB configuration is done via Python, giving total flexibility into even the endpoint configuration, for example.

self.ep_to_host = USBEndpoint(
3, # endpoint number
USBEndpoint.direction_in,
USBEndpoint.transfer_type_bulk,
USBEndpoint.sync_type_none,
USBEndpoint.usage_type_data,
64, # max packet size
0, # polling interval
None # handler function
)

dclass = USBMassStorageClass()

USBInterface.__init__(
self,
0, # interface number
0, # alternate setting
dclass, # interface class: Mass Storage
6, # subclass: SCSI transparent
0x50, # protocol: bulk-only (BBB)
0, # string index
verbose,
[ self.ep_from_host, self.ep_to_host ],
descriptors
)

You can also use the USB emulator to serve as a “magic device type” to give new functionality to old equipment. For example, some test equipment added USB support for saving data files to USB drives. The first problem is sometimes old devices only work with smaller drives, which can be hard to find now. Luckily you can emulate those old drives with GreatFET and not worry about such problems. The second issue is you might want to be logging that data onto a network instead, and maybe the device has no network interface. With GreatFET you can now emulate a mass storage device, while, in reality, the data is getting saved to a network-accessible location.

USB emulation can serve all kinds of other useful tasks too. You can emulate a USB keyboard to send boot sequence commands to a headless computer, or emulate a USB mouse to prevent a device from going to sleep.

Just telling you how you can use USB emulation to keep your old test equipment working wouldn’t fit the scope of this article. Don’t worry, there is lots of security-focused uses as well. A great overview of them was given in a presentation by Dominic Spill & Kate Temkin called “Opening Black Box Systems with GreatFET + Facedancer” [2]. One cool example from this is a device that did a firmware update over USB. The logic for the host device (the target of the attack) is shown in Figure 3. You can see the logic reads the file, validates a signature and then if the signature passes, flashes that firmware into the device. But in the process, it re-reads the firmware from the USB drive!

FIGURE 3 – A device receiving a new firmware file by a USB flash drive can be attacked. This is done by emulating the flash drive to swap the firmware file to a malicious version after the original version passes validation checks.

Because we’re emulating the USB drive, it’s trivial for us to swap out the legitimate firmware for something nefarious. Now the device thinks the firmware will be OK, and flashes it onto the system. If no more verification is done on boot, the device will boot the incorrect firmware.

USB INTERPOSER AND HOST
Another unique feature of GreatFET is its ability to serve as a USB interposer. Remember PhyWhisperer-USB that I described in my column in Circuit Cellar 352 (November 2019) that could sniff USB traffic? Rather than just doing that, you can use GreatFET as both a USB device connected to a target computer and as a USB host stack driving a target device.

Because the GreatFET is a complete USB stack, you can do more than just modify specific packets in-flight. You can interject completely new requests to either the device or host, or block certain requests. When evaluating security tokens, this can be useful since you can modify requests in-flight, or even forward requests from one device to another device.

— ADVERTISMENT—

Advertise Here

In the previous example of attacking the firmware from Figure 3, the interposer mode would let us confirm that the USB firmware is read twice in a row. We could then potentially even interject our own malicious firmware for the second read.

Of course, we can also use the GreatFET USB host to send specific commands to the target device. This requires a micro USB OTG cable adapter to change the micro USB connector on the GreatFET into the more common “Female A” connector. With that, you can plug any standard USB device into the GreatFET. In Figure 4, I’m working on the Trezor Wallet that I featured in my column in Circuit Cellar 346 (May 2019). I’m using it as a basic sanity check for the built-in host script shown running in Listing 2, which prints the expected VID/PID pair and additional information. The output of this script is given in Listing 3. Using the GreatFET is a perfect way to trigger the type of fault injection attacks I talked about in my May 2019 column, because it provides you total control of what is sent to the device.

FIGURE 4 – USB Wallet attached to the GreatFET One, where the GreatFET One is working as a USB host.

LISTING 2 – A simple example of configuring GreatFET as a USB host device using the Facedancer project

from facedancer import FacedancerUSBHostApp

# Enumerate and configure the attached device.
u = FacedancerUSBHostApp(verbose=3)
u.initialize_device(assign_address=1, apply_configuration=1)

# At this point, we can perform whatever communications we need to to use the target device.
# Usually, this is accomplsihed using the send_on_endpoint and read_from_endpoint functions
# for non-control requests, and the control_request_in and control_request out functions
# for control requests.

# Print the device state.
print(“Device initialized: “)
print(“\tDevice is: {}”.format(“Connected” if u.device_is_connected() else “Disconnected”))
print(“\tDevice speed: {}”.format(u.current_device_speed(as_string=True)))

# Print information about the attached device...
print(“Attached device: {}”.format(u.get_device_descriptor()))

# .. and its configuration.
configuration = u.get_configuration_descriptor()
print(“Using first configuration: {}”.format(configuration))

for interface in configuration.interfaces:
print(“\t - {}”.format(interface))

for endpoint in interface.endpoints:
print(“\t\t - {}”.format(endpoint))

LISTING 3 – The output of running Listing 2 with a Trezor USB wallet attached in bootloader mode is shown here.

Using GreatDancer Host backend.
Device initialized:
Device is: Connected
Device speed: Full speed

Attached device: <USBDevice object; vid=0x1209, pid=0x53c0>
Using first configuration: <USBConfiguration index=1 num_interfaces=1 attributes=0x80 max_power=100mA>
- <USBInterface number=0 alternate=0 class=class 255 subclass=0 protocol=0 string_index=0 endpoints=[1, 1]>
- <USBEndpoint number=1 direction=IN transfer_type=3 sync_type=0 usage_type=0 max_packet_size=64 interval=1ms>
- <USBEndpoint number=1 direction=OUT transfer_type=3 sync_type=0 usage_type=0 max_packet_size=64 interval=1ms>

CLASSES AND VERBS
If you check out the GreatFET documentation, you’ll find out it has the idea of classes and verbs. Different functionality is encapsulated in a class, and within the class it has various capabilities (verbs). The previous examples would fall into a few different USB classes such as greatdancer or usbhost. Sometimes those classes are easier to use with some higher-level support, such as the Facedancer control logic I used, but many of the classes can be easily used directly.

There is a lot you can do here from working with a SPI flash device (spi_flash), toggling some GPIO pins (gpio), working as a quick logic analyzer (logic_analyzer) and talking to some peripheral devices (spi and i2c). There’s a lot of other features like working as a serial UART cable, analog measurements and programming MSP430 MCUs with JTAG, for example. Again, the entire project is fully open source, so it can be extended to support new devices and protocols relatively easily.

A simple example of talking to an SPI peripheral is shown in Listing 4. In this example, I’m using the greatfet shell command to give me an interactive Python console, and reading the ID of an attached SPI flash by sending the 0x9F command, using the hardware setup shown in Figure 5. Note here I’m connected to an in-circuit SPI flash device, which requires me to hold the MCU on the target board in reset. Otherwise the MCU on the target board might also try to exercise some of the I/O lines!

$ gf shell
In [1]: gf.spi.transmit([0x9F, 0xFF, 0xFF, 0xFF])

LISTING 4 – A few lines of Python are sufficient to read the device ID of an attached SPI flash memory.

FIGURE 5 – Attaching to a SPI flash chip on-board an IoT device

One trick up the GreatFET sleeve is provided by the LPC4330 parallel data capture feature. This feature allows NXP Semiconductors’ LPC4330 MCU to capture parallel data on a bus interface and write it directly into internal memory—and thus download over USB as well. This feature is used to provide a simple logic analyzer that can run alongside other commands.

This means that, with a single GreatFET device, I could sniff the SPI traffic on a logic analyzer along with performing the actual SPI data transactions. This requires wiring the SPI data lines to the SGPIOn pins, which I can then use the logic_analyzer backend to record data with.

The parallel data capture feature allows a lot of interesting future use cases. For example, an extremely low-cost USB sniffer is possible since you could actually record low/full-speed USB 2.0 traffic! This would be similar to the architecture of the PhyWhisperer-USB I presented in November 2019, except without the FPGA—which is the most expensive component. Kate Temkin already has a beta of a neighbor (add-on board) called Rhododendron that provides this feature to GreatFET. Keep an eye out for its full release.

FIRST HOUSE ON THE BLOCK
GreatFET is still a relatively new project, so you might find many features aren’t yet well documented. You’ll also notice there are many planned neighbors (add-on boards), with only a few in active release currently. Keep an eye out for the rest of 2020 as this project continues to evolve. But if the examples I’ve talked about in this article sound interesting, I suggest trying to dive into it now and see how you can use GreatFET. The hardware itself has been finalized for some time, so being the first house on the block might just mean waiting for updated firmware and documentation to perform the task you need—or even adding the feature yourself. And as new neighbors move in, you’ll just continue to get more functionality!

— ADVERTISMENT—

Advertise Here

While I don’t discuss a lot of generic tools in this column, GreatFET has some unique features. It even allows you to more directly explore USB commands. This type of tool is useful for both development and usage of USB stacks (both host and device side), along with security testing of your USB products. You can also see the link back to a few of my previous articles, and how the GreatFET functionality would have simplified the projects I presented.

Hopefully you found some of these examples useful, and it gave you some ideas for what you might be able to do with this new open-source tool. Happy hacking! 

RESOURCES

See article code archive for code for this article.

References:

[1] https://github.com/usb-tools/Facedancer
[2]  https://greatscottgadgets.com/slides/TR18_AR_RE-Black-Box-Systems-GreatFET-Facedancer.pdf

Great Scott Gadgets | www.greatscottgadgets.com
NXP Semiconductors | www.nxp.com
Texas Instruments | www.ti.com

PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MARCH 2020 #356 – Get a PDF of the issue


Don't miss out on upcoming issues of Circuit Cellar. Subscribe today!

 
 
Note: We’ve made the October 2017 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.


Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Become a Sponsor
Website | + posts

Colin O’Flynn, writes the column Embedded System Essentials for Circuit Cellar. Colin has been building and breaking electronic devices for many years, and is currently completing a PhD at Dalhousie University in Halifax, NS, Canada. His most recent work focuses on embedded security, but he still enjoys everything from FPGA development to hand-soldering his prototype circuits. Some of his work is posted on his website.