Thursday, September 1, 2011

Remotely Exploiting the PHY Layer

or, Bobby Tables from 1938 to 2011

by Travis Goodspeed <travis at radiantmachines.com>
concerning research performed in collaboration with
Sergey Bratus, Ricky Melgares, Rebecca Shapiro, and Ryan Speers.

20110808_001

The following technique is a trick that some very good neighbors and I present in Packets in Packets: Orson Welles' In-Band Signaling Attacks for Modern Radios (pdf) at Usenix WOOT 2011. As the title suggests, Orson Welles authored and implemented the attack in 1938 as a form of social engineering, but our version acts to remotely inject raw frames into wireless networks by abuse of the PHY layer. As that paper is limited to a formal, academic style, I'd like to take the opportunity to describe the technique here in my people's native language, which has none of that formal mumbo-jumbo and high-faluttin' wordsmithin'. This being just a teaser, please read the paper for full technical details.

The idea is this: Layer 1 radio protocols are vulnerable injections similar to those that plague naively implemented SQL websites. You can place one packet inside of another packet and have the inner packet drop out to become a frame of its own. We call the technique Packet-in-Packet, or PIP for short.

As I've mentioned in my article on promiscuously sniffing nRF24L01+ traffic, every modern digital radio has a Layer 1 form that consists of a Preamble, followed by a Sync, followed by a Body. The Body here is Layer 2, and that is the lowest that a normal packet sniffer will give you. (Keykeriki, Ubertooth, and GoodFET/NRF give a bit more.)

In the specific case of IEEE 802.15.4, which underlies ZigBee, the Preamble consists of the 0 symbol repeated eight times, or 00000000. The Sync is A7. After that comes the Body, which begins with a byte for the length, a few bytes for flags, the addresses, and some sort of data. Suppose that an attacker, Mallory, controls some of that data, in the same way that she might control an HTTP GET parameter. To cause a PIP injection of a Layer 2 packet, she need only prepend that packet with 00000000A7 then retransmit a large--but not unmanageably large--number of times. I'm not joking, and I'm not exaggerating. It actually works like that.

Below is a photograph of the first packet capture in which we had this technique working. The upper packet capture shows those packets addressed to any address, while the lower capture only sniffs broadcast (0xFFFF) messages. The highlighted region is a PIP injection, a broadcast packet that the transmitter intended to only be data within the payload of an outer packet.
20110808_003

How it works.


When Alice transmits a packet containing Mallory's PIP to Bob, Bob's interpretation can go one of three ways, two of which are depicted in the diagram below. In the first case, as shown in the left column, Bob receives every symbol correctly and interprets the packet as Alice would like him to, with Mallory's payload sitting harmlessly in the Body. In the second case, which is not depicted, a symbol error within the Body causes the packet's checksum to fail, and Mallory's packet is dropped along with the rest of Alice's.

802.15.4 PIP

The third interpretation, shown above in the right column, is the interesting one. If a symbol error occurs before the Body, within the Preamble or the Sync, then there's no checksum to cause the packet to be dropped. Instead, the receiver does not know that it is within a packet, and Mallory's PIP is mistaken as a frame of its own. Mallory's Preamble and Sync will mark the start of the frame, and Mallory's Body will be returned to the receiver.

In this way, Mallory can remotely inject radio frames from anywhere on the network to which she can send her payload. That is, this is a PHY-Layer radio vulnerability that requires no physical access to the radio environment. Read the WOOT paper for complications that arise when applying this to IEEE 802.11, as well as the conditions under which a PIP injection can succeed on every attempt.

War of the Worlds


In 1938, Orson Welles implemented a similar exploit as a form of social engineering in order to cause panic with his War of the Worlds (mp3, transcript) performance.

Recall that PIP injection works by having the victim miss the real start of frame marker, then fraudulently including another start of frame marker inside of the broadcast. As per the FCC requirements of his time, Orson begins with a real start of broadcast marker:

ANNOUNCER: The Columbia Broadcasting System and its affiliated stations present Orson Welles and the Mercury Theatre on the Air in The War of the Worlds by H. G. Wells.

(MUSIC: MERCURY THEATRE MUSICAL THEME)

ANNOUNCER: Ladies and gentlemen: the director of the Mercury Theatre and star of these broadcasts, Orson Welles . . .

ORSON WELLES: We know now that in the early years of the twentieth century this world was being watched closely by intelligences greater than man's and yet as mortal as his own. We know now that as human beings busied themselves about their various concerns they were scrutinized and studied, perhaps almost as narrowly as a man with a microscope might scrutinize the transient creatures that swarm and multiply in a drop of water. With infinite complacence people went to and fro over the earth about their little affairs, serene in the assurance of their dominion over this small spinning fragment of solar driftwood which by chance or design man has inherited out of the dark mystery of Time and Space. Yet across an immense ethereal gulf, minds that to our minds as ours are to the beasts in the jungle, intellects vast, cool and unsympathetic, regarded this earth with envious eyes and slowly and surely drew their plans against us. In the thirty-ninth year of the twentieth century came the great disillusionment.
It was near the end of October. Business was better. The war scare was over. More men were back at work. Sales were picking up. On this particular evening, October 30, the Crosley service estimated that thirty-two million people were listening in on radios.


That introduction is two minutes and twenty seconds long, and it was scheduled to begin while a popular show on another station was still in progress. Many of the listeners tuned in late, causing them to miss the Sync and not know which show they were listening to, just as in a PIP injection! What follows is thirty-eight minutes of a first act, without a single word out of character or a single commercial message from a sponsor. The play begins in the middle of a weather report, followed by repeated false station and show announcements, a few of which follow.

