Tuesday, October 9, 2012

Emulating USB DFU to Capture Firmware

by Travis Goodspeed <travis at radiantmachines.com>,
to be presented at Breakpoint Melbourne 2012,
continuing Emulating USB Devices with Python,
with thanks Sergey Bratus and the Dartmouth Scooby Crew.

Ever since breaking the MSP430's UART BSL back in '07, I've loved attacking bootloaders, particularly those in Masked ROM. A good bootloader exploit exposes the firmware of anything using that chip, drastically reducing the amount of work I need to do on a given target. As an alternative when a bootloader exploit isn't available, I've found it handy to reverse engineer firmware updater applications to get firmware images.

Toward that end, I'm happy to announce that USB Device Firmware Update emulation is working on the Facedancer Board, so you can emulate DFU devices in order to catch firmware updates as they are sent from a USB host. In many cases, this will require a bit of patching for your specific target, but it's damned handy when you haven't got the time to reverse engineer a firmware updater.

Facedancer is an Ubertooth

In this brief article, I will explain how the Device Firmware Update (DFU) protocol works under the hood, by walking you through the one that I wrote for the Facedancer hardware. As an example target, we will be catching the firmware update for one of Mike Ossmann's Project Ubertooth boards by emulating one well enough to fool the ubertooth-dfu tool that Jared Boone has contributed to that project.

A Child's Guide to USB Device Firmware Updates, Suitable for Adults

USB DFU is a protocol for reflashing devices. By recording and replaying such an update, it is possible to port a firmware update utility to a second operating system, to patch a device's firmware, or to extract a copy of firmware for reverse engineering. If none of these things interest you, feel free to stop reading.

First and foremost, you should understand that the DFU mode is usually a secondary function of a USB device. In emulating such a device, you might need to emulate enough of its legitimate protocol that the host believes that (1) the device is the device that it intends to reprogram and that (2) the device's firmware is out of date and needs to be replaced. Exceptions include devices with a DFU recovery mode.

Second, you should know that the host might attempt to read back from the device, such as to verify that an erasure was successful. As every dialect of DFU seems to do this slightly differently, you might need to patch your implementation to support such features.

Facedancing as USB DFU

The Facedancer acts as a minimal USB Device Firmware Update emulator with the goodfet.maxusbdfu client. Typically, the command needs to be told which style of chip to emulate, where to save the output, and, optionally, what to use as the prior firmware for read attempts.

To emulate a typical victim with your Facedancer, just run 'goodfet.maxusbdfu foo bar' where foo is the hexadecimal Vendor ID and bar is the Product ID. Then plug the Victim end of your Facedancer into the target machine and order a firmware update, the blocks of which will be printed as hex to stdout.

First, we need to know the Vendor ID and Product ID of our target. These are given for the default firmware by 'lsusb' as FFFF:0004. If you are lucky, most commonly with low-volume devices, you'll find a VID/PID pair that comes from the chip manufacturer, such as 0483:DF11 for an STM32. Sometimes the device enumerates differently for DFU than for general use, so expect surprises here.

The default USB listing for the Ubertooth is below. Note that by default it doesn't show any DFU support. Support only appears when the device is put into flashing mode with 'ubertooth-util -f'.

Ubertooth lsusb

When switched into DFU mode, the device changes its USB device descriptor to indicate DFU support. Be sure to remember this when reverse engineering your own devices, as they might support DFU but not advertise it.

Ubertooth in DFU Mode

A Tourist's Phrasebook for DFU

In order to read the goodfet.maxusbdfu source code, it's handy to know at least the basics of the protocol. In this section, I'll give you an informal description of it.

DFU consists of SETUP queries, which have a standard set of header parameters. Some chips implement extra commands, particularly when they have too large an address space for the limited offsets allowed by the UPLOAD (2) and DNLOAD (1) commands. Generally, the bmRequestType will be 0xA1 and the bRequest will be one of the following.