We now take you to the Meridian Room in the Hotel Park Plaza in downtown New York, where you will be entertained by the music of Ramón Raquello and his orchestra.
From the Meridian Room in the Park Plaza in New York City, we bring you the music of Ramón Raquello and his orchestra.
Ladies and gentlemen, we interrupt our program of dance music to bring you a special bulletin from the Intercontinental Radio News.
We are now ready to take you to the Princeton Observatory at Princeton where Carl Phillips, or commentator, will interview Professor Richard Pierson, famous astronomer.
Good evening, ladies and gentlemen. This is Carl Phillips, speaking to you from the observatory at Princeton.
Just a moment, ladies and gentlemen, someone has just handed Professor Pierson a message. While he reads it, let me remind you that we are speaking to you from the observatory in Princeton, New Jersey, where we are interviewing the world- famous astronomer, Professor Pierson.

By repeatedly lying to the listeners about the station and the program, Welles was able to convince them that they were listening to legitimate news broadcasts of an alien invasion. Ensuring that the listener missed the starting broadcast announcement breaks the encapsulation that was intended to prevent such confusion, just as a PIP injection relies upon the start of frame to be missed in order to break OSI model encapsulation.

How the hell did this happen?


This class of vulnerability is a really, really big deal. An attacker can use it to inject raw frames into any wireless network that lacks cryptography, such as a satellite link or an open wifi hotspot. Not only that, but because the injection is remote, the attacker needs no radio to perform the injection! Not only that, but this vulnerability has sat unexploited in nearly every unencrypted digital radio protocol that allows for variable frame length since digital radio began! So why did no one notice before 2011?

Packet in Packet injection works because when Bob forwards a wrapped string to Alice over the air, he is trusting Mallory to control the radio symbols that are broadcast for that amount of time. The potential for abusing that trust wasn't considered, despite communications experts knowing full well that sometimes a false Sync was detected or a true Sync missed. This is because a symbol error in the Sync field causes the packet to be implicitly dropped, with the same behavioral effect that would be had if the error were later in the packet and it were explicitly dropped. Except when faced with a weaponized PIP injection, nothing seems strange or amiss. Sync errors were just a nuisance to communications engineers, as we security guys were staying a few layers higher, allowing those layers of abstraction to become boundaries of competence.

That same trust is given in wired networks and busses, with the lesser probability of missing a Sync being the only defense against PIP injection. Just as PIP has shown that unencrypted wireless networks are vulnerable even when the attacker is not physically present, I expect wired networks to be found vulnerable as soon as an appropriate source of packet errors is identified. Packet collisions provide this in unswitched Ethernet networks, and noisy or especially long links might provide it for more modern wired networks.

If I've not yet convinced you that this attack is worth studying, I probably won't be able to. For the rest of you, please print and read the paper and extend this research yourself. There's a hell of a lot left to be done at the PHY layer, and it might as well be you who does it.

Thank you kindly,
--Travis Goodspeed




Tuesday, May 24, 2011

Practical MC13224 Firmware Extraction

by Travis Goodspeed <travis at radiantmachines.com>
as presented at CONFidence Krakow, 2011.

MC13224

Pictured above is a Freescale MC13224 chip, having been partially decapped with nitric acid in my lab. This is the chip used in the Defcon 18 Ninja Badge and the Redwire Econotag. This brief demonstrates two methods for extracting the firmware from an MC13224 or MC13226 which has been read-protected by placing "SECU" as the first four bytes of Flash memory.

Rather, pictured above are the three chips and a few discrete components that comprise the MC13224. The smallest chip is a radio balun, while the largest is a CPU+radio and the third chip is Flash memory. This brief article will present two methods for forcibly extracting firmware from a locked MC13224, the latter of which is non-invasive and requires only a bit of soldering skill.

For a more thorough discussion of the MC13224, read Akiba's MC13224 Review. In short, the strong point of this chip is its radio, which integrates analog components on chip. Literally everything except for the antenna is included, so a 50Ω trace antenna is the only external radio component. Most of these components aren't on-die, just in-package. You can see the 0402 components used in this in the photo below, which is slightly less etched than the one at the beginning of this article.

MC13224

Unlike many competing microcontrollers, the MC13224 is unable to execute code directly from Flash. Rather, a ROM bootloader copies a working image from Flash into RAM. If the security word "OKOK" is seen, then JTAG access is enabled before the bootloader branches into RAM. If the security word is instead set to "SECU", then JTAG access is not enabled and the chip remains in its default, locked state.

MC13224 CPU
MC13224 LittleMC13224 Flash (SST25WF010)

The final chip shown above is the Flash memory. Its badge is in the corner near a bonding wire, clearly identifying the chip as an SST25WF010, a SPI flash chip that aside from its low voltage is easily interfaced with a GoodFET or Arduino.
SST25WF010 Badge

The first method for recovery requires access to some rather--but not terribly--expensive equipment. First, use HNO3 or H2SO4 to remove the packaging and expose the SST25WF010 die. Then use a wedge wire-bonder to place the chip into a new package. The die has ten bonding pads while only eight pins are documented, but these can be guessed quickly enough if it is supposed that the sides of the chip are kept constant.

A second extraction technique takes advantage of the fact that, while the SPI bus is not bound out to external pins, the power and ground lines are exposed. Still better, the supply line to the SST25 has its own pin! Pin #133, NVM_REG, is the voltage regulator output for the flash memory, which is exposed in order to allow an external voltage regular to replace the internal one. In ZigBee applications, power could be saved by shutting down the SST25 after booting. This pin is highlighted below.

MC13224 NVM_REG

Given that a local attacker can control power to just the SST25 Flash chip, what would happen if he disabled the chip by cutting its power? MC1322xRM.pdf explains in Figure 3-22 on page 93 that the MC13224 will enable JTAG access then try to boot from UART1, as a SPI slave, as a SPI master, or as an I2C master. If none of these methods work, the chip will hang in an infinite loop.

So all that is needed to recover a copy of an MC13224's flash memory is a board that holds Pin 133 too low during a reset, then loads a new executable into RAM that--when Pin 133 is allowed to swing high--will read firmware out of the SST25WF010 and exfiltrate it through an I/O pin.

Toward that end, I've made a small batch of modified Econotag boards that expose this pin to a jumper. A pair of tweezers can then hold the line low during a reboot in order to unlock JTAG. Once the tweezers are removed, a client for the internal SST25 flash chip can be used through the board's built-in OpenOCD implementation to dump the firmware.

RedBee w/ SECU Bypass

Please note that the MC13224 and MC13226 are the only Freescale 802.15.4 chips with an ARM and external flash die. Both older and more recent devices use an 8-bit HCS08 microcontroller with built-in flash memory.

Freescale could certainly patch the boot behavior, but this would bring its own complications. Mandating an erase and erase-check on failure would cause the chip to self-destruct when being supplied with noisy power. Not mandating that erase would make the chip difficult to recover if improperly flashed.

But even if they were to patch the ROM behavior, successfully, the first vulnerability would still remain. The SST25WF010 chip can still be rebonded into a new package. Further, MC1322x family appears to be an evolutionary dead-end. There have been no new releases since the initial pair of chips, and Freescale's more recent designs have abandoned the ARM7 for the less expensive HCS08 core they maintain in-house.

Tuesday, March 1, 2011

GoodFET on the TelosB, TMote Sky

by Travis Goodspeed <travis at radiantmachines.com>
with kind thanks to Sergey Bratus, Ryan Speers, and Ricky Melgares,
for contributions of code, conversation, and general neighborliness.

Telos B

As I was recently reminded that the Crossbow Telos B and Sentilla TMote Sky devices litter most universities, left over from wireless sensor network research, it seemed like a perfect target. As such, I'm happy to announce that the GoodFET firmware now fully supports the Telos B and TMote, and also that support for the Zolertia Z1 mote will be coming soon. KillerBee integration should come in the next few weeks, but there's plenty of fun to be had in the meantime.

This brief tutorial will walk you through cross-compiling the GoodFET firmware for the Telos B or TMote Sky, as well as simple packet sniffing and injection. As the GoodFET project is always being refactored in one way or another, you can expect a bit of this to change.

Compiling the Firmware

A port of the GoodFET firmware is defined by three things. First, the $platform environment variable defines the header file from which port definitions come. Most platforms just use platforms/goodfet.h, which is loaded when $platform is undefined or set to 'goodfet'. Some devices, such as the two varieties of the Next Hope Badge and the Telos B, use ports which are not the same as the standard GoodFET's layout. In particular, it's rather common for the Slave-Select (!SS) line to be unique to the hardware layout of a particular board. Setting $platform to 'telosb' takes care of this.

Additionally, the Telos B uses the MSP430F1611 chip, so $mcu must be set to 'msp430x1611'. (That's with an 'x', as the linker doesn't care whether the chip is in the F, G, or C variants.)

Finally, a normal GoodFET includes a lot of modules for things like JTAG and similar protocols that the Telos B does not include wiring for. Although leaving them in doesn't hurt, it does make the firmware larger, which is annoying when repeatedly recompiling and reflashing during firmware development. To restrict support to just the monitor, the SPI Flash chip, and the Chipcon SPI radio, it is handy to set $config to 'monitor spi ccspi'.

export platform=telosb
export mcu=msp430x1611
export config='monitor ccspi spi'
make clean install


Accessing the SPI Flash

The Telos B is reset in a manner very different from the GoodFET, courtesy of a bit-banged I2C controller. Someday we'll figure out how to auto-detect this, but until then you will need to have $platform set to 'telosb' just as you did when compiling.

The Telos B contains a Numonyx M25P80 SPI Flash chip, which is compatible with the goodfet.spiflash client. Unfortunately, most units use a variety of this chip that does not respond to a request for its model number. (According to the datasheet, this feature is only available in the 110nm version. Datasheets have a way of phrasing bugs as if they were just optional features.) On those lucky units with a properly behaving chip, run 'goodfet.spiflash info' to get its capacity and model number. Upgrading to a larger chip or replacing the SMD unit with a socketed one will cause no problems, as the client will automatically adapt.

GoodFET for the Telos B

You may also use the standard peek, erase, dump, and flash verbs to access the contents of the chip. When the chip refuses to identify itself, the GoodFET will default to a size of 8Mb, so explicit ranges needed be given for things like 'goodfet.spiflash dump telosb_m25p80.bin'.

As the M25P80 chip is not access-controlled in any way, it's a handy way to grab old data from a node. On some academically-sourced devices, you might find leftover data or code from LogStorage or Deluge. On commercial devices, these chips sometimes keep hold more interesting things.

Sniffing ZigBee, 802.15.4

While the Flash chip is a neat little toy and handy for forensics, most users of the Telos B port will be interested in the CC2420 radio. As a final collaboration between Ember and Chipcon, the '2420 was one of the first popular 802.15.4 chips, and it is still quite handy for reversing and exploit ZigBee devices. Just as before, you must set $platform to be 'telosb' or the client will not connect.

To sniff raw 802.15.4 packets on channel 11, just call 'goodfet.ccspi sniff 11'. This enables promiscuous mode, so you will see traffic from all PANs and to all MACs in the region. If you are only interested in broadcast traffic, use 'goodfet.ccspi bsniff 11' instead.
goodfet.ccspi sniff 11

As much fun as it is to sit with the 802.15.4 and ZigBee protocol documentation to figure out what a packet means the first time, white-washing this particular fence quickly becomes boring. For that reason, Ryan Speers and Ricky Melgares at Dartmouth tossed together a Scapy module for dissecting these sorts of packets. It's in the scappy-com Mercurial repository, so check it out with "hg clone http://hg.secdev.org/scapy-com" then run "sudo python setup.py install" after the prerequisite packages have been installed.