bRequestwValuewIndexwLength
0x00 DETACH
0x01 DNLOADblocknumblocklen
0x02 UPLOAD
0x03 GETSTATUS0x0006
0x04 CLRSTATUS
0x05 GETSTATE0x0001
0x06 ABORT

The GETSTATE (0x05) command will often come first. The ten status from the Bluetooth's DFU client are as follows, but you can often get by with always returning the dfuIDLE (0x02) response. GETSTATE always wants a single byte as its reply, and as with the other DFU commands, all of this runs over the Setup endpoint as a Class request.

#From the ubertooth-dfu source code.
0: 'appIDLE'
1: 'appDETACH'
2: 'dfuIDLE'
3: 'dfuDNLOAD_SYNC'
4: 'dfuDNBUSY'
5: 'dfuDNLOAD_IDLE'
6: 'dfuMANIFEST_SYNC'
7: 'dfuMANIFEST'
8: 'dfuMANIFEST_WAIT_RESET'
9: 'dfuUPLOAD_IDLE'
10: 'dfuERROR'

Additionally, you'll need to support GETSTATUS (0x03) to let the host know the UPLOAD and DNLOAD requests have completed successfully. This one is really easy, just return six bytes of zeroes in response to any request.

The DNLOAD (0x01), like all others, is over Endpoint 0. Its data payload consists of the data to be written, but the address gets to be a bit complicated. Rather than give an absolute address, DFU clients merely provide a 16-bit block number in the wValue field of the Setup request. On the Ubertooth's NXP LPC1756 chip, the address is simply the base address of flash memory plus 256 times the block number. Other chips, such as the STM32, have an extra command that specifies the base address, but these commands are non-standard and will need to be implemented specific to the device.

Recap and Basic Usage

If you've followed along so far, don't worry about being a little lost. Let's step back a bit and actually capture a firmware image, using the default script. In the next section, we'll get back to the nuts and bolts in order to capture a slightly trickier update.

In one window, start the DFU emulator on your Facedancer with 'board=facedancer11 goodfet.maxusbdfu ffff 0004'. You'll see the device warm up and then appear on lsusb listings of the victim machine.

Finally, send a DFU update to our fake Ubertooth board by running 'sudo ./ubertooth-dfu --write bluetooth_rxtx.dfu'. You should see packets scroll across the screen that look like the ones below. Pipe them to a file and you'll have a record of everything that would've been written into the device, enough to make a patch or begin reverse engineering with IDA.

Facedancer DFU Emulator

Complications of Entering DFU Mode

Thus far, we've been emulating a device that is *already* in DFU mode, but in the real world, few devices ship that way.

For example, the following is an error message caused by using the naive DFU emulator script presented earlier with a VID:PID of 1d50:6000. The update script is failing because it orders the USB device to enter DFU mode, but the Facedancer doesn't know how to respond. When emulating closed-source devices, you'll run into the same issue.

Failure Entering DFU

In order to patch this issue, I looked at the emulator's log to see that it blindly accepted a vendor request without knowing what to do.

Unhandled Vendor Request in
USB

On a real Ubertooth device which appears as 1d50:6002, command 19 causes the board to disconnect and launch the DFU application, after which it reappears as ffff:0004. On more complicated devices, you might need to reply with a version number less than the one you wish to receive.

On many devices, such as those newfangled iPods and iPhones, a DFU recovery mode can be entered by holding a particular key combination. To emulate those devices, just hold the key combo and use lsusb to find the right settings for your Facedancer.

Complications of Non-Standard Extensions

If you've dealt with bootloaders before, you'll notice that quite a bit is missing from the DFU protocol as I've described it here. There's been no mention of any way to write to an address except by its block number, nor any mention of commands to erase the device or to enable protective modes. That's because these features are not standard; they are implemented differently for every host.