Once the community build of Scapy has been installed, you can run 'goodfet.ccspi sniffdissect 11' to print the Scapy dissections of various packets. As this code is less than a week old, there are a few kinks to work out, so ignore the warning messages that pop up at the beginning of the log. (Scapy likes to initialize the operating system's networking stack even though we're using a GoodFET instead. This is infuriating on OpenBSD, but merely an annoyance on OS X and Linux.)

802.15.4 Scapy

If you have no other 15.4 equipment to play with, you can do a transmission test with 'goodfet.ccspi txtest 11'. In the following section, I'll show you to how to send and receive packets in a Python script, which is useful for talking to the myriad of wireless sensors that have less than serious security.

Scripting the CC2420

The GoodFET project is built as a number of client scripts which are written in spaghetti code, features from which are slowly moved out of spaghetti and into classes. That is to say, the heavy lifting should be in GoodFETCCSPI.py, while short and sweet client scripts will be found in goodfet.ccspi. As an example, this section will cover the functioning of 'goodfet.ccspi txtoscount' which implements the radio protocol spoken by the TinyOS RadioCountToLeds application.

Rather than go into too much detail, I'll just point out the lines that are most instructive. Just like sing-along cartoons, this only works if you read the code, so please open up your favorite editor and follow along. While you're at it, use 'svn blame' to figure out which new GoodFET developer wrote that routine. If too much time has passed, you'll also need to back up to the revision that was current when I wrote this review. Then jump back a few more revisions to figure out which bugs of mine had to be fixed before his code worked. Isn't revision control nifty?

By default, the CC2420 only receives packets addressed to the local PAN and MAC as well as those sent to the broadcast address. In order to receive promiscuously, allowing the client to automatically identify any devices on the channel, it is necessary to enable promiscuous mode with 'client.RF_promiscuity(1)'. You might also want to tune away from the default channel with 'client.RF_setchan()'.

Also, as checksums must be correct in any outbound traffic, it is necessary to enable the AUTOCRC mode with 'client.RF_autocrc(1)'. This appends a checksum to every outbound packet, and it also rejects any inbound packets with invalid checksums, which is helpful to reduce noise but would sometimes accidentally rejects packets from non-compliant devices during sniffing. (TinyOS always uses the AUTOCRC feature, so it isn't an issue in this particular application.)

Packet reception, as is standard among the radio modules, is performed by 'client.RF_rxpacket()'. This method returns None if no packet has been received, so a synchronous application ought to spin in a loop until something else is returned.

Finally, the routine needs to broadcast its own reply, either from a stock template or from the sniffed packet. This is accomplished by passing an array of bytes to 'client.RF_txpacket(packet)'.

That's really all there is to it.

Conclusions

The GoodFET is primarily a tool for reverse engineering, and integration with other tools is a priority. KillerBee and Kismet plugins are already in development, and clients for all sorts of 802.15.4 devices will be written as hardware becomes available. Support for the CC2420's AES engine will also be added, so that encrypted packets can be sniffed once keys are sniffed from the air or by syringe with a bus analyzer.

That's all folks. Grab a Telos B or TMote and start poking at devices. Good targets might include Z-Wave door locks and ZigBee thermostats.

Monday, February 7, 2011

Promiscuity is the nRF24L01+'s Duty

by Travis Goodspeed <travis at radiantmachines.com>
extending the work of Thorsten Schröder and Max Moser
of the KeyKeriki v2.0 project.

NHBadge and a Keyboard

Similar to Bluetooth, the protocols of the Nordic VLSI nRF24L01+ chip are designed such that the MAC address of a network participant doubles as a SYNC field, making promiscuous sniffing difficult both by configuration and by hardware. In this short article, I present a nifty technique for promiscuously sniffing such radios by (1) limiting the MAC address to 2 bytes, (2) disabling checksums, (3) setting the MAC to be the same as the preamble, and (4) sorting received noise for valid MAC addresses which may later be sniffed explicitly. This method results in a rather high false-positive rate for packet reception as well as a terribly high drop rate, but once a few packets of the same address have been captured, that address can be sniffed directly with normal error rates.

As proof of concept, I present a promiscuous sniffer for the Microsoft Comfort Desktop 5000 and similar 2.4GHz wireless keyboards. This vulnerability was previously documented at CanSecWest by Thorsten Schröder and Max Moser, and an exploit has been available since then as part of the KeyKeriki v2.0 project. My implementation differs in that it runs with a single radio and a low-end microcontroller, rather than requiring two radios and a high-end microcontroller. My target hardware is the conference badge that I designed for the Next Hope, running the GoodFET Firmware.

Part 1: or, Why sniffing is hard.

nRF24L01 Die

Radio packets usually begin with a preamble, followed by a SYNC field. In the SimpliciTI protocol, the SYNC is 0xD391, so the radio packets will begin with {0xAA,0xD3,0xD91} or {0x55,0xD3,0x91}. The AA or 55 in the beginning is a preamble, which is almost universally a byte of alternating 1's and 0's to note that a packet is beginning, followed by the SYNC field which makes sure that the remainder of the packet is byte-aligned.

In the case of the Nordic radios, there is no SYNC pattern unique to the radio. Instead, the MAC address itself serves this purpose. So an OpenBeacon packet will begin with {0x55, 0x01, 0x02, 0x03, 0x02, 0x01} while a Turning Point Clicker's packets will begin with {0x55, 0x12, 0x34, 0x56}. The preamble in this case will be 0x55 if the first bit of the SYNC/MAC is a 0 and 0xAA if the first bit is a 1. To make matters worse, the chip does not allow a MAC shorter than three bytes, so previously it was believed that at least so many bytes of the destination address must be known in order to receive a packet with this chip.

Moser and Schröder solved this problem by using an AMICCOM A7125 chip, which is a low-level 2FSK transceiver, to dump raw bits out to an ARM microcontroller. The ARM has just enough time to sample the radio at 2Mbps, looking for a preamble pattern. If it finds the pattern, it fills the rest of register memory with the remaining bits and then dumps them to the host by USB. In this manner, every prospective MAC address can be found. Once the address is known, KeyKeriki places that address in its second radio, an nRF24L01+, which is used to sniff and inject packets.

A similar solution is used in Michael Ossmann's Project Ubertooth sniffer for Bluetooth. See that project's documentation and Ossmann's Shmoocon 2011 video for a more eloquent explanation of why sniffing without a known SYNC is so hard.

Part 2: or, Sniffing on the cheap.
My trick for sniffing promiscuously involves a few illegal register settings and the expectations of background noise. You can find code for this in the AutoTuner() class of the goodfet.nrf client.

First, the length of the address to sniff must be reduced to its absolute minimum. The datasheet claims that the lowest two bits of register 0x03 are responsible for address width, and that the only valid lengths at 3 bytes (01b), 4 bytes (10b), or 5 bytes (11b). Setting this value to 00b gives a 2 byte match, but when checksums are disabled, this results in a deluge of false-positive packets that appear out of background noise.
nRF Address Width

Second, it is necessary to begin receiving before the SYNC field appears, as the Nordic chips drop the address of incoming packets, leaving only the payload. By looking at the noise returned when the address is at its shortest length, it is clear that background noise includes a lot of 0x00 and 0xFF packets as well as 0xAA and 0x55 packets, which are likely feedback from an internal clock. What then would happen if the address were to be 0x00AA or 0x0055?

What happens is that noise activates the radio a bit early, which then syncs to the real preamble, leaving the SYNC field as the beginning of the packet payload! This is because the preamble and SYNC do not need to be immediately adjacent; rather, the SYNC can be delayed for a few bytes from the preamble in order to allow for longer preambles in noisy environments.

As a concrete example, an OpenBeacon packet looks something like the following. The SYNC field is 0x0102030201, so the packet will be cropped from that point backward. 0xBEEF is all that will be returned to the application, with everything prior to that cropped.
nRF24L01+ Promiscuous Mode

By making the address be 0x0055 and disabling checksums, that same packet will sometimes be interpreted as shown on the bottom. The preamble will be mistaken for a SYNC, causing the real SYNC value to be returned as the beginning of the payload. In that way, I am able to determine the SYNC/MAC field without any prior knowledge or brute force exploration.

This does depend upon the preamble being preceded by 0x00, which occurs often in background noise but is not broadcast by the attacker. So the odds of receiving a packet, while significantly worse than we'd like, are much better than the 1/2^16 you might assume. In experiments, one in twenty or so real packets arrive while a significant number of false positives also sneak in.

Recalling that the MAC addresses are three to five bytes long, and that radio noise is rather distinct, it stands to reason that noise can easily by separated from real packets by either manually checksumming to determine packet correctness or simply counting the occurrences of each address and taking the most popular. You will find an example log of OpenBeacon packets and false positives at http://pastebin.com/8CbxHzJ9. Sorting the list reveals that the MAC address 0x0102030201 is the most popular, which is in fact the address used by OpenBeacon tags.

Rather than rely on packet dumps and sorts, there is an autotune script that identifies network participants and prints their MAC addresses. Simply run 'goodfet.nrf autotune | tee autotune.txt' and go out for a coffee break while your device is transmitting. When you come back, you'll find logs like the following, which has identified a nearby OpenBeacon transmitter.

goodfet.nrf autotune

As low data-rate devices require significantly more time than high-rate devices to identify, such devices will either require undue amounts of patience or a real KeyKeriki. In the case of a Nike+ foot pod, I'm resorting to using loud hip hop music to trigger the sensor, which is left inside a pair of headphones. My labmates are not amused, but it is a great way to reveal the radio settings when syringe probes aren't convenient.

Part 3: or, Sniffing a keyboard effectively.

Having a class to identify channels and MAC addresses is most of the problem, but there are remaining issues. First, the packets themselves are encrypted, and that cryptography must be broken.

Fear not! We won't need to do any fancy math to break this cryptography, as the key is included at least once in every packet. Moser and Schröder's slides explain that the packet's header is cleartext, while the payload is XOR encrypted with the MAC address.
XOR Crypto!

Applying an XOR to the proper region yields decrypted packets such as the following. Because these contain USB HID events, key-up HID events quite often include long strings of 0x00 bytes. When XOR'ed with the key, those zeroes produce the key, so some packets contain the XOR key not just once, but twice!
MSKB5k Traffic

Finally, the USB HID events need to be deciphered to get key positions. Mapping a few of these yields meaningful text, with bytes duplicated in the case of retransmissions and omitted in the case of lost packets. Disabling checksums will allow the dropped packets to be converted to a smaller number of byte errors, while tracking sequence numbers will prevent retransmitted keys from being displayed twice. Regardless, the results are quite neighborly, as you can make out the sentence typed below in its packet capture.
NHBadge Key Sniffer

Part 4; or, Reproducing these results.

All of the code for this article is available in the GoodFET Project's repository, as part of GoodFETNRF.py and its goodfet.nrf client script. The hardware used was an NHBadge12, although an NHBadge12B or a GoodFET with the SparkFun nRF24L01+ Transceiver Module will work just as well.

To identify a nearby Nordic transmitter, run 'goodfet.nrf autotune'. Keyboards can be identified and sniffed with 'goodfet.nrf sniffmskb', while a known keyboard can be sniffed and decoded by providing its address as an argument, 'goodfet.nrf sniffmskb aa,c10ac074cd,17,09'. The channel--0x17 in this case--will change for collision avoidance, but channel hopping is slow and resets to the same starting channel. Identification of the broadcast channel is faster when the receiver is not plugged in, as that causes the keyboard to continuously rebroadcast a keypress for a few seconds.

All code presently in the repository will be refactored and rewritten, so revert to revision 885 or check the documentation for any changes.

Conclusions

Contrary to prior belief, the nRF24L01+ can be used to promiscuously sniff compatible radios, allowing for keyboard sniffing without special hardware. It's also handy for figuring out the lower levels of the otherwise-documented ANT+ protocol, and for reverse engineering vendor-proprietary protocols such as Nike+.

Additionally, it should be emphasized that the security of the Microsoft keyboards in this family is irreparably broken, and has been since Moser and Schröder published the vulnerability at CanSecWest. (It's a shame, because the keyboards are quite nicer than most Bluetooth ones, both in pairing delay and in battery life.) Do not purchase these things unless you want to broadcast every keystroke.

While I have not yet written code for injecting new keystrokes, such code does exist in the KeyKeriki repository and would not be difficult to port. Perhaps it would be fun to build stand-alone firmware for the Next Hope badge that sniffs for keyboards, broadcasting Rick Astley lyrics into any that it finds?

Please, for the love of the gods, use proper cryptography and double-check the security your designs. Then triple-check them. There is no excuse for such vulnerable garbage as these keyboards to be sold with neither decent security nor a word of warning.

Monday, January 24, 2011

Generic CC1110 Sniffing, Shellcode, and iClickers

Chipcon CC1110 Logo

Howdy y'all,

I haven't the time to write individual posts on these subjects, but I do have plenty of new features for the CC1110 that are worth sharing. Rather than explain how they were written in too much detail, I invite you to read the source code, which is mostly Python and C shellcode.

In order to follow along with these examples, you will need to have SmartRF Studio installed to /opt/smatrf7. While this requirement will go away in a few weeks, the GoodFET client temporarily needs SmartRF Studio for machine documentation about the CC1110. You can find more details on SmartRF requirements in the goodfet.cc client page.

(1) Packet sniffing, and other neighborly scripts.

GoodFETCC now has packet sniffing support for the SimpliciTI protocol used by the Chronos watch. Not only that, but it implements the protocol well enough to act as an access point for the watch, collecting accelerometer data and deciphering it for the host.
GoodFET Simpliciti Sniffing!

Run an access point with 'goodfet.cc simpliciti [band]'. (This command will likely change names soon, as it is a rather ugly hack which only supports the Chronos accelerometer feature.) The optional parameter should be us, eu, or lf for the American, European, and Low Frequency versions of the watch.
GoodFET SimpliciTI Client

Not only protocols intended for the GoodFET, but also others which are coincidentally compatible, are supported. Thanks to some register settings contributed by Mike Ossman, you can sniff and decipher i<clicker traffic with 'goodfet.cc iclicker'.
goodfet.cc iclicker

The i<clicker uses a Xemics XE1203F (PDF) radio chip, shown below. The XE1203F is nearly as configurable as the CC11xx parts, except that it is limited to 2FSK encoding. Previously, this protocol could be sniffed with the GR-Clicker project and a USRP, but the highly-versatile CC1110 chip allows this to be done with neither a software defined radio nor a chip identical to that used by the transmitter.
iClicker

If you find it handy to see when a device is broadcasting, you can produce an ASCII-art plot of signal strength with 'goodfet.cc rssi [freq]':
GoodFET CC1110 RSSI Graph

Care to jam another transmitter? Just like with the Next Hope Badge's GoodFET mode, it takes a single command to hold a carrier wave.
'goodfet.cc carrier [freq]'
Chipcon Carrier

(2) Shellcode, now for quiche-eaters!

At the risk of appearing to facilitate quiche-eating, I'd like to quickly explain the new shellcode interface for placing code fragments on a Chipcon 8051 target, such as the CC1110.

The Chipcon radios have certain functions which are timing sensitive, chief among these being the rewriting of flash memory and the use of the digital radio core. If flash memory is not pulsed with the correct timing, mis-writes will occur. If the radio is read too slowly, bytes will be missed and a buffer underflow will ruin the transaction. Similarly, a transmission might fail if the single-byte transmission buffer isn't refilled quickly enough. I've also had trouble, for reasons that I can poorly explain, configuring the crystal oscillator through the debugging interface without shellcode.

As I described in my CC2430 Debugging Notes, the recommended method of flashing memory is to write a small block of code into XDATA RAM which does the actual write, then to branch to this code, waiting for a HALT (0xA5) opcode to return control to the debugger. This routine is provided in SWRA124 as machine code with assembly comments, beginning with the fragment shown below.
CC2430 Flash Routine

While this is fine and dandy for code that works, it's a bit infuriating to debug code in machine language. (Is that opcode supposed to be 0xA5 or 0xA6? Is the length of this instruction correct? Similar frustration abounds.) To correct for this, the GoodFET project now has a trunk/shellcode directory in addition to trunk/firmware and trunk/client. Shellcode is compiled for target microcontrollers, in this case just the CC1110 by SDCC, the Small Device C Compiler.

For example, this is the code that used to configure the crystal oscillator on the CC1110, a prerequisite for any radio operations:
Chipcon Shellcode

That ugly mess becomes the following little fragment of C. It is compiled by 'sdcc --code-loc 0xF000 crystal.c' in order to place the code squarely within RAM, which is executable in this 8051 clone's unified memory architecture. (It's a Harvard chip that acts Von Neumann, or the other way around.)
CC1110 Crystal Shellcode

For inputs to these functions, and also for their return values, I find it more convenient to declare arrays at known locations than to read the symbol files to find them. The syntax for placing an array in XDATA memory at 0xFE00 is 'char __xdata at 0xfe00 packet[256];'. You can find examples of this in txpacket.c and rxpacket.c in the GoodFET repository.

(3) Care to join the fun?

There are a number of features remaining to be implemented in shellcode. Among them in a completed port of Ossmann's $15 Spectrum Analyzer, which I began in CC1110 Instrumentation in Python and you can find in the contrib/ directory of the GoodFET repository. By dropping the GUI interface and replacing it with timing delays, full spectrum scans can be made in decent time without requiring that anything in flash memory be changed.

Another handy tool would be an OOK sniffer that over-samples, using the infinite-packet-length trick described in the CC1110 datasheet to fill ram with a recording. Triggering on RSSI allows the beginning of the packet to be reliably timed, with oversampling allowing for correction on all later bits. I've begun to implement this as 'goodfet.cc sniffook [freq]', but an enterprising neighbor should be able to start sniffing garage door remotes in short order.

A Morse-code library in combination with an external amplifier would also be neighborly for the licensed amateur bands. The ability of the microcontroller to quickly return and channel hop might be able to account for, among other things, the Doppler shift experienced in EME moon-bounce experiments, without losing backward compatibility with 19th century radio technology.

As a prize, I offer one ale apiece for GoodFET patches implementing these features.

Stay neighborly,
--Travis Goodspeed
<travis at radiantmachines.com>

Monday, December 6, 2010

Hacking a Knitting Machine's Keypad

by Travis Goodspeed <travis at radiantmachines.com>
in collaboration with Fabienne Serriere and Arjan Scherpenisse,
at Mediamatic's RFID Devcamp 2010, Amsterdam,
for Multithreaded Banjo Dinosaur Knitting Adventure 2D Extreme,
with kind thanks to David Carne.

Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme

Thanks to some extra-neighborly blackmail by Fabienne, I spent last week hacking up a storm in Amsterdam. By extending the work of Steven Conklin, Limor Fried, and Becky Stern, we were able to hack a Brother KH930 knitting machine to print high score panes from a custom video game in yarn. This game was then displayed at Mediamatic for SensorFest, leading all sorts of neighbors to learn that RFID, socializing, and beer can lead to a neighborly time. Never in my life did I expect to get such an adrenaline rush from knitting, much less from from this newfangled social networking nonsense.

Conklin's technique for loading new patterns into the machine involves using an FTDI chip to simulate a Tandy PDD1 floppy disk drive, then typing "CE 5 5 1 STEP 1 STEP CE STEP STEP CE 9 0 3 STEP STEP" to load a new pattern set from disk and print pattern 3 of the set. (551 is the command to read from disk, and patterns held in RAM begin at 900.) For our exhibit, this sequence was far too complicated to type for every half meter of output, so we hacked the device's keypad for scripting.

This article describes how a matrix keypad works, how we reverse engineered the specific keypad of the Brother KH930, and how to use an Arduino with a handful of transistors to automate the typing of commands necessary for loading a new pattern from an emulated floppy disk. It should be applicable to all sorts of keyboards, but for those with serial protocols there might be a simpler method.

Unfortunately, there won't be room here to describe the first emergency knitting machine purchase in history, our A-Team trip to the far side of Holland in a borrowed van, or the case of Club Mate that we begged from a squatter bar in order to finish the project in the five days allotted.



A keypad matrix is most often built with switches that connect a row wire to a column wire. By keeping every column in a high-impedance state with pull-up resistors, then dropping each row low in sequence, the column inputs can be sensed to determine when a button is pressed. Dave's Hacks' first article on IM ME Hacking describes in detail how the keypad of the GirlTech IMME works, and all other implementations seem to function similarly.

The connections between rows and columns are just switches.
KeySchem

While in a perfect world, rows and columns would be arranged exactly as they appear visually, this is rarely efficient to route in copper for more than twelve buttons. We produced the diagram below by scanning the keyboard membrane, then pushing a button while using the continuity tester to see which row and column wire were connected. The table at the bottom converts from wire signal names to the Arduino signal names used within the client library.
KH930 Keypad Topside



In order to connect rows and columns to a center rail, I used BC547 NPN transistors prototyped on an Arduino shield. Each has a 1K resistor on the base. Row transistors have the collector coming from the row signal and the emitter going to the common rail; column transistors are the same, except that the collector and emitter are swapped in order to fit the direction of current.
Keymu10 Rows

As each transistor conducts when only when its base is high, the Arduino can press a key by first dropping all outputs low, then raising a row control line (RCx) and a column control line (CCx) high. Because of debouncing and a limited scan rate, this must be held for a short amount of time before releasing the key.


Such a design fits perfectly well on a prototyping shield, although the transistors are a tight fit. I recommend first prototyping a single row and column to ensure that the transistors are properly aligned, as current direction might be different on your keypad.
Keymu Prototype

For those who prefer to have a board fabbed, here's a proper schematic and layout. Gerbers and Eagle CAD source files are available in the project's subversion repository.
Keymu10 Schematic
Keymu10 Shield



A more sophisticated software implementation would involve using the Arduino's serial port to communicate with the host, accepting strings in ASCII and translating them to keypresses. We decided against such a complication because we feared relying on a second long USB cable. Further, we thought it handy when necessary to be able to run the device stand-alone with a single (reset) button press from the operator signaling that the next pattern should be loaded.

Full keyboard emulator code is available either by pastebin or from SVN. You'll find it in banjo/code/arduino.
svn checkout svn://svn.mediamatic.nl/devcamps/camp10/banjo

The code works by using simple methods to press a row and column by raising those pin voltages. Higher level methods allow for such functions as loading a pattern from disk or printing a pattern, each by performing multiple key presses and occasionally inserting a delay. By placing this within the Arduino code's setup() function, the pattern is loaded whenever the device is reset.

New patterns are loaded from the Banjo Dinosaur Knitting Adventure 2D Extreme game by first starting a floppy disk emulator--as per Steve Conklin's technique--then pulsing the DTR line of the arduino in order to cause a reset. The Perl for that is just a single line,
Device::SerialPort->new("/dev/ttyACM0")->pulse_dtr_on(100)

The end result, with a machine typing by itself, looks a little like this,


That's all there is to it. With fourteen transistors and just as many resistors, you can script your knitting machine--or any other keypad device--from a microcontroller without modifying the underlying firmware.

As a final note, I will give a cookie to the first neighbor who uses this technique to dump all of the power codes from a universal infrared remote control, or to program something long and sophisticated into a graphing calculator that lacks a link port.

Banjo Dinosaur
Arecibo Pattern
Intel 4001 Art
Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme

Monday, November 1, 2010

Bitmapped Sprites on the GirlTech IMME

by Travis Goodspeed <travis at radiantmachines.com>
with sprites by Eli Skipp,
extending Dave's LCD reversing,
and with thanks to Mike Ossmann.

ZombieGotcha

The GirlTech IMME is a fine platform for radio hacking and embedded programming, but the LCD of the device is by no means designed for lightning fast graphics. In this brief article, I demonstrate the method by which a sprite library can be constructed which abstracts away the less neighborly minutia of the LCD in favor of a row-wise framebuffer that gets flushed to the LCD as appropriate. This isn't fast enough for a port of Sonic the Hedgehog, but it's certainly sufficient for ZombieGotcha, a network disease simulation game that Eli Skipp and I are prototyping.

To quickly recap, the GirlTech IMME is a children's toy powered by the CC1110F32, which combines an 8051 microcontroller with a versatile sub-GHz radio. The toy also includes a text LCD controller and keyboard, making it a delightful platform for embedded systems hacking and prototyping. Thanks to Dave's article on attaching a debugger and reversing the LCD, it is possible to wire a GoodFET into the IMME, allowing for debugging and reprogramming of the device.



Since the days of the first raster displays, computers have been drawing images as rows, because that's the way that a television's electron stream is traced along the display. The IMME draws rows internally, but because it is intended to draw fonts, its rows are eight pixels tall. For example, the bytes {0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00} are pushed to the LCD in order to draw an uppercase letter H in Dave's LCD Demo for the IMME. Drawing this on graph paper or rendering it by Python, it becomes clear that 0x7F represents a side of the letter, 0x08 represents the bar, and 0x00 is the space following the letter.

IMME Font 'H'

Rather than attempting to natively store a framebuffer in the LCD's format, I chose to internally index by row, then to translate during the export of the framebuffer to the LCD. My primary reason for doing this is to maintain portability of the ZombieGotcha code to custom hardware. It also simplifies the transcription of sprites from original bitmaps to C structures.

Having an internal framebuffer is not without cost, however. The buffer is 132 pixels wide and 64 pixels tall. Even with bit-packing, this is more than a kilobyte in size, consuming more than a quarter of the CC1110's 4kB of XDATA RAM. (Programs and sprites are stored in CODE Flash memory, of which there is 32kB, so this limit is not quite so severe as it sounds.)



girlpix

My sprite toolchain is begun with bitmap images submitted by the artist. I cannot stress enough how important it is that your pixel artist understand pixels. Every sprite must be drawn at native resolution, with proper offsets of each frame and an understanding that the LCD is what it is, regardless of what Photoshop might render.

From the original bitmap sprites, PNM files are produced that are more easily parsed by Perl. This format consists of whitespace-delimited words for the format, width, and height of the sprite. In this case, the sprite consists of three frames, each of them being 24 pixels width and 32 pixels tall. Other sizes are possible, of course, but it is convenient for bit packing that the width is an even multiple of 8, so that the old pixels needn't be read back in.

PNM Format

It is then necessary to use an ugly Perl script to convert the sprite from a PNM to a C array of bytes. Pretty Perl won't work, of course, because such a thing doesn't exist. My script, sprite2c.pl, takes a 24-bit color PNM file and converts it to a 1-bit map that is byte-packed. Each of these is included by the preprocessor as a __code unsigned char[], with the __code keyword implying that the object should be stored in Flash rather than RAM.

sprit2cl.pl

Sprite animations are performed by storing the frame count along with the width and height in the C structure. Considering the resource constraints of this system, frame counts change very rarely and are stored within the C code.

zsprites.c



Dumping the frame-buffer to the LCD is as simple as writing every stripe of data to the screen. Potentially, as an optimization, you could keep track of which stripes have been invalidated across what horizontal range, updating only where necessary.

Keeping in mind that the LCD is updated as stripes of 8 pixels in height, code such as the following will refresh the entire LCD from the frame-buffer. Be sure not to erase the LCD between writes, as that would cause unnecessary flickering.

Framebuffer Dump

The framebuffer elements themselves are grabbed by selecting the pixel index divided by 8, then masking off the selected bit. The following functions work admirably for this purpose.

FBGetSet

If greater performance is required, a game should certainly be designed with a custom graphics library that optimizes the few things it does most. Performances can be gained by storing sprites and the frame-buffer natively in the row/stripe format that the LCD expects, simplifying conversion. Mike Ossmann used the technique of basing most graphics around vertical lines in his spectrum analyzer firmware, allowing for channels to be redrawned as they are scanned rather than flushed from a frame-buffer.

As the ZombieGotcha game is largely turn-based and the frame-rate is not a dire concern, I don't expect to optimize the sprite library much beyond what is presented here.

One major addition will be that of screenshots, as I'd like to produce animated GIFs of game action for the website. Screenshots can be produced by the method that I outline in CC1110 Instrumentation with Python, dumping the frame-buffer from XDATA with a GoodFET and writing that to disk. Alternatively, full-speed screenshots could be dumped by sniffing the LCD's SPI bus using a Total Phase Beagle or other SPI protocol analyzer.

For those of you with an IMME, Eli and I will be releasing the ZombieGotcha game at the Twenty-Seventh Chaos Communications Congress in Berlin this winter. We'll bring a bed of nails for reflashing IMME units on the spot, as well as GoodFET kits for modifying your IMME to be a development kit. (The ZombieGotcha will also run on full-custom hardware, but we are maintaining IMME support in parallel.)

As a final note, a teaser of the ZombieGotcha opening screen can be found here in the Intel-Hex format. I'll give a GoodFET40 kit to the first neighbor who sends me an animated GIF of it and a script to generate the same, either by a debugger or an emulator.