The STM32, for example, implements special features as writes to block 0000. If you see `BLOCK 0000 : 41' in your log, that means that the host has ordered the device to erase all of Flash memory, leaving only the bootloader that is in masked ROM. A write of 'BLOCK 0000 : 21 ef be ad de' orders the device to execute code at 0xdeadbeef.

Finally, you'll run into trouble with the DFU states, as some clients demand particular states at particular times. You can recognize this condition when goodfet.maxusbdfu repeatedly logs "Returning state of XX." Just patch the relevant code to provide the expected status, and all should be well.

Conclusion

In conclusion, I'd like to share a Cease and Desist letter that I recently received from Michael Ossmann at Great Scott Gadgets, the good neighbor who makes the Ubertooth One.

C&D from Great Scott
Gadgets

In keeping with Mr. Ossmann's strongly-worded request, I humbly ask you to solder up a Facedancer and join me in emulating all sorts of nifty devices.

Fake iPhone

As usual, patches should be sent to myself or the goodfet-devel mailing list. PCBs are available free or at cost, as described on the Ordering Page of the GoodFET Project. Assembly instructions can be found on the Facedancer11 Page.

Tuesday, July 3, 2012

Emulating USB Devices with Python

by Travis Goodspeed <travis at radiantmachines.com>
as presented with Sergey Bratus at Recon 2012
with thanks to Sergio Alverez and the Dartmouth Scooby Gang.

Not long ago, I was giving a lecture to Sergey Bratus's class at Dartmouth, where he asked me to teach the students about SPI, I2C, and the other bus protocols that are commonly found in embedded systems. When a student made the inevitable joke about Sergey's Magic School Bus, my good neighbor's eyes lit up and he exclaimed, "It's not a bus; it's a network!"

The Magic School Bus is a Network!

A bottle of Laphroaig 18 later, we came to the conclusion that while libusb and python-usb make it easy to prototype USB host-side applications, there wasn't really anything handy for prototyping device-side applications. So the next afternoon, we wired a MAX3421 EVK into the GoodFET41. This allows us to write USB devices entirely in host-side Python, fuzzing for device-driver vulnerabilities wherever we like.

Unlike the Teensy and similar hardware, this tool is not designed to run standalone. All of the complicated software is in Python on one workstation, while the emulated USB device appears on a second workstation. This makes fuzz testing and exploit debugging a hell of a lot more efficient, while the resulting exploit can be ported to run as C firmware for deployment.

GoodFET Does USB

Introducing the Facedancer Board

Our rough prototype was refined into a single board, which is documented as the Facedancer10 as part of the GoodFET project. The board consists of a GoodFET41 with the MAX3420 target onboard. One USB Mini plug runs to the workstation emulating a USB device, and the other USB Mini plug runs to a second host which sees only the emulated device.

Facedancer10 Prototype

The C firmware running on the MSP430 is intentionally kept as minimal as possible, with complexity pushed to the Python client in order to speed development and prevent the need for reflashing during development. This is perfectly fine for emulating USB devices, as kernels seem very tolerant of delays in responses. Additionally, the MAX3420 handles all fast-reaction timings itself, so our round-trip overheads don't create any serious problems.

To learn how the chip functions, read the MAX3420E Programming Guide and similar documents from the MAX3420E Page of Maxim's website.

Maxim MAX3420E

Learning USB

As a networking protocol, USB is quite different from the IP protocols that you are likely familiar with. It is not more difficult, but it is designed along different lines, with a different philosophy and different concepts. To learn the language, I recommend a mixture of reverse engineering devices, writing drivers, and writing emulators. Sniff some traffic with Wireshark, VMWare, or a Total Phase Beagle, then read it and try to write your own client in PyUSB. A good tutorial on that can be found in Adafruit's page on Hacking the Kinect.

In all of this, remember that USB is a network, not a bus. You can be just as 1990's stack-evil as you like, and a lot of the 90's tricks still work in USB. Every device driver included in the operating system is the equivalent of an open port!

Clear code examples for USB protocols can generally be found either in other microcontroller implementations or in the relevant BSD or Linux drivers. In general, you need to know just enough of the SETUP endpoint (EP0) to get the driver to select and initialize the device, then the packets will begin flowing over the other endpoints. There are exceptions, but generally this traffic flows through a device-specific protocol on two more endpoints, one of which is bulk-in and the other bulk-out.

HID Keyboard Emulation

As an example, I've included in the GoodFET repository a script which emulates a simple keyboard through the USB HID protocol. It's run with 'goodfet.maxusbhid', but the bulk of the code is found as the GoodFETMAXUSBHID class in GoodFETMAXUSB.py. The important thing to keep in mind when working from this code is that you are speaking a real protocol, USB HID. You are speaking it over a real chip, the MAX3420. Look up the documentation for both of those if anything is confusing, and look for code examples if things are still unclear.

The HID emulator is a more or less literal translation to Python of Maxim's example code, with much of the code devoted to handling device configuration and descriptor passing. Just like the original, some array boundaries aren't checked, so you can expect a crash or two if the host says things it oughtn't. Exploiting this code in a real product is left as an exercise for the reader.

The first descriptor is the Device Descriptor, which is defined like so. Notice that everything is in Little Endian notation. The maximum packet length is defined as 64 bytes, which is a common maximum and the one supported by the MAX3420.

DD=[0x12,           # bLength = 18d
    0x01,           # bDescriptorType = Device (1)
    0x00,0x01,      # bcdUSB(L/H) USB spec rev (BCD)
    0x00,0x00,0x00, # bDeviceClass, SubClass, Protocol
    0x40,     # bMaxPacketSize0 EP0 is 64 bytes
    0x6A,0x0B,      # idVendor(L/H)--Maxim is 0B6A
    0x46,0x53,      # idProduct(L/H)--5346
    0x34,0x12,      # bcdDevice--1234
    1,2,3,          # iMfg, iProduct, iSerialNumber
    1];

After the Device Descriptor comes the much longer Configuration Descriptor, which defines this device as being a Human Interface Device. For all vendor-proprietary protocols, the idVendor and idProduct fields of the Device Descriptor define the driver to be used. For standard devices, and HID devices in particular, it's the Configuration Descriptor that tells the operating system to treat the device as a keyboard in addition to whatever else it might be.

The Configuration Descriptor also describes endpoints used by the device. Our HID example has just one IN endpoint on EP3. EP3 was used instead of EP1 or EP2 because in the MAX3420, endpoint directions are hardwired. EP0 is implicitly the endpoint used for configuration; it's the one that the descriptors are transmitted across. EP1 and EP1 are hardwired as OUT endpoints.

Finally, you will see a set of String Descriptors used to describe the product. Roughly speaking, these are Pascal strings beginning with a length and a type, followed by UTF16 bytes. The iMfg, iProduct, and iSerialNumber entries in the Device Descriptor are indexes to this table. In C firmware, it is rather common to find a memory leak when string table entries are requested out of range. More on this bug in a later post.

FTDI Emulation

While HID is a favorite first example for USB, it's not very closely related to the devices you'll see in the field. For one thing, it only uses a single IN endpoint and no OUT endpoints. For another, there are dozens of open source firmware implementations already available. As such, I've also included an emulator for the FTDI chip, which I based upon the documentation in OpenBSD's uftdireg.h and a few quick peeks at the Linux equivalent.

To get up to speed quickly on this emulator, which is found in goodfet.maxusbftdi, compare its class GoodFETMAXUSBFTDI to that of GoodFETMAXUSBHID. In order to load the FTDI driver, it was necessary to change the idVendor and idProduct values to any of those in the FTDI driver's massive list. The strings are for the user's convenience only, so they could have been left unchanged.

Also worth noting is that the FTDI chip requires both IN and OUT endpoints to function, and that the exact endpoints must be specified in the Device Descriptor.

FTDI Emulator

The screenshot above shows goodfet.maxusbftdi emulating an FTDI chip, which a Linux workstation has enumerated as /dev/ttyUSB1. Catting that device returns text through the virtual serial port of a virtual USB chip.

Bugs Abound!

The bug below has already been fixed, but it's worth mentioning that I accidentally got heap corruption in libusb before I got to Hello World with my keyboard emulator. Intentional fuzzing ought to provide all sorts of neighborly results.

lsusbcoredump

Another fun one was found by a Chrome OS developer, and it involves a format string vulnerability in X11's logs. Any devices with a few %n's in its device or manufacturer string will crash X11. You can find example code for doing this on AVR at Kees Cook's Blog. While this probably isn't exploitable on a modern machine due to hardening, there are plenty of embedded ARM devices that could suffer code execution from it.

Finally, be sure to look for consumer apps that crash from USB devices. I've no idea why the hell Skype is watching USB devices, but I do know that it falls over when HID descriptors are fuzzed.

Facedancer in Action

Scapy Integration

Ryan Speers, one of the neighbors with whom I invented the Packet-in-Packet attack, has already begun to write Scapy models for USB. Not only that, but he managed to document it before I got around to publishing this, so you can find his description on his blog. As I write this, it's in the contrib section of the GoodFET repository, but I expect him to integrate it into scapy-com as soon as stability allows.

Host Mode

While the Facedancer10 does not contain hardware for USB Host mode, software support is included for it in GoodFETMAXUSB.py. The hardware, shown below, consists of a MAX3421 development kit wired into a GoodFET41. Generally, pyusb in a real workstation can do everything that you'd need in attacking or proxying a USB device, but there are a few select cases in which you would want host mode from a GoodFET. In particular, it's handy when actions crash the victim device repeatedly, as the GoodFET has no operating system to make re-enumeration slow.

GoodFET as a USB Host

Conclusions

The Facedancer hardware extends the GoodFET framework to allow for fast prototyping and fuzzing of USB device drivers. Software connect/disconnect allows the enumeration process to be repeated, and Ryan's fork allows for clean coding of the various data structures with Scapy.

You can order Facedancer and GoodFET boards by following the instructions on the GoodFET Ordering Page. We're happy to send them out for free to the funemployed, but please properly format your shipping address.

Soon enough, I'll be publishing scripts for "portscanning" a host to see which devices are supported, a USB Mass Storage emulator for attacking filesystem drivers, and a whole host of other nifty tools. Feel free to implement them first, and send a neighborly email to the goodfet-devel mailing list when you do.

Thursday, February 23, 2012

Wardriving for Zigbee

by Travis Goodspeed <travis at radiantmachines.com>
with kind thanks to @fbz, @skytee, and their Hacker Hostel.

While I don't do much on-site work these days, it's always fun to pull out a packet sniffer for a weird protocol and show a client how much cleartext is bouncing around his facility. It's even more fun in the vendor room of a conference. Toward that end, I made a Microsoft Keyboard Sniffer in September that forwards keyboard traffic to my Nokia N900. (By the by, Microsoft still refuses to issue an advisory for that bug.)

A few months and a new phone later, I found myself doing the same thing for ZigBee/802.15.4. The result, presented in this article, is a complete wardriving solution for my Nokia N9, allowing for efficient mapping of ZigBee usage when walking or driving. This lets me to map networks similar to the irrigation and city bus networks that KF identified, but for any of the cities that I pass through.
Zigbee Wardriving

Hardware


Just as I last used the Next Hope Badge for its nRF24L01+ radio to sniff Microsoft's keyboard traffic, the new device uses a MoteIV TMote Sky, better known in some circles as a TelosB. These flooded every university campus four years ago, and you can probably pick a few up for a cup of coffee with a neighborly professor.
Pocket ZigBee Sniffer

The TelosB has a 10-pin expansion port exposing UART0's RX and TX pins, as well as AVCC and GND. Running these lines to the Roving Networks RN42 module provides an RFCOMM connection at 115,200 baud, coincidentally the same default rate used by the GoodFET firmware. Be sure to swap RX and TX for a proper connection.

Finally, a LiPO battery and charging circuit were soldered in to replace the AA batteries of the original TelosB. This allows for quick recharges and several days of battery life.

In use, I either leave the box in my jacket or put in on the dashboard of a car. The Lego Duplo case keeps all components together, and the SMA jack allows for an antenna external to the car. (Not that I ever stay in one city long enough to buy a car, but surely one of my neighbors has a convenient external 2.4GHz antenna for me to wire into.)
Zigbee Wardriving

Firmware


The GoodFET firmware natively supports the TelosB, as described here. Firmware is normally compiled by running "board=telosb make clean install", but a second board definition exists to use the external serial port instead of the internal one. So set board=telosb for local use and board=telosbbt for use over Bluetooth. Luckily both the TelosB and the RN42 module default to 115,200 baud.

This image exposes both the TelosB's CC2420 radio and its SPI Flash chip to the host. The host also has the authority to load and execute code in the device, so a standalone mode that writes recorded packets to the SPI Flash is a distinct possibility.

Standard Client


The standard GoodFET client works as expected, once py-bluez is manually installed and Nokia's DRM infrastructure, Aegis, has been disabled. To use a Bluetooth device instead of a serial port, just set the GOODFET environment variable to the appropriate MAC address.
GoodFET on the N9

Custom Client


The standard GoodFET client is written in Python, in a style where most of the guts are exposed for tinkering. This is great for doing original research on a workstation, but it's terrible when trying to show off a gizmo in a bar or at a client site. For this reason, I hacked together a quick client in QT Quick using my reverse engineered SPOT Connect client as a starting point.

The interface is composed of a Bluetooth selection dialog, a packet sniffer, and a packet beaconing script that repeatedly broadcasts a sample Packet-in-Packet Injection.
N9 ZigBee Sniffing (cropped)
GoodFET for Meego

A log is kept in the N9's internal storage, so that any captured packet can be fetched later. The log is append-only, with a record of every received packet and timestamps from each start of the application. Additionally, GPS positions are dumped for positioning.

Plotting


The position log is then translated by a script into the Keyhole Markup Language or any other GIS format for plotting.
Wardriving for Zigbee

KML is simple enough to compose, with the one oddity that longitude comes before latitude. Use the <Placemark> and <Point> tags to mark packets. For small data sets, I've had luck using <LineString> to mark my path, but after touring much of North America, I exceeded Google Maps hundred-thousand line limit.
KML Point

Post processing is frequently needed to smooth out a few erroneous GPS positions. I've collected GPS locks up to twenty kilometers from my real position when indoors and, in one instance, my phone believed itself to be in Singapore while I was actually in the USA. Be sure to check for these when making your own maps.

Conclusions


Now that I have a lightweight system for grabbing Zigbee packets in the wild, I'd like to expand my collection system to vendor proprietary protocols such as TI's SimpliciTI, the Turning Point Clicker, and other protocols that the GoodFET stack supports. I could also use it to map neighbors with the CCC's r0ket badge and similar OpenBeacon transmitters as they stray from the conference venue.

Other protocols, however, are a lot harder to wardrive. While my Microsoft keyboard sniffer can sniff traffic to the phone, it requires a learning phase that is too long to be performed while travelling in a car. This is because the keyboard protocol, unlike Zigbee and more like Bluetooth, has a Start of Frame Delimiter (SFD/Sync) that is unique to each keyboard/dongle pair, requiring special techniques for any promiscuous sniffing. The original Keykeriki exploit by Thorsten Schröder and Max Moser might identify keyboards quickly enough to be performed on the road, or there might be some new trick that will make it possible. For now, though, you'll need to know where the keyboard you'd like to attack is before you can start sniffing it.

While I'll stubbornly stick to Meego for the foreseeable future, an Android client should pop up sooner or later. Also, Mike Kershaw seems to be toying around with full-custom hardware for the job that'll be compatible with the GoodFET firmware. You can find the code for my client in /contrib/meegoodfet of the GoodFET repository.

As a final note, Zigbee traffic can be found just west of 40th Street in West Philadelphia, at Union Station in DC, in the Fort Sanders neighborhood of Knoxville, and at South Station's food court in Boston. In Louisville, Kentucky, search near the intersection of Lexington Road and Grinstead Drive. In Manhattan, try Seventh Avenue just south of Penn Station.

Have fun,
--Travis