tag:blogger.com,1999:blog-36385054613992323792024-03-19T01:34:43.535-04:00Travis Goodspeed's BlogTravis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.comBlogger96125tag:blogger.com,1999:blog-3638505461399232379.post-4051591495573320742013-07-20T18:18:00.001-04:002013-07-20T18:18:42.797-04:00Hillbilly Tracking of Low Earth Orbit SatellitesAn adventure of the Southern Appalachian Space Agency,<br />
by Travis Goodspeed <travis at radiantmachines.com>,<br />
as presented at <a href="http://www.summercon.org/">Summercon 2013</a>,<br />
inspired by the lectures of Adam Laurie and Jim Geovedi,<br />
with kind assistance from Skytee.<br />
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8582983534/" title="SASA by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8369/8582983534_45a1c40c72.jpg" width="375" height="281" alt="SASA"></a></p>
<p>At Black Hat DC in 2008, I watched Adam Laurie present a tool for mapping Ku-band satellite downlinks, which he has since rewritten as <a href="http://www.alcrypto.co.uk/satmap/">Satmap</a>. His technique involves using an DVB-S card in a Linux computer as a receiver through a 90cm Ku-band dish with fixed elevation and a DiSEqC motor for azimuth motion. It was among the most inspirational talks I'd ever seen, and I had a blast recreating his setup and scanning the friendly skies. However, such a rig is limited to geostationary satellites in a small region of the sky; I wanted to see the whole sky, especially the moving targets.</p>
<p>In this article, I'll demonstrate a method for modifying a naval telecommunications dish to track moving targets in the sky, such as those in Low Earth Orbit. My dish happily sits in Tennessee, while I direct it using my laptop or cellphone here in Europe. It can also run unattended, tracking moving targets and looking for downlink channels.</p>
<h3>The Hardware</h3>
<p>This is my dish, originally a Felcom 82B from Furuno, intended as a mobile earth station on maritime vessels. It would connect to one of the Inmarsat satellites in geostationary orbit, using mechanical gyroscopes to correct the dish against the ship's movements. My use case is the opposite, trying to track moving targets from a stationary ground position.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8581915329/" title="SASA by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8527/8581915329_c588c12650.jpg" width="375" height="500" alt="SASA"></a></p>
<p>The first of several modifications was to place the motors under computer control. Rather than build dedicated electronics, I took the lazy route and wired an <a href="http://www.schmalzhaus.com/EBB/">EiBotBoard</a> into a <a href="http://beagleboard.org/Products/BeagleBone">BeagleBone</a> for motor control. I wired things such that the first motor is Azimuth and the second motor is Elevation, with the Tilt motor disabled.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8489514001/" title="Stepper Motor EAD ZA23ECK-12T1 by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8523/8489514001_7c6b1bc251.jpg" width="500" height="282" alt="Stepper Motor EAD ZA23ECK-12T1"></a></p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8616814775/" title="20130322_012 by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8120/8616814775_aa700180d0.jpg" width="500" height="282" alt="20130322_012"></a></p>
<p>When testing the stepper motors, I found it handy to have a second EBB that was wired into standalone motors, so that my control software could run away from the dish. The EBB appears to its host computer as /dev/ttyACM0, and it's easy to test the motors by directly sending commands. To move both motors slowly forward 400 steps for three seconds, run <i>echo "SM,3000,400,400" >>/dev/ttyACM0</i> on the BeagleBone. To do this from software, a control application can simply open /dev/ttyACM0 as a file and write the relevant commands into it.</p>
<p>In case the Azimuth or Elevation become lost, I really don't want to travel for two days just to lift the radome and recalibrate. For that reason, we painted the twelve hours of a clock inside of the radome and added a webcam. When lit by the Sun, the camera can be directed to twelve o'clock in order to ensure the dish itself is pointed nearly South. Finer calibration is performed by radio against geostationary targets.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8583014548/" title="SASA by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8507/8583014548_a67c71f185.jpg" width="500" height="375" alt="SASA"></a></p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8851228871/" title="Southern Appalachian Space Agency by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8278/8851228871_67b506a956.jpg" width="500" height="375" alt="Southern Appalachian Space Agency"></a></p>
<p>For handling the radio input and controlling the motors, I have a BeagleBone wired into a USB hub. These are all mounted on the trunk of the assembly inside of the radome, sending data back to a server indoors. Unfortunately, I couldn't fit everything over the assembly's original ring connector, so an umbilical cord connects the dish to the outside world. To prevent this cord from tangling, software prevents the dish from spinning more than 360 degrees in azimuth.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8851227075/" title="Southern Appalachian Space Agency by Travis Goodspeed, on Flickr"><img src="http://farm6.staticflickr.com/5463/8851227075_e4efd24a17.jpg" width="500" height="375" alt="Southern Appalachian Space Agency"></a></p>
<p>Additionally, I wanted input from an Inertial Measurement Unit. While definitely a luxury rather than a necessity, this allows for direct measurement of the dish's elevation. In future rebuilds, I'll use a much cheaper accelerometer. The unit I chose was a VectorNav VN100, as its UART output could run directly to the BeagleBone without requiring another USB port.</p>
<h3>The Daemons</h3>
<p>In order to operate the dish, I wanted both a flashy GUI and concise scripting, but scripting was the higher priority. Toward that end, I constructed the software as a series of daemons that communicate through a PostgreSQL database on a server inside the house. For example, I can run <i>SELECT * FROM sats WHERE el>0</i> to select the names and positions of all currently tracked satellites that are above the horizon. To begin tracking the International Space Station if it is in view, I run <i>UPDATE target SET name='ISS';</i>.</p>
<p>These daemons run on two machines, with everything computationally intensive on an AMD64 server and everything that needs to be locally within the radome on a BeagleBone.</p>
<p>For predicting satellite locations, I wrote a quick daemon using <a href="http://rhodesmill.org/pyephem/">PyEphem</a> that fetches satellite catalog data from <a href="http://celestrak.com/">CelesTrak</a>. These positions are held in a database, with duplicates filtered out and positions constantly updated. PyEphem is sophisticated enough to predict in any number of formats, so it's easy to track many of the brighter stars as well as planets and deep-space probes, such as Voyagers 1 and 2.</p>
<p>In addition to knowing where the satellites are, it's also necessary to know where the dish is and how the dish is tilted. For this, I have one daemon to watch my IMU's input and a second daemon to control the motor. These two are both used to predict the position, as the motor daemon does dead reckoning to compare against the IMU daemon's values.</p>
<p>Finally, there are a few different daemons and clients for directing the targeting of the dish. Generally, I run one slow background process to retarget every fifteen minutes, so that I can take manual control of the dish using a GUI application.</p>
<h3>The GUI</h3>
<p>Once the daemons were running smoothly, I tossed together a GUI using <a href="http://www.pygame.org/">Pygame</a> and the same database library that the daemons use. The GUI is operated by keyboard and mouse commands, with a left-click targeting an object and a right-click targeting a position. Named stars can optionally be shown in the background and moving targets are tracked as they move.</p>
<a href="http://www.flickr.com/photos/travisgoodspeed/8856529842/" title="SASA Commander, Polar View by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8261/8856529842_5796089225.jpg" width="400" height="400" alt="SASA Commander, Polar View"></a>
<p>In the screenshot above, the dish is aimed at GOES 3 and has just been ordered to aim at Voyager 1. Future enhancements to the GUI will show radial views and offer some control or visualization of the radio data.</p>
<p>Being written in Pygame, I can run the same exact code on both my laptop and my phones. Coding new features while bored on the Ubahn is a lot healthier than Angry Birds or Sudoku.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8757945976/" title="SASA Commander on the N900 by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7439/8757945976_0956f630ce.jpg" width="500" height="375" alt="SASA Commander on the N900"></a></p>
<h3>The Radio</h3>
<p>My initial build using an RTLSDR dongle. Data processing is done on my server, with the BeagleBone forwarding data from <a href="http://sdr.osmocom.org/trac/wiki/rtl-sdr">rtl_tcp</a>. To avoid offending the FCC and ham radio operators everywhere, I disabled the dish's 1.5GHz transmitter and use only the 1.6GHz downlink antenna. If I can justify the extra weight, I'd like to drop the RTLSDR in favor of a USRP2 over Gigabit Ethernet in order to get greater bandwidth and sensitivity.</p>
<p>Recordings are stored either as raw I/Q data or as a simple signal strength indicator from the Power Spectral Density (PSD) function. In the near future, I hope to automatically adjust the aim of the dish in realtime based upon the signal quality feedback.</p>
<h3>Next Steps</h3>
<p>When time and travel allow, I plan to replace the old Low Noise Amplifier (LNA) with one that has wider bandwidth. I'm also hoping to add support for new radio bands either by swappable antennas or by adding more antennas to the collection.</p>
<h3>Thank you kindly.</h3>
<p>As a final note, I'd like to thank Skytee for trekking six timezones to help me out with this. Thanks are also due to my next-door neighbors for not panicking when they thought I was talking to aliens.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8489404919/" title="L Band by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8510/8489404919_9140d1d94b_n.jpg" width="320" height="180" alt="L Band"></a></p>
Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com1369tag:blogger.com,1999:blog-3638505461399232379.post-81167575024931078402012-10-09T06:30:00.000-04:002012-10-09T06:32:24.503-04:00Emulating USB DFU to Capture Firmwareby Travis Goodspeed <travis at radiantmachines.com>,<br/>
to be presented at <a href="http://ruxconbreakpoint.com/">Breakpoint Melbourne 2012</a>,<br />
continuing <a href="http://travisgoodspeed.blogspot.de/2012/07/emulating-usb-devices-with-python.html">Emulating USB Devices with Python</a>,<br />
with thanks Sergey Bratus and the Dartmouth Scooby Crew.<br />
<p>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.</p>
<p>Toward that end, I'm happy to announce that USB Device Firmware
Update emulation is working on the <a href="http://goodfet.sourceforge.net/hardware/facedancer11/">Facedancer Board</a>, 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.</p>
<a href="http://www.flickr.com/photos/travisgoodspeed/8062736165/" title="Facedancer is an Ubertooth by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8311/8062736165_858c724d4d_n.jpg" width="320" height="180" alt="Facedancer is an Ubertooth"></a>
<p>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 <a href="http://ubertooth.sourceforge.net/">Project
Ubertooth</a> boards by emulating one well enough to fool the ubertooth-dfu tool that Jared Boone has contributed to that project.</p>
<h3>A Child's Guide to USB Device Firmware Updates, Suitable for Adults</h3>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<h3>Facedancing as USB DFU</h3>
<p>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.</p>
<p>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.</p>
<p> </p>
<p>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.</p>
<p>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'.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8059388956/"
title="Ubertooth lsusb by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8040/8059388956_fd3f3c7f36.jpg"
width="263" height="500" alt="Ubertooth lsusb"></a></p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8059407567/"
title="Ubertooth in DFU Mode by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8176/8059407567_a8525f2ca5.jpg"
width="304" height="500" alt="Ubertooth in DFU Mode"></a></p>
<h3>A Tourist's Phrasebook for DFU</h3>
<p>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.</p>
<p>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.</p>
<p><table>
<tr><th>bRequest</th><th>wValue</th><th>wIndex</th><th>wLength</th></tr>
<tr><td>0x00 DETACH</td><td></td><td></td><td></td></tr>
<tr><td>0x01 DNLOAD</td><td>blocknum</td><td></td><td>blocklen</td></tr>
<tr><td>0x02 UPLOAD</td><td></td><td></td><td></td></tr>
<tr><td>0x03 GETSTATUS</td><td></td><td></td><td>0x0006</td></tr>
<tr><td>0x04 CLRSTATUS</td><td></td><td></td><td></td></tr>
<tr><td>0x05 GETSTATE</td><td></td><td></td><td>0x0001</td></tr>
<tr><td>0x06 ABORT</td><td></td><td></td><td></td></tr>
</table></p>
<p>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.</p>
<p>#From the ubertooth-dfu source code.<br />
0: 'appIDLE'<br />
1: 'appDETACH'<br />
2: 'dfuIDLE'<br />
3: 'dfuDNLOAD_SYNC'<br />
4: 'dfuDNBUSY'<br />
5: 'dfuDNLOAD_IDLE'<br />
6: 'dfuMANIFEST_SYNC'<br />
7: 'dfuMANIFEST'<br />
8: 'dfuMANIFEST_WAIT_RESET'<br />
9: 'dfuUPLOAD_IDLE'<br />
10: 'dfuERROR'</p>
<p>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.</p>
<p>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.</p>
<h3>Recap and Basic Usage</h3>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8060133999/"
title="Facedancer DFU Emulator by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8181/8060133999_9fb68d438a.jpg"
width="500" height="320" alt="Facedancer DFU Emulator"></a></p>
<h3>Complications of Entering DFU Mode</h3>
<p>Thus far, we've been emulating a device that is *already* in DFU
mode, but in the real world, few devices ship that way.</p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8062512411/"
title="Failure Entering DFU by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8173/8062512411_1fab38564e.jpg"
width="500" height="126" alt="Failure Entering DFU"></a></p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8062527404/"
title="Unhandled Vendor Request in USB by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8179/8062527404_939fb93bba.jpg"
width="432" height="154" alt="Unhandled Vendor Request in
USB"></a></p>
<p>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.</p>
<p>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.</p>
<h3>Complications of Non-Standard Extensions</h3>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<h3>Conclusion</h3>
<p>In conclusion, I'd like to share a Cease and Desist letter that I
recently received from Michael Ossmann
at <a href="http://greatscottgadgets.com/">Great Scott Gadgets</a>,
the good neighbor who makes the <a href="http://ubertooth.sourceforge.net/hardware/one/">Ubertooth One</a>.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8061880131/"
title="C&D from Great Scott Gadgets by Travis Goodspeed, on
Flickr"><img src="http://farm9.staticflickr.com/8035/8061880131_9ac2628eac.jpg"
width="281" height="500" alt="C&D from Great Scott
Gadgets"></a></p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/8062832076/" title="Fake iPhone by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8315/8062832076_3bf660614c_n.jpg" width="320" height="160" alt="Fake iPhone"></a></p>
<p>As usual, patches should
be sent to myself or
the <a href="https://lists.sourceforge.net/lists/listinfo/goodfet-devel">goodfet-devel</a>
mailing list. PCBs are available free or at cost, as described on
the <a href="http://goodfet.sourceforge.net/orders/">Ordering Page</a>
of the <a href="http://goodfet.sourceforge.net/">GoodFET
Project</a>. Assembly instructions can be found on the
<a href="http://goodfet.sourceforge.net/hardware/facedancer11/">Facedancer11 Page</a>.</p>
Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com535tag:blogger.com,1999:blog-3638505461399232379.post-37814087933371232012-07-03T19:32:00.001-04:002012-07-03T19:34:00.435-04:00Emulating USB Devices with Pythonby Travis Goodspeed <travis at radiantmachines.com><br />
as presented with Sergey Bratus at <a href="http://recon.cx/">Recon</a> 2012<br />
with thanks to Sergio Alverez and the Dartmouth Scooby Gang.<br />
<p>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!"</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7255192718/" title="The Magic School Bus is a Network! by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8156/7255192718_9b9b713cac.jpg" width="333" height="250" alt="The Magic School Bus is a Network!"></a></p>
<p>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.</p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/6801358124/" title="GoodFET Does USB by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7182/6801358124_6054d938bb.jpg" width="400" height="225" alt="GoodFET Does USB"></a></p>
<h3>Introducing the Facedancer Board</h3>
<p>Our rough prototype was refined into a single board, which is documented as the <a href="http://goodfet.sourceforge.net/hardware/facedancer10/">Facedancer10</a> 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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7208636254/" title="Facedancer10 Prototype by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7090/7208636254_c88097aaf8.jpg" width="400" height="225" alt="Facedancer10 Prototype"></a></p>
<p>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.</p>
<p>To learn how the chip functions, read the <a href="http://pdfserv.maxim-ic.com/en/an/AN3598.pdf">MAX3420E Programming Guide</a> and similar documents from the <a href="http://www.maxim-ic.com/datasheet/index.mvp/id/4751">MAX3420E Page</a> of Maxim's website.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7174816263/" title="Maxim MAX3420E by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8002/7174816263_4f7cdfa8af.jpg" width="287" height="300" alt="Maxim MAX3420E"></a></p>
<h3>Learning USB</h3>
<p>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 <a href="http://wiki.wireshark.org/CaptureSetup/USB">Wireshark</a>, <a href="http://labs.vmware.com/flings/virtualusb">VMWare</a>, or a <a href="http://www.totalphase.com/products/beagle_usb12/">Total Phase Beagle</a>, 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 <a href="http://www.ladyada.net/learn/diykinect/">Hacking the Kinect</a>.</p>
<p>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!</p>
<p>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.</p>
<h3>HID Keyboard Emulation</h3>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p><pre>
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];</pre></p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<h3>FTDI Emulation</h3>
<p>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 <a href="http://ftp.fr.openbsd.org/pub/OpenBSD/src/sys/dev/usb/uftdireg.h">uftdireg.h</a> and a few quick peeks at the Linux equivalent.</p>
<p>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.</p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7235643856/" title="FTDI Emulator by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8004/7235643856_169f009dd0.jpg" width="383" height="192" alt="FTDI Emulator"></a></p>
<p>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.</p>
<h3>Bugs Abound!</h3>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7211571882/" title="lsusbcoredump by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7211/7211571882_534a37a812.jpg" width="300" height="288" alt="lsusbcoredump"></a></p>
<p>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 <a href="http://www.outflux.net/blog/archives/2012/05/16/usb-avr-fun/">Kees Cook's Blog</a>. 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.</p>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7328519432/" title="Facedancer in Action by Travis Goodspeed, on Flickr"><img src="http://farm9.staticflickr.com/8156/7328519432_2dc0d0264b.jpg" width="400" height="225" alt="Facedancer in Action"></a></p>
<h3>Scapy Integration</h3>
<p>Ryan Speers, one of the neighbors with whom I invented the <a href="http://travisgoodspeed.blogspot.com/2011/09/remotely-exploiting-phy-layer.html">Packet-in-Packet attack</a>, 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 <a href="http://rmspeers.com/archives/252">on his blog</a>. 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.</p>
<h3>Host Mode</h3>
<p>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.</p>
<p><a href="http://www.flickr.com/photos/travisgoodspeed/7039663051/" title="GoodFET as a USB Host by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7077/7039663051_bb40f09e54.jpg" width="400" height="225" alt="GoodFET as a USB Host"></a></p>
<h3>Conclusions</h3>
<p>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.</p>
<p>You can order Facedancer and GoodFET boards by following the instructions on the <a href="http://goodfet.sourceforge.net/orders/">GoodFET Ordering Page</a>. We're happy to send them out for free to the funemployed, but please properly format your shipping address.</p>
<p>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 <a href="https://lists.sourceforge.net/lists/listinfo/goodfet-devel">goodfet-devel</a> mailing list when you do.</p>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com607tag:blogger.com,1999:blog-3638505461399232379.post-45006536456479159562012-02-23T01:31:00.002-05:002012-02-23T01:31:00.609-05:00Wardriving for Zigbeeby Travis Goodspeed <travis at radiantmachines.com><br />with kind thanks to @fbz, @skytee, and their <a href="http://hackerhostel.org/">Hacker Hostel</a>.<br /><br />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 <a href="http://travisgoodspeed.blogspot.com/2011/09/bluetooth-goodfet-for-n900.html">Microsoft Keyboard Sniffer</a> in September that forwards keyboard traffic to my Nokia N900. (By the by, Microsoft still refuses to issue an advisory for that bug.)<br /><br />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 <a href="http://www.digitalmunition.com/_/Blog/Entries/2010/10/13_Nearby_Park_has_Zigbee_lighting_or_irrigation.html">irrigation</a> and <a href="http://www.digitalmunition.com/_/Blog/Entries/2010/10/13_Confirmed_COTA_Bus_Zigbee_Usage.html">city bus</a> networks that KF identified, but for any of the cities that I pass through.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6824819675/" title="Zigbee Wardriving by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7169/6824819675_7974c0acd2.jpg" width="500" height="281" alt="Zigbee Wardriving"></a><br /><br /><h3>Hardware</h3><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6561000183/" title="Pocket ZigBee Sniffer by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7013/6561000183_20b8e5d4fc.jpg" width="500" height="282" alt="Pocket ZigBee Sniffer"></a><br /><br />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 <a href="http://www.rovingnetworks.com/products/RN_42">Roving Networks RN42</a> 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.<br /><br />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.<br /><br />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.)<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6819584705/" title="Zigbee Wardriving by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7163/6819584705_39a0e0ba3c.jpg" width="500" height="282" alt="Zigbee Wardriving"></a><br /><br /><h3>Firmware</h3><br />The GoodFET firmware natively supports the TelosB, as described <a href="http://goodfet.sourceforge.net/hardware/telosb/">here</a>. 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.<br /><br />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.<br /><br /><h3>Standard Client</h3><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6575041493/" title="GoodFET on the N9 by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7019/6575041493_a230f46b5a.jpg" width="480" height="205" alt="GoodFET on the N9"></a><br /><br /><h3>Custom Client</h3><br />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 <a href="http://travisgoodspeed.blogspot.com/2011/12/introduction-to-bluetooth-rfcomm.html">SPOT Connect client</a> as a starting point.<br /><br />The interface is composed of a Bluetooth selection dialog, a packet sniffer, and a packet beaconing script that repeatedly broadcasts a sample <a href="http://travisgoodspeed.blogspot.com/2011/09/remotely-exploiting-phy-layer.html">Packet-in-Packet Injection</a>. <br /><a href="http://www.flickr.com/photos/travisgoodspeed/6575209579/" title="N9 ZigBee Sniffing (cropped) by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7015/6575209579_57a96c3cca.jpg" width="480" height="265" alt="N9 ZigBee Sniffing (cropped)"></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6702986967/" title="GoodFET for Meego by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7146/6702986967_e1965f118c.jpg" width="281" height="500" alt="GoodFET for Meego"></a><br /><br />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.<br /><br /><h3>Plotting</h3><br />The position log is then translated by a script into the Keyhole Markup Language or any other GIS format for plotting.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6817816951/" title="Wardriving for Zigbee by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7157/6817816951_102e2f8c0f.jpg" width="500" height="419" alt="Wardriving for Zigbee"></a><br /><br />KML is simple enough to compose, with the one oddity that longitude comes <i>before</i> 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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6819699825/" title="KML Point by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7154/6819699825_29b350dc23.jpg" width="497" height="115" alt="KML Point"></a><br /><br />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.<br /><br /><h3>Conclusions</h3><br />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 <a href="http://travisgoodspeed.blogspot.com/2011/01/generic-cc1110-sniffing-shellcode-and.html">SimpliciTI</a>, the <a href="http://travisgoodspeed.blogspot.com/2010/07/reversing-rf-clicker.html">Turning Point Clicker</a>, and other protocols that the GoodFET stack supports. I could also use it to map neighbors with the CCC's <a href="http://r0ket.badge.events.ccc.de/">r0ket</a> badge and similar OpenBeacon transmitters as they stray from the conference venue.<br /><br />Other protocols, however, are a lot harder to wardrive. While my <a href="http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html">Microsoft keyboard sniffer</a> 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.<br /><br />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 <a href="http://goodfet.sourceforge.net/">GoodFET</a> repository.<br /><br />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.<br /><br />Have fun,<br />--TravisTravis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com214tag:blogger.com,1999:blog-3638505461399232379.post-52265241941490748062011-12-04T15:25:00.000-05:002011-12-04T15:29:53.157-05:00Introduction to Bluetooth RFCOMM Reverse Engineeringby Travis Goodspeed <travis at radiantmachines.com><br />with thanks to <a href="http://natrium42.com/">Alexei Karpenko</a><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6388584445/" title="Spot Connect (cropped) by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7171/6388584445_b1f9542de4_m.jpg" width="240" height="211" alt="Spot Connect (cropped)"></a><br /><br />Reverse engineering a Bluetooth device is rather straightforward, but quite a few good neighbors don't know where to begin. This article demonstrates exactly how an Android client was reverse engineered in order to produce open source clients in Python and QT Mobility. I'm writing with the assumption that you are trying to reverse engineering your own device, which is similar but not identical to mine. As this is an introductory guide, I'll stay clear of any code reverse engineering, sticking only to network traffic.<br /><br />The subject of this article is the <a href="http://www.findmespot.com/en/index.php?cid=116">Spot Connect</a>, which transmits one-way text messages and GPS coordinates by L-band to the GlobalStar satellite constellation. These messages are then forwarded by email or SMS. Except in its emergency mode, the device is operated through Bluetooth by a smart phone. Thanks to Android's use of the Bluez bluetooth stack, it is rather easy to get the necessary traffic dumps.<br /><br />Kind thanks are due to Alexei Karpenko (Natrium42) for his article on <a href="http://natrium42.com/projects/spot/">SPOT Reverse Engineering</a>, which covers the original SPOT unit in excellent and thorough detail. It was his article that got me looking at the Spot Connect, and his description of the GPS format saved me quite a bit of travel for sample collection.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6340739819/" title="GlobalStar Beacon by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6110/6340739819_cf093debb1.jpg" width="375" height="278" alt="GlobalStar Beacon"></a><br /><br /><h3>Sniffing RFCOMM</h3><br />The first step is to load the official client onto a rooted Android phone, in my case a Nexus S. I had to swap SIM cards as my Brazilian one put me in a region of the Android market that didn't have the application. Switching to a Swiss card fixed this, and a moment later the app was installing.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6341490393/" title="SPOT Connect by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6107/6341490393_f0ba102413_m.jpg" width="135" height="240" alt="SPOT Connect"></a><br /><br />The Spot Connect uses RFCOMM, which is Bluetooth's alternative to a TCP socket or a UART. As it is easy to prototype and always delivers packets in order, RFCOMM has become the standard way of implementing custom protocols. To sniff the traffic before knowing the mode, we'll use hcidump running in a debugging shell of the phone. For this, run <i>adb shell hcidump -X | tee spotlog.txt</i> on your workstation, send a transmission, and watch the result in the log.<br /><br />The message being sent stands out as ASCII, of course, so it's the first thing to look for. With no knowledge of the HCI protocol, you can still be sure that you have a cleartext recording.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6388996157/" title="HCIDump Screenshot by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6116/6388996157_f6282e9e29.jpg" width="400" height="240" alt="HCIDump Screenshot"></a><br /><br /><pre>35 00 40 00 0b ef 63 aa 31 26 01 00 01 00 01 4d 5.@...c.1&.....M<br />72 2e 20 57 61 74 73 6f 6e 2c 20 63 6f 6d 65 20 r. Watson, come <br />68 65 72 65 2e 20 49 20 77 61 6e 74 20 74 6f 20 here. I want to <br />73 65 65 20 79 6f 75 2e 9a see you..</pre><br />From Alexei's article, you can expect that frames inside of RFCOMM will begin with 0xAA, followed by a length, followed by a verb and the objects. These bytes will be wrapped in padding on the outbound end, and they'll be fragmented on the inbound end. Sure enough, these are the bytes that come before the word ``Watson'':<br /><pre>aa Preamble<br />31 Length<br />26 Verb<br />01 00 01 00 01 Flags (OK, Check In)<br />4d 72 2e 20 57 ASCII Message (abbreviated)</pre><br />Counting 0x31 bytes out, notice that the packet ends exactly on a byte of the ASCII message, without a checksum! By looking for bytes of AA and searching for length, with allowances for packet fragmentation and the RFCOMM wrapper, it becomes possible to decode every command and its matching response.<br /><br />Be aware that responses will be fragmented more than transmissions. If you need to reverse engineer longer transactions or have a more complete log, it will be handy to have a script to reassembly from the HCI frames. In those cases, toss together a proper HCI decoder to get a more accurate interpretation of the records.<br /><br />Looking through the entire log, it the protocol appears to be as follows. First, the client queries the Device ID with verb 0x01, using the exact same format as Alexei's article. Then it uses verb 0x25 to query the last known position of the device, which will be returned in the style that Alexei reverse engineered from the original unit. Use pen and paper to decode these transactions from my Python client.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6389276441/" title="Location Query by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7151/6389276441_4898e203a2.jpg" width="338" height="100" alt="Location Query"></a><br /><br /><h3>First Implementation</h3><br />With these recordings in hand, the complete language can now be described and implemented. Luckily, three verbs make for a quick implementation!<br /><br />I use <a href="http://code.google.com/p/pybluez/">py-bluez</a> for prototyping such implementations, as its <a href="http://code.google.com/p/pybluez/source/browse/trunk/examples/simple/rfcomm-client.py">rfcomm-client.py</a> example is simple enough to get a working client in minutes. As py-bluez is specific to Linux, Mac users might prefer <a href="http://lightblue.sourceforge.net/">lightblue</a>.<br /><br />For simplicity, cut the UUID code or switch it to RFCOMM's UUID, which is 00001101-0000-1000-8000-00805F9B34FB. For a list of all services on a device, run 'sdptool records $adr'. This only lists those which are publicly announced by SDP, the Service Discovery Protocol. To scan for unadvertised services, try <a href="http://www.betaversion.net/btdsd/download/">BT Audit</a> from Collin Mulliner.<br /><br /><b>0x01 -- Get ID</b><br />A minimal test client will just test the serial number of the device. To do this, simply send "\xAA\x03\x01" and then catch the reply with verb 0x01. Bytes 3, 4, 5, and 6 of the reply will contain the serial number in Big Endian notation. For this first implementation, commands and their responses may be handled synchronously for simplicity.<br /><br />Where self.tx() takes a frame as its input and returns the response, this is implemented in Python as the following. What could be simpler?<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6430848699/" title="SpotConnect.getid(self) by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7002/6430848699_8290716b1b.jpg" width="253" height="116" alt="SpotConnect.getid(self)"></a><br /><br /><b>0x25 -- Get Last Position</b><br />Similar in calling convention, the 0x25 verb requests the last known GPS position of the device. The coordinate format is exactly the same as in Alexei Karpenko's <a href="http://natrium42.com/projects/spot/">Spot Hacking</a> article, consisting of three bytes apiece to describe latitude and longitude. The following is my C++ code for parsing the position data, which has already been requested as "\xAA\x03\x25".<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6430890283/" title="SpotConnect::parsePosition(char*) by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7143/6430890283_2c3b2e4d34.jpg" width="391" height="360" alt="SpotConnect::parsePosition(char*)"></a><br /><br /><b>0x26 -- Transmit Text</b><br />Transmitting text is just as easy, with the Spot Connect handling all the work after a message has been loaded. The following is Python code to transmit a short text message with the OK message-code. This lacks length checks and doesn't support the changing of flags, but it will work perfectly well for a test.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6430980859/" title="SpotConnect.checkin() by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6101/6430980859_b594d90a64.jpg" width="376" height="94" alt="SpotConnect.checkin()"></a><br /><br />After the device receives this command, it will reply with an acknowledgment and then begin to attempt transmissions at irregular intervals. Each transmission consists of a number of fragments, such that the packet can be reassembled so long as one copy of each fragment makes it through. If you have a clear view of the sky and have configured the first destination to be your email address, you should receive a notification within a few minutes. If you don't receive a notification by the time the mailbox icon has ceased blinking, then the transmission failed.<br /><br /><b>Other Verbs</b><br />These three verbse--0x01, 0x25, and x026--are sufficient to implement a minimal client for the Spot Connect. If you'd care to help out, it would be useful to have more documentation for the flags of the 0x26 verb, as well as documentation for 0x52, 0x40, and 0x38. By scanning and listening for error codes, it should be possible to get a complete list of those verbs that are unused by the Android application.<br /><br />You can find my Python client at <a href="https://github.com/travisgoodspeed/pyspot">https://github.com/travisgoodspeed/pyspot</a> . It ought to run as-is on Linux with py-bluez, including the Nokia N900.<br /><br /><h3>A Graphical Client</h3><br />Now that the protocol has been sufficiently well documented to have a Python implementation, it is worthwhile to rewrite it as a GUI. In my case, I wanted a QT Mobility client for my Nokia N9. You can find my work in progress at <a href="https://github.com/travisgoodspeed/goodspot">https://github.com/travisgoodspeed/goodspot</a>.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6426692031/" title="Pacific Ocean by Travis Goodspeed, on Flickr"><img src="http://farm8.staticflickr.com/7032/6426692031_4328a89076.jpg" width="281" height="500" alt="Pacific Ocean"></a><br /><br /><h3>Other Methods</h3><br />If hcidump isn't available for your platform, you might try <a href="http://www.usenix.org/event/woot07/tech/full_papers/spill/spill_html/">Sniffing with a USRP</a> or <a href="http://www.remote-exploit.org/wp-content/uploads/2010/01/busting_bluetooth_myth.pdf">reflashing a dongle</a> to become a commercial sniffer. For a jailbroken iPhone, see the <a href="http://theiphonewiki.com/wiki/index.php?title=Bluetooth">iPhone Wiki's</a> documentation.<br /><br />Another option would be to create a Bluetooth proxy, relying on the slim authentication performed in the protocol. In this case, the proxy would open all relevant port to the device being reverse engineered, ferrying commands back and forth as a way to record them. You might also need to experiment with changing the device class and, in the case of iOS devices, there is also a lockout sequence that must be implemented.<br /><br />If none of that works for your device, you could sniff the UART lines that come from the bluetooth module, shown here on the left board. This particular module happens to be a BT23, and Page 8 of <a href="http://www.ampedrf.com/datasheets/BT23_Datasheet.pdf">BT23_Datasheet.pdf</a> shows that pins 14 and 13 should be tapped to get a communications log.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6341493229/" title="SPOT Connect by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6229/6341493229_d3334298aa.jpg" width="500" height="282" alt="SPOT Connect"></a><br /><br />As a last resort, you could always ask for documentation. I didn't bother with this because of my own impatience, but for some devices, such as the <a href="http://www.metawatch.org/developers/">Metawatch</a>, documentation is freely available. More than once, a neighborly vendor has been so kind as to give me the source code or documentation just to be neighborly.<br /><br /><h3>Future Work</h3><br />This article will be followed with one on the physical layer protocol of the SPOT, which I've been able to sniff thanks to some kind help from Michael Ossmann. For a preview of that technique, you are welcome to stalk my <a href="http://www.flickr.com/photos/travisgoodspeed/sets/72157628136605956/">SPOT Connect Set</a> on Flickr. The most neighborly of these shows individual bits from a FunCube Dongle recording of the transmission. It's cleartext, of course.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6382817421/" title="Bits from SPOT Connect by Travis Goodspeed, on Flickr"><img src="http://farm7.staticflickr.com/6097/6382817421_1191864a81.jpg" width="354" height="500" alt="Bits from SPOT Connect"></a><br /><br />Replacement firmware is also a possibility. The Spot Connect uses an MSP430F5xx microcontroller with the standard USB bootloader, using a Java client on Windows and an Objective C client on OS X. The firmware itself is downloaded by HTTPS, and a copy could be acquired either by a MITM attack on HTTPS or by asking the bootloader politely, using the password that is to be found within the firmware update. Be careful when doing this to test on a unit without a service contract, as service cannot be moved from one unit to another and bricking is a distinct possibility.<br /><br /><h3>Conclusions</h3><br />I hope that this article has given you a decent overview of the methods for reverse engineering Bluetooth RFCOMM devices. While my subject was the Spot Connect, these methods would apply equally well to something like a GPS, the Metawatch, Bluetooth chat applications, and multiplayer games. Other brands of Bluetooth satellite communicators are available, and open documentation for them would be quite handy. For a list of a few thousand potential targets, search the Bluetooth SIG's <a href="http://gadgetguide.bluetooth.com/gadgetGuide.cfm#">Gadget Guide</a>.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com264tag:blogger.com,1999:blog-3638505461399232379.post-77131876114136169222011-09-06T09:09:00.002-04:002011-09-06T09:09:00.551-04:00A Bluetooth GoodFET for the N900by Travis Goodspeed <travis at radiantmachines.com><br />continuing <a href="http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html">Promiscuity is the NRF24L01+'s Duty</a><br />with kind thanks to @fbz, @skytee, and their <a href="http://hackerhostel.org/">Hacker Hostel</a>.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6093058810/" title="Bluetooth GoodFET by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6200/6093058810_18e3320884.jpg" width="500" height="375" alt="Bluetooth GoodFET"></a><br /><br />Since building my <a href="http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html">packet sniffer for the Microsoft 2.4GHz keyboards</a>, I've frequently wanted to demo it without having to drag out a laptop. Laptops are heavy, they are inconvenient, and cables just make matters worse. While it is possible to port it to a standalone board or to add an LCD to the Next Hope Badge, I'd rather have the entire GoodFET client library available over bluetooth to my Nokia N900. Pictured above is my prototype build, which reliably sniffs keyboard traffic on battery power for a more than an hour. Rather than serving as a build tutorial, this article will chronicle the bugs that cropped up during the port, in the hope that they'll help other neighbors trying to port the GoodFET firmware to new devices.<br /><br />This sniffer was assembled from a <a href="http://goodfet.sourceforge.net/hardware/nhb12/">Next Hope Badge</a> running the GoodFET firmware with hardwired DCO calibrations, a Roving Networks RN41 module, and three NiMH batteries. The client uses py-bluez at the moment, but I might port it to LightBlue for OS X support. Future models will use a GirlTech IMME or Telos B in place of the Next Hope Badge, to allow me to play with APCO P25 or ZigBee networks without a laptop.<br /><br /><h3>Compiling the Firmware</h3><br />Most of the GoodFET devices are built around an FT232RL and MSP430, with the FTDI taking care of USB to serial conversions. The client software just opens /dev/ttyUSB0 or its local equivalent through py-serial, then uses the DTR and RTS lines to reset the MSP430 into either the GoodFET application or a masked-ROM bootloader, the BSL. The client and the hardware do a little initialization dance in which the GoodFET is reset until the clock configuration register within the device matches 16MHz. So when you run 'goodfet.monitor info' and it replies with "Clocked at 0x8f9e", the devices has rebooted several times until it finds by chance that 0x8F9E is a stable clock configuration for 16MHz.<br /><br />When replacing the FTDI with a Bluetooth module, the DTR and RTS lines are unavailable with the timing resolution that is necessary to enter the BSL. Rather than rely upon them, I left them disconnected and instead ran only the TX and RX lines from the RN41 to the NHBadge. The !RST signal is also disconnected, so the GoodFET will boot when power is applied and cannot be rebooted except by the appropriate software command.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6112216039/" title="Bluetooth GoodFET by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6183/6112216039_aeb03a184b.jpg" width="500" height="281" alt="Bluetooth GoodFET"></a><br /><br />This creates a number of complications in the client, which I'll get to later, but the important thing for firmware is that the clock configuration must be explicitly known by the firmware at compile or link time. To specify this at compile time, set <i>CFLAGS="-DSTATICDCO=0x8F9E"</i>. To specify it at link time, just flash the image without erasing the INFO flash that resides from 0x1000 to 0x1100 in the MSP430X chips.<br /><br />Additionally, the firmware must be told which pins to use and which microcontroller to target. These are specified by exporting <i>platform="nhb12b"</i> and <i>mcu="msp430x2618"</i>. If an NHB12 were used instead of the NHB12B, then the platform would be redefined appropriately. Finally, the firmware size (and thus the flashing time) can be significantly reduced by exporting <i>config="monitor nrf spi"</i> to reduce the set of applications to only the Monitor, <a href="http://goodfet.sourceforge.net/clients/goodfet.nrf/">Nordic RF</a>, and SPI applications.<br /><br />To ease in reconfiguring my build environment, I left a script to create these settings in trunk/firmware/configs/examples/bluetooth-nhb12b.sh . Be sure to change the STATICDCO value to that of your own hardware when building it.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6112758420/" title="Next Hope Badge Flashing by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6072/6112758420_7b9b66af92.jpg" width="500" height="281" alt="Next Hope Badge Flashing"></a><br /><br />Finally, the firmware had to be flashed by JTAG, rather than BSL. This was done the same way the Next Hope Badges were originally programmed at the factory, by wedging the board into a GoodFET programmer and running 'goodfet.msp430 flash goodfet.hex', then verifying with 'goodfet.msp430 verify goodfet.hex'.<br /><br /><h3>Patching the Client</h3><br />Recalling that the client was initially designed to use py-serial, a few changes were required to make it function through <a href="http://code.google.com/p/pybluez/">py-bluez</a>.<br /><br />Before writing a proper client, I wrote a quick py-bluez script to connect to the GoodFET and print any string that is received. Briefly touching the !RST signal on the JTAG connector to its GND pin resets the device, causing it this client to print "http://goodfet.sf.net/". If the default GoodFET firmware is flashed, with no STATICDCO or Info Flash, the string will be printed as garbage most times, with one attempt in ten producing a legible string.<br /><br />Having verified that the timing and baud rate were correct, I continued by writing a communications module, GoodFETbtser(), that emulates the read() and write() functions of serial.Serial() used by the rest of the application. Additionally, the GoodFETbtser.read() function is written so as to always return the exact number of bytes requested by the receiver, as Bluetooth buffering sometimes breaks apart packets that would otherwise reliably be received as contiguous chunks.<br /><br />The following is a screenshot (with GoodFET.verbose=1) of a transmission being split in half because of a read() request returning too few bytes.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6092264993/" title="Bluetooth Packetization Bug by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6196/6092264993_50b8b11e02.jpg" width="500" height="372" alt="Bluetooth Packetization Bug"></a><br /><br />Additionally, the initialization routine was modified such that if the GOODFET environment variable is set to a six byte MAC address. Setting it to "bluetooth" causes the firmware to search for Bluetooth devices by name, then exit with instructions for setting the MAC. Later revisions might attempt to use the first observed RFCOMM adapter.<br /><br /><h3>Conclusions</h3><br />The final client is already mainstreamed into the GoodFET's subversion repository, and it looks a little like the following when packet sniffing encrypted <a href="http://www.openbeacon.org/">OpenBeacon</a> traffic. It can also sniff <a href="http://travisgoodspeed.blogspot.com/2010/07/reversing-rf-clicker.html">Turning Point Clickers</a>, <a href="http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html">Microsoft Keyboards</a>, and anything else that uses the 2.4GHz Nordic chips.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/6092876724/" title="Bluetooth GoodFET OpenBeacon Sniffing by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6075/6092876724_a1b049fbea.jpg" width="301" height="128" alt="Bluetooth GoodFET OpenBeacon Sniffing"></a><br /><br />I've already ordered parts to build Bluetooth versions of the Girltech IMME and the Telos B for mobile sniffing of APCO P25 and ZigBee. My rebuilds will include integrated battery charging from USB and the option of running standalone with the bluetooth module disabled, in order to greatly increase battery life. The client ought to run unmodified on rooted Android devices by use of SL4A and py-bluez. Additionally, I'm planning a firmware port to the <a href="http://www.openbeacon.org/OpenBeacon_USB_2">OpenBeacon USB 2</a> module from Bitmanufaktur GmbH.<br /><br />As a final note, I would like to remind all good neighbors that there is no reason why offensive security can't be fun for the whole family.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6112218273/" title="Bluetooth GoodFET by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6203/6112218273_a77f4ab87e.jpg" width="281" height="500" alt="Bluetooth GoodFET"></a>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com659tag:blogger.com,1999:blog-3638505461399232379.post-11980648752867128412011-09-01T01:57:00.001-04:002011-09-01T01:57:00.841-04:00Remotely Exploiting the PHY Layeror, Bobby Tables from 1938 to 2011
<br />
<br />by Travis Goodspeed <travis at radiantmachines.com>
<br />concerning research performed in collaboration with
<br />Sergey Bratus, Ricky Melgares, Rebecca Shapiro, and Ryan Speers.
<br />
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6052809032/" title="20110808_001 by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6070/6052809032_85af2f97d5.jpg" width="400" height="224" alt="20110808_001"></a>
<br />
<br />The following technique is a trick that some very good neighbors and I present in <a href="http://www.usenix.org/events/woot11/tech/final_files/Goodspeed.pdf">Packets in Packets: Orson Welles' In-Band Signaling Attacks for Modern Radios</a> (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.
<br />
<br />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 <i>inside of another packet</i> 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.
<br />
<br />As I've mentioned in my article on <a href="http://travisgoodspeed.blogspot.com/2011/02/promiscuity-is-nrf24l01s-duty.html">promiscuously sniffing nRF24L01+ traffic</a>, 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. (<a href="http://www.remote-exploit.org/?p=437">Keykeriki</a>, <a href="http://ubertooth.sourceforge.net/">Ubertooth</a>, and <a href="http://goodfet.sourceforge.net/clients/goodfet.nrf/">GoodFET/NRF</a> give a bit more.)
<br />
<br />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.
<br />
<br />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.
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/6052809378/" title="20110808_003 by Travis Goodspeed, on Flickr"><img src="http://farm7.static.flickr.com/6206/6052809378_4bec3866b2.jpg" width="500" height="281" alt="20110808_003"></a>
<br />
<br /><h3>How it works.</h3>
<br />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.
<br />
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5872168506/" title="802.15.4 PIP by Travis Goodspeed, on Flickr"><img src="http://farm4.static.flickr.com/3187/5872168506_92eb6c9c7b_m.jpg" width="240" height="144" alt="802.15.4 PIP"></a>
<br />
<br />The third interpretation, shown above in the right column, is the interesting one. If a symbol error occurs before the Body, <i>within the Preamble or the Sync</i>, then there's no checksum to cause the packet to be dropped. Instead, the receiver <i>does not know</i> 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.
<br />
<br />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 <i>no physical access</i> 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.
<br />
<br /><h3>War of the Worlds</h3>
<br />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 (<a href="http://www.archive.org/details/OrsonWellesMrBruns">mp3</a>, <a href="http://www.sacred-texts.com/ufo/mars/wow.htm">transcript</a>) performance.
<br />
<br />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:
<br />
<br /><i>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.
<br />
<br />(MUSIC: MERCURY THEATRE MUSICAL THEME)
<br />
<br />ANNOUNCER: Ladies and gentlemen: the director of the Mercury Theatre and star of these broadcasts, Orson Welles . . .
<br />
<br />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.
<br />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.</i>
<br />
<br />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.
<br />
<br /><i>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.</i>
<br /><i>From the Meridian Room in the Park Plaza in New York City, we bring you the music of Ramón Raquello and his orchestra.</i>
<br /><i>Ladies and gentlemen, we interrupt our program of dance music to bring you a special bulletin from the Intercontinental Radio News.</i>
<br /><i>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.</i>
<br /><i>Good evening, ladies and gentlemen. This is Carl Phillips, speaking to you from the observatory at Princeton.</i>
<br /><i>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.</i>
<br />
<br />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.
<br />
<br /><h3>How the hell did this happen?</h3>
<br />This class of vulnerability is a really, <i>really</i> 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?
<br />
<br />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 <i>implicitly dropped</i>, with the same behavioral effect that would be had if the error were later in the packet and it were <i>explicitly</i> 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.
<br />
<br />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.
<br />
<br />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 <a href="http://www.usenix.org/events/woot11/tech/final_files/Goodspeed.pdf">the paper</a> 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.
<br />
<br />Thank you kindly,
<br />--Travis Goodspeed
<br />
<br />
<br />
<br />
<br />Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com200tag:blogger.com,1999:blog-3638505461399232379.post-32095379372236746532011-05-24T08:00:00.003-04:002011-05-24T08:00:08.081-04:00Practical MC13224 Firmware Extractionby Travis Goodspeed <travis at radiantmachines.com><br />as presented at <a href="http://2011.confidence.org.pl/agenda">CONFidence Krakow, 2011</a>.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5540047761/" title="MC13224 by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5051/5540047761_d302653d6a.jpg" width="500" height="375" alt="MC13224" /></a><br /><br />Pictured above is a <a href="http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MC13224V">Freescale MC13224</a> chip, having been partially decapped with nitric acid in my lab. This is the chip used in the <a href="http://ninjas.org/badges/defcon18.html">Defcon 18 Ninja Badge</a> and the <a href="http://www.redwirellc.com/store/node/1">Redwire Econotag</a>. 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.<br /><br />Rather, pictured above are the <i>three chips</i> 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.<br /><br />For a more thorough discussion of the MC13224, read <a href="http://freaklabs.org/index.php/Blog/Zigbee/freescale-mc13224-review.html">Akiba's MC13224 Review</a>. 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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5540047603/" title="MC13224 by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5055/5540047603_79a42d9947.jpg" width="500" height="375" alt="MC13224" /></a><br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5540268655/" title="MC13224 CPU by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5094/5540268655_6ed46c1967_m.jpg" width="240" height="155" alt="MC13224 CPU" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5540141987/" title="MC13224 Little by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5018/5540141987_a0cce3d672_m.jpg" width="240" height="227" alt="MC13224 Little" /></a><a href="http://www.flickr.com/photos/travisgoodspeed/5540763624/" title="MC13224 Flash (SST24WF010) by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5014/5540763624_ba52329c14_m.jpg" width="186" height="240" alt="MC13224 Flash (SST25WF010)" /></a><br /><br />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 <a href="http://www.sst.com/products/?inode=41343">SST25WF010</a>, a SPI flash chip that aside from its low voltage is easily interfaced with a GoodFET or Arduino.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5559270923/" title="SST25WF010 Badge by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5176/5559270923_616d67d23b_m.jpg" width="240" height="230" alt="SST25WF010 Badge" /></a><br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5541052982/" title="MC13224 NVM_REG by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5051/5541052982_9847652e73.jpg" width="500" height="432" alt="MC13224 NVM_REG"></a><br /><br />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? <a href="http://www.freescale.com/files/rf_if/doc/ref_manual/MC1322xRM.pdf">MC1322xRM.pdf</a> 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.<br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5724960117/" title="RedBee w/ SECU Bypass by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5129/5724960117_bb2b465a4b.jpg" width="500" height="375" alt="RedBee w/ SECU Bypass"></a><br /><br />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.<br /><br />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.<br /><br />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.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com170tag:blogger.com,1999:blog-3638505461399232379.post-22050903018051222452011-03-01T03:41:00.001-05:002011-03-01T03:41:00.453-05:00GoodFET on the TelosB, TMote Skyby Travis Goodspeed <travis at radiantmachines.com><br />with kind thanks to <a href="http://www.cs.dartmouth.edu/~sergey/">Sergey Bratus</a>, <a href="http://rmspeers.com/">Ryan Speers</a>, and Ricky Melgares,<br />for contributions of code, conversation, and general neighborliness.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/3118926786/" title="Telos B by Travis Goodspeed, on Flickr"><img src="http://farm4.static.flickr.com/3235/3118926786_c0b724ec36_m.jpg" width="240" height="104" alt="Telos B" /></a><br /><br />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 <a href="http://www.zolertia.com/products/Z1">Zolertia Z1</a> 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.<br /><br />This brief tutorial will walk you through cross-compiling the <a href="http://goodfet.sourceforge.net/">GoodFET</a> firmware for the <a href="http://goodfet.sourceforge.net/hardware/telosb/">Telos B or TMote Sky</a>, 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.<br /><br /><b>Compiling the Firmware</b><br /><br />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 <a href="http://goodfet.sourceforge.net/hardware/nhb12/">Next Hope Badge</a> 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.<br /><br />Additionally, the Telos B uses the <a href="http://focus.ti.com/docs/prod/folders/print/msp430f1611.html">MSP430F1611</a> 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.)<br /><br />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 '<a href="http://goodfet.sourceforge.net/clients/goodfet.monitor/">monitor</a> <a href="http://goodfet.sourceforge.net/clients/goodfet.spiflash/">spi</a> <a href="http://goodfet.sourceforge.net/clients/goodfet.ccspi/">ccspi</a>'.<br /><br /><pre>export platform=telosb<br />export mcu=msp430x1611<br />export config='monitor ccspi spi'<br />make clean install</pre><br /><br /><b>Accessing the SPI Flash</b><br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5422687146/" title="GoodFET for the Telos B by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5019/5422687146_ecf2966955_m.jpg" width="207" height="132" alt="GoodFET for the Telos B" /></a><br /><br />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'.<br /><br />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.<br /><br /><b>Sniffing ZigBee, 802.15.4</b><br /><br />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 <i>must</i> set $platform to be 'telosb' or the client will not connect.<br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5479801716/" title="goodfet.ccspi sniff 11 by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5291/5479801716_dffc676d0b.jpg" width="271" height="104" alt="goodfet.ccspi sniff 11" /></a><br /><br />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 <a href="http://www.secdev.org/projects/scapy/">Scapy</a> 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.<br /><br />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.)<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5476495293/" title="802.15.4 Scapy by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5172/5476495293_f6d131247d.jpg" width="269" height="271" alt="802.15.4 Scapy" /></a><br /><br />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.<br /><br /><b>Scripting the CC2420</b><br /><br />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 <a href="http://www.tinyos.net/tinyos-2.x/apps/RadioCountToLeds/README.txt">RadioCountToLeds</a> application.<br /><br />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?<br /><br />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()'.<br /><br />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.)<br /><br />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.<br /><br />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)'.<br /><br />That's really all there is to it.<br /><br /><b>Conclusions</b><br /><br />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 <a href="http://travisgoodspeed.blogspot.com/2009/03/breaking-802154-aes128-by-syringe.html">by syringe</a> with a bus analyzer.<br /><br />That's all folks. Grab a Telos B or TMote and start poking at devices. Good targets might include <a href="http://www.digitalmunition.com/_/Blog/Entries/2010/11/29_Starting_to_reverse_a_Z-wave_door_lock_kit.html">Z-Wave door locks</a> and <a href="http://www.digitalmunition.com/_/Blog/Entries/2010/11/25_More_small_steps_with_Saleae.html">ZigBee thermostats</a>.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com75tag:blogger.com,1999:blog-3638505461399232379.post-72480654491163626732011-02-07T01:09:00.001-05:002011-02-07T01:42:36.321-05:00Promiscuity is the nRF24L01+'s Dutyby Travis Goodspeed <travis at radiantmachines.com><br />extending the work of Thorsten Schröder and Max Moser<br />of the <a href="http://www.remote-exploit.org/?page_id=602">KeyKeriki v2.0</a> project.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5385189893/" title="NHBadge and a Keyboard by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5213/5385189893_898a16ccf2.jpg" width="500" height="375" alt="NHBadge and a Keyboard" /></a><br /><br />Similar to Bluetooth, the protocols of the Nordic VLSI <a href="http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=94">nRF24L01+</a> 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.<br /><br />As proof of concept, I present a promiscuous sniffer for the <a href="http://www.microsoft.com/hardware/mouseandkeyboard/ProductDetails.aspx?pid=117">Microsoft Comfort Desktop 5000</a> 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 <a href="http://www.remote-exploit.org/?page_id=602">KeyKeriki v2.0</a> 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 <a href="http://thenexthope.org/">Next Hope</a>, running the <a href="http://goodfet.sourceforge.net/hardware/nhb12/">GoodFET Firmware</a>.<br /><br /><b>Part 1: or, Why sniffing is hard.</b><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5180664232/" title="nRF24L01 Die by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1437/5180664232_4f105b824f.jpg" width="488" height="500" alt="nRF24L01 Die" /></a><br /><br />Radio packets usually begin with a preamble, followed by a SYNC field. In the <a href="http://www.ti.com/corp/docs/landing/simpliciTI/">SimpliciTI</a> 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.<br /><br />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 <a href="http://www.openbeacon.org/">OpenBeacon</a> packet will begin with {0x55, 0x01, 0x02, 0x03, 0x02, 0x01} while a <a href="http://travisgoodspeed.blogspot.com/2010/07/reversing-rf-clicker.html">Turning Point Clicker</a>'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.<br /><br />Moser and Schröder solved this problem by using an <a href="www.amiccom.com.tw">AMICCOM</a> 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.<br /><br />A similar solution is used in Michael Ossmann's <a href="http://ubertooth.sourceforge.net/">Project Ubertooth</a> 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.<br /><br /><b>Part 2: or, Sniffing on the cheap.</b><br />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 <a href="http://goodfet.sourceforge.net/clients/goodfet.nrf/">goodfet.nrf</a> client.<br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5370000279/" title="nRF Address Width by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5006/5370000279_5deca53cd0.jpg" width="345" height="72" alt="nRF Address Width" /></a><br /><br />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?<br /><br />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. <br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5417524810/" title="nRF24L01+ Promiscuous Mode by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5137/5417524810_cb494ea655.jpg" width="500" height="263" alt="nRF24L01+ Promiscuous Mode" /></a><br /><br />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.<br /><br />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.<br /><br />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 <a href="http://pastebin.com/8CbxHzJ9">http://pastebin.com/8CbxHzJ9</a>. Sorting the list reveals that the MAC address 0x0102030201 is the most popular, which is in fact the address used by OpenBeacon tags.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5348416729/" title="goodfet.nrf autotune by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5241/5348416729_fd75b9735b.jpg" width="393" height="157" alt="goodfet.nrf autotune" /></a><br /><br />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 <a href="http://www.remote-exploit.org/?page_id=602">KeyKeriki</a>. 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 <a href="http://travisgoodspeed.blogspot.com/2009/03/breaking-802154-aes128-by-syringe.html">syringe probes</a> aren't convenient.<br /><br /><b>Part 3: or, Sniffing a keyboard effectively.</b><br /><br />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.<br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5354354594/" title="XOR Crypto! by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5002/5354354594_f7bf64f3af.jpg" width="500" height="354" alt="XOR Crypto!" /></a><br /><br />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!<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5393852890/" title="MSKB5k Traffic by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5176/5393852890_acfc901c73.jpg" width="500" height="199" alt="MSKB5k Traffic" /></a><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5416657948/" title="NHBadge Key Sniffer by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5052/5416657948_8fe0b0b4c6.jpg" width="289" height="500" alt="NHBadge Key Sniffer" /></a><br /><br /><b>Part 4; or, Reproducing these results.</b><br /><br />All of the code for this article is available in the <a href="http://goodfet.sourceforge.net/">GoodFET Project's</a> repository, as part of GoodFETNRF.py and its <a href="http://goodfet.sourceforge.net/clients/goodfet.nrf/">goodfet.nrf</a> client script. The hardware used was an <a href="">NHBadge12</a>, although an NHBadge12B or a GoodFET with the SparkFun <a href="http://www.sparkfun.com/products/705">nRF24L01+ Transceiver Module</a> will work just as well.<br /><br />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.<br /><br />All code presently in the repository will be refactored and rewritten, so revert to revision 885 or check the documentation for any changes.<br /><br /><b>Conclusions</b><br /><br />Contrary to prior belief, the nRF24L01+ <i>can</i> 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+.<br /><br />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.<br /><br />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?<br /><br />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.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com308tag:blogger.com,1999:blog-3638505461399232379.post-52138081135365820032011-01-24T09:34:00.001-05:002011-01-24T09:34:00.176-05:00Generic CC1110 Sniffing, Shellcode, and iClickers<a href="http://www.flickr.com/photos/travisgoodspeed/5035132843/" title="Chipcon CC1110 Logo by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4086/5035132843_d80ec45ed5.jpg" width="500" height="400" alt="Chipcon CC1110 Logo" /></a><br /><br />Howdy y'all,<br /><br />I haven't the time to write individual posts on these subjects, but I do have plenty of new features for the <a href="http://focus.ti.com/docs/prod/folders/print/cc1110f32.html">CC1110</a> 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.<br /><br />In order to follow along with these examples, you will need to have <a href="http://focus.ti.com/docs/toolsw/folders/print/smartrftm-studio.html">SmartRF Studio</a> 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 <a href="http://goodfet.sourceforge.net/clients/goodfet.cc/">goodfet.cc</a> client page.<br /><br /><b>(1) Packet sniffing, and other neighborly scripts.</b><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5247787940/" title="GoodFET Simpliciti Sniffing! by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5164/5247787940_daca7e2506.jpg" width="500" height="182" alt="GoodFET Simpliciti Sniffing!" /></a><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5252697453/" title="GoodFET SimpliciTI Client by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5089/5252697453_cbcd04f222.jpg" width="443" height="500" alt="GoodFET SimpliciTI Client" /></a><br /><br />Not only protocols intended for the GoodFET, but also others which are coincidentally compatible, are supported. Thanks to some register settings contributed by <a href="http://www.ossmann.com/mike/">Mike Ossman</a>, you can sniff and decipher <a href="http://www.iclicker.com/dnn/">i<clicker</a> traffic with 'goodfet.cc iclicker'.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5339425252/" title="goodfet.cc iclicker by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5009/5339425252_ffac652fce.jpg" width="424" height="340" alt="goodfet.cc iclicker" /></a><br /><br />The i<clicker uses a Xemics <a href="http://www.semtech.com/images/datasheet/xe1203f.pdf">XE1203F (PDF)</a> 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 <a href="http://sourceforge.net/projects/gr-clicker/">GR-Clicker</a> 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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4834814212/" title="iClicker by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4092/4834814212_ec435d2f63.jpg" width="500" height="375" alt="iClicker" /></a><br /><br />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]':<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5247268140/" title="GoodFET CC1110 RSSI Graph by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5245/5247268140_b1f831f59f.jpg" width="257" height="500" alt="GoodFET CC1110 RSSI Graph" /></a><br /><br />Care to jam another transmitter? Just like with the <a href="http://travisgoodspeed.blogspot.com/2010/06/hacking-next-hope-badge.html">Next Hope Badge</a>'s GoodFET mode, it takes a single command to hold a carrier wave.<br />'goodfet.cc carrier [freq]'<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5242553766/" title="Chipcon Carrier by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5162/5242553766_649ba3ea64.jpg" width="500" height="375" alt="Chipcon Carrier" /></a><br /><br /><b>(2) Shellcode, now for quiche-eaters!</b><br /><br />At the risk of appearing to facilitate <a href="http://www.pbm.com/~lindahl/real.programmers.html">quiche-eating</a>, I'd like to quickly explain the new shellcode interface for placing code fragments on a Chipcon 8051 target, such as the CC1110.<br /><br />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.<br /><br />As I described in my <a href="http://travisgoodspeed.blogspot.com/2009/10/cc2430-debug-protocol-first-notes.html">CC2430 Debugging Notes</a>, 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 <a href="http://focus.ti.com/lit/ug/swra124/swra124.pdf">SWRA124</a> as machine code with assembly comments, beginning with the fragment shown below.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4019557552/" title="CC2430 Flash Routine by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2739/4019557552_1a502e952d.jpg" width="403" height="174" alt="CC2430 Flash Routine" /></a><br /><br />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.<br /><br />For example, this is the code that used to configure the crystal oscillator on the CC1110, a prerequisite for any radio operations:<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5246585381/" title="Chipcon Shellcode by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5126/5246585381_7c235d3c4d.jpg" width="500" height="186" alt="Chipcon Shellcode" /></a><br /><br />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.)<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5283782164/" title="CC1110 Crystal Shellcode by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5289/5283782164_f661cc724c.jpg" width="314" height="399" alt="CC1110 Crystal Shellcode" /></a><br /><br />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.<br /><br /><b>(3) Care to join the fun?</b><br /><br />There are a number of features remaining to be implemented in shellcode. Among them in a completed port of Ossmann's <a href="http://ossmann.blogspot.com/2010/03/16-pocket-spectrum-analyzer.html">$15 Spectrum Analyzer</a>, which I began in <a href="http://travisgoodspeed.blogspot.com/2010/10/cc1110-instrumentation-with-python.html">CC1110 Instrumentation in Python</a> 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.<br /><br />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.<br /><br />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 <a href="http://en.wikipedia.org/wiki/EME_%28communications%29">EME</a> moon-bounce experiments, without losing backward compatibility with 19th century radio technology.<br /><br />As a prize, I offer one ale apiece for GoodFET patches implementing these features.<br /><br />Stay neighborly,<br />--Travis Goodspeed<br /><travis at radiantmachines.com>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com83tag:blogger.com,1999:blog-3638505461399232379.post-26135118629856251892010-12-06T02:16:00.006-05:002010-12-06T02:16:00.068-05:00Hacking a Knitting Machine's Keypadby Travis Goodspeed <travis at radiantmachines.com><br />in collaboration with <a href="http://fabienne.us/">Fabienne Serriere</a> and <a href="http://scherpenisse.net/">Arjan Scherpenisse</a>,<br />at Mediamatic's RFID Devcamp 2010, Amsterdam,<br />for <a href="http://www.mediamatic.net/page/167514/en">Multithreaded Banjo Dinosaur Knitting Adventure 2D Extreme</a>,<br />with kind thanks to David Carne.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5206596473/" title="Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5047/5206596473_326f3a0f8d.jpg" width="500" height="375" alt="Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme" /></a><br /><br />Thanks to some extra-neighborly blackmail by Fabienne, I spent last week hacking up a storm in Amsterdam. By extending the work of <a href="http://www.antitronics.com/wiki/index.php?title=Electroknit_Technical_Information">Steven Conklin</a>, <a href="http://ladyada.net/learn/electroknit/">Limor Fried</a>, 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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br /><!--Background--><br /><br />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 <a href="http://daveshacks.blogspot.com/2010/01/im-me-hacking.html">IM ME Hacking</a> describes in detail how the keypad of the GirlTech IMME works, and all other implementations seem to function similarly.<br /><br />The connections between rows and columns are just switches.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5235653449/" title="KeySchem by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5005/5235653449_ffbf355c62_m.jpg" width="240" height="94" alt="KeySchem" /></a><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5231512479/" title="KH930 Keypad Topside by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5082/5231512479_67c3461d19.jpg" width="500" height="278" alt="KH930 Keypad Topside" /></a><br /><br /><!--Arduino Hardware--><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5232367418/" title="Keymu10 Rows by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5122/5232367418_e1573afc98.jpg" width="276" height="437" alt="Keymu10 Rows" /></a><br /><br />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.<br /><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5232385174/" title="Keymu Prototype by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5003/5232385174_ce2c910b47.jpg" width="500" height="333" alt="Keymu Prototype" /></a><br /><br />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.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5232676950/" title="Keymu10 Schematic by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5202/5232676950_6a271b5543.jpg" width="454" height="500" alt="Keymu10 Schematic" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5232367414/" title="Keymu10 Shield by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5241/5232367414_930db7af0b.jpg" width="384" height="500" alt="Keymu10 Shield" /></a><br /><br /><!--Software--><br /><br />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.<br /><br />Full keyboard emulator code is available either by <a href="http://pastebin.com/Zbj2DqiY">pastebin</a> or from SVN. You'll find it in banjo/code/arduino.<br /><i>svn checkout svn://svn.mediamatic.nl/devcamps/camp10/banjo</i><br /><br />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 <i>setup()</i> function, the pattern is loaded whenever the device is reset.<br /><br />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,<br /><i>Device::SerialPort->new("/dev/ttyACM0")->pulse_dtr_on(100)</i><br /><br />The end result, with a machine typing by itself, looks a little like this,<br /><object type="application/x-shockwave-flash" width="400" height="300" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="flashvars" value="intl_lang=en-us&photo_secret=c65846a38e&photo_id=5235543171"></param> <param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=71377"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&photo_secret=c65846a38e&photo_id=5235543171" height="300" width="400"></embed></object><br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5207189466/" title="Banjo Dinosaur by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5163/5207189466_c7aedf8031.jpg" width="500" height="375" alt="Banjo Dinosaur" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5206594273/" title="Arecibo Pattern by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5168/5206594273_fc7b9f3d04.jpg" width="375" height="500" alt="Arecibo Pattern" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5206593399/" title="Intel 4001 Art by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5168/5206593399_614870a1e3.jpg" width="500" height="375" alt="Intel 4001 Art" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5206592435/" title="Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme by Travis Goodspeed, on Flickr"><img src="http://farm6.static.flickr.com/5201/5206592435_c018fd86b3.jpg" width="500" height="375" alt="Multi-Threaded Banjo Dinosaur Knitting Adventure 2D Extreme" /></a>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com100tag:blogger.com,1999:blog-3638505461399232379.post-67420012532118323942010-11-01T08:00:00.001-04:002010-11-01T08:00:08.934-04:00Bitmapped Sprites on the GirlTech IMMEby Travis Goodspeed <travis at radiantmachines.com><br />with sprites by <a href="http://eliskipp.com/blog/">Eli Skipp</a>,<br />extending Dave's <a href="http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html">LCD reversing</a>,<br />and with thanks to <a href="http://ossmann.blogspot.com/">Mike Ossmann</a>.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5008846873/" title="ZombieGotcha by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4130/5008846873_c9244d1bca.jpg" width="500" height="375" alt="ZombieGotcha" /></a><br /><br />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.<br /><br />To quickly recap, the GirlTech IMME is a children's toy powered by the <a href="http://focus.ti.com/docs/prod/folders/print/cc1110f32.html">CC1110F32</a>, 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 <a href="http://daveshacks.blogspot.com/2010/01/im-me-hacking.html">attaching a debugger</a> and <a href="http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html">reversing the LCD</a>, it is possible to <a href="http://travisgoodspeed.blogspot.com/2010/03/im-me-goodfet-wiring-tutorial.html">wire a GoodFET</a> into the IMME, allowing for debugging and reprogramming of the device.<br /><br /><!--Framebuffer format.--><br /><br />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 <a href="http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html">Dave's LCD Demo</a> 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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5131629739/" title="IMME Font 'H' by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4112/5131629739_0f9d9e899c.jpg" width="326" height="157" alt="IMME Font 'H'" /></a><br /><br />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.<br /><br />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.)<br /><br /><!--Sprite transcription.--><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5017579645/" title="girlpix by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4128/5017579645_f9d43f1a38.jpg" width="288" height="128" alt="girlpix" /></a><br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5132898054/" title="PNM Format by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1063/5132898054_47c788cf3f.jpg" width="468" height="322" alt="PNM Format" /></a><br /><br />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, <a href="http://perl.pastebin.com/5Mvi6f66">sprite2c.pl</a>, 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 <i>__code unsigned char[]</i>, with the <i>__code</i> keyword implying that the object should be stored in Flash rather than RAM.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5132328043/" title="sprit2cl.pl by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1353/5132328043_62aca4439a.jpg" width="500" height="417" alt="sprit2cl.pl" /></a><br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5133020586/" title="zsprites.c by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1311/5133020586_1f3f2b6072.jpg" width="260" height="304" alt="zsprites.c" /></a><br /><br /><!--Frambuffer dumping.--><br /><br />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.<br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5132964968/" title="Framebuffer Dump by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4023/5132964968_d1bde64ae7.jpg" width="356" height="218" alt="Framebuffer Dump" /></a><br /><br />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.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5132993398/" title="FBGetSet by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1122/5132993398_0bc41f8367.jpg" width="307" height="145" alt="FBGetSet" /></a><br /><br />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 <a href="http://ossmann.blogspot.com/2010/03/16-pocket-spectrum-analyzer.html">spectrum analyzer firmware</a>, allowing for channels to be redrawned as they are scanned rather than flushed from a frame-buffer.<br /><br />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.<br /><br />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 <a href="http://travisgoodspeed.blogspot.com/2010/10/cc1110-instrumentation-with-python.html">CC1110 Instrumentation with Python</a>, 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 <a href="http://www.totalphase.com/products/beagle_ism/">Total Phase Beagle</a> or other SPI protocol analyzer.<br /><br />For those of you with an IMME, Eli and I will be releasing the ZombieGotcha game at the <a href="http://events.ccc.de/category/27c3/">Twenty-Seventh Chaos Communications Congress</a> 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.)<br /><br />As a final note, a teaser of the ZombieGotcha opening screen can be found <a href="http://pastebin.com/tU3YhejH">here</a> 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.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com55tag:blogger.com,1999:blog-3638505461399232379.post-24879652686777167792010-10-05T00:10:00.015-04:002010-10-09T12:56:11.338-04:00CC1110 Instrumentation with Pythonby Travis Goodspeed <travis at radiantmachines.com><br />concerning the <a href="http://www.girltech.com/electronics-imMe.aspx">GirlTech IMME</a>,<br />utilizing the <a href="http://goodfet.sourceforge.net/clients/goodfet.cc/">GoodFET's Chipcon Debugger</a><br />to instrument Michael Ossmann's <a href="http://ossmann.blogspot.com/2010/03/16-pocket-spectrum-analyzer.html">$16 Pocket Spectrum Analyzer</a>.<br /><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5054987346/" title="Kenwood Spectrum, Overlay by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4130/5054987346_a98104bec4.jpg" width="500" height="375" alt="Kenwood Spectrum, Overlay" /></a><br /><br />Often a neighbor, such as myself, finds himself with a damned useful tool that's missing logging. Further, when this is a black-box application, it is undeniably inconvenient to patch in logging where no communications method exists. In this brief article, I will demonstrate how to instrument a Chipcon CC1110 application using Python and a GoodFET with zero bytes of modification to the original firmware image. My target's source code is available, but the technique applies just as well to black-box firmware.<br /><br />Specifically, I want to dump the raw data from Michael Ossmann's <a href="http://ossmann.blogspot.com/2010/03/16-pocket-spectrum-analyzer.html">$16 Pocket Spectrum Analyzer</a> in order to demo it on stage at our Toorcon 12 talk, <a href="http://sandiego.toorcon.org/index.php?option=com_content&task=section&id=3&Itemid=9#lineup">Real Men Carry Pink Pagers</a>. I'll assume the reader to be familiar with Mike's article, as well as my article on <a href="http://travisgoodspeed.blogspot.com/2010/03/im-me-goodfet-wiring-tutorial.html">wiring an IMME</a> for debugging with a GoodFET. Readers wishing to play along can order a GoodFET31 for little or no money by following <a href="http://goodfet.sourceforge.net/orders/">these instructions</a>.<br /><br />From the <a href="http://focus.ti.com/docs/prod/folders/print/cc1110f32.html">datasheet</a> or Mike's Makefile it can be seen that the external RAM (XDATA, which is called external for historic reasons) section begins at 0xF000. The only structure at this location is <i>xdata channel_info chan_table[NUM_CHANNELS]</i>, where NUM_CHANNELS is defined to be 132 and the channel_info struct is eight bytes, defined as <pre>typedef struct {<br /> /* frequency setting */<br /> u8 freq2;<br /> u8 freq1;<br /> u8 freq0;<br /> <br /> /* frequency calibration */<br /> u8 fscal3;<br /> u8 fscal2;<br /> u8 fscal1;<br /><br /> /* signal strength */<br /> u8 ss;<br /> u8 max;<br />} channel_info;</pre><br /><br />The first several entries in this struct might be as follows. The first of these lines defines the frequency to be 0x22af4b, the frequency calibration to be 0xef2c27, and the signal strength to be 0x41. The final byte defines the maximum strength, which is zero unless max-highlighting mode is turned on.<pre> 22 af 4b ef 2c 27 41 00<br /> 22 b1 43 ef 2c 27 3e 00<br /> 22 b3 3b ef 2c 27 46 00<br /> 22 b5 33 ef 2c 27 3c 00<br /> 22 b7 2b ef 2c 27 44 00<br /> 22 b9 23 ef 2c 28 3c 00<br /> 22 bb 1b ef 2c 28 42 00<br /> 22 bd 13 ef 2c 28 3f 00<br /> 22 bf 0b ef 2c 28 3d 00<br /> 22 c1 03 ef 2c 28 40 00<br /> 22 c2 fb ef 2c 28 3d 00<br /> 22 c4 f3 ef 2c 28 3e 00<br /> ...</pre><br /><br />This information can be extracted by halting and resuming the CPU, just as I did in my article on the <a href="http://travisgoodspeed.blogspot.com/2009/12/prng-vulnerability-of-z-stack-zigbee.html">PRNG Vulnerability of Z-Stack's ZigBee SEP ECC</a> implementation. That is, GoodFETCC.CCpeekdatabyte() is used to grab these bytes from the CC1110's RAM. The following code dumped the fragment shown above.<pre>#!/usr/bin/env python <br /><br />import sys;<br /><br />sys.path.append('/Users/travis/svn/goodfet/trunk/client/')<br /><br />from GoodFETCC import GoodFETCC;<br />from intelhex import IntelHex16bit, IntelHex;<br />import time;<br /><br />client=GoodFETCC();<br />client.serInit();<br /><br />client.setup();<br />client.start();<br /><br />bytescount=8*132;<br />bytestart=0xf000;<br /><br />while 1:<br /> time.sleep(1);<br /> client.CChaltcpu();<br /> <br /> dump="";<br /> for foo in range(0,bytescount):<br /> dump=("%s %02x" % (dump,client.CCpeekdatabyte(bytestart+foo)));<br /> if foo%8==7: dump=dump+"\n";<br /> print dump;<br /> sys.stdout.flush();<br /> client.CCreleasecpu();<br /></pre><br /><br />To get proper data, it is necessary to add a wake-up delay of a few seconds, so that the table is populated by the first sampling. Additionally, it is handy to convert the frequency to MHz from its native unit (Hz/396.728515625). Finally, successive pages should be separated by a time column in order to facilitate graphing. The result is <a href="http://pastebin.com/gqPS1Qms">this script</a>, which can be found in the GoodFET project as "contrib/ccspecantap/specantap.py".<br /><br />An example recording can be seen below, as a spectrum recording of a friend's Kenwood FreeTalk UBZ-AL14 FM Transceiver unit. This is compatible with other family FM radios, and I wanted to know which center frequencies were in use. In the first image, I've highlighted the noise floor as blue and the peaks as green. In the second image, the time domain is used to show broadcasts on several channels in sequence, all of which fall into one of the two center frequencies: 925MHz and 935MHz. The raw data is <a href="http://pastebin.com/90TZD97v">here</a>, best viewed with NASA's excellent <a href="http://astrophysics.arc.nasa.gov/~pgazis/viewpoints.htm">Viewpoints</a> tool.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/5054737006/" title="Kenwood FreeTalk Spectrum by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4151/5054737006_4aec43c176.jpg" width="450" height="346" alt="Kenwood FreeTalk Spectrum" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/5054736856/" title="Kenwood FreeTalk Channels by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4127/5054736856_e0e174d3e3.jpg" width="440" height="346" alt="Kenwood FreeTalk Channels" /></a><br /><br />Future additions to this project will include integration into the GoodFET radio framework, as well as a 2.4GHz version built around the CC2430 and CC2530. The performance of the tap can be greatly improved by using block transactions rather than peeking individual bytes, and the view can be re-tuned by poking the configuration IDATA variables, positions of which are described in <a href="http://pastebin.com/HePVmC50">specan.rst</a> as produced by the SDCC compiler.<br /><br />It's also handy to know that a Chipcon radio will halt if the 0xA5 opcode is executed. In this manner, patching a single byte of a while() loop can allow the state at every iteration to be dumped.<br /><br />This technique of scripted debugging through a programmer can be handy for more than instrumentation. Unit tests can be run on an assembly line without additional wiring, and--by single-stepping--execution traces of unknown firmware can be generated for assisting in reverse engineering. Those with enough patience can use this to fuzz test embedded systems for security vulnerabilities.<br /><br />For help instrumenting your own Chipcon or MSP430 project, join us in #goodfet on irc.freenode.net or send me an email. The project has advanced to the point where interesting things can be done from Python alone, and I'd quite like to see what could be done with it.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com34tag:blogger.com,1999:blog-3638505461399232379.post-9983097288745729012010-07-04T17:00:00.000-04:002010-07-04T17:27:17.912-04:00Reversing an RF Clickerby Travis Goodspeed <travis at radiantmachines.com><br />concerning the Turning Point <a href="http://www.turningtechnologies.com/audienceresponseproducts/responseoptions/responsecards/responsecardrf/">ResponseCard RF</a>,<br />having FCC ID R4WRCRF01,<br />patented as <a href="http://www.google.com/patents?vid=USPAT7330716">USA 7,330,716</a>.<br /><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4747156868/" title="Turning Point Clicker by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4079/4747156868_867d3e6c09.jpg" alt="Turning Point Clicker" height="375" width="500" /></a><br /><br />In this article, I describe in detail the methods by which I have reverse engineered the TurningPoint ResponseCard RF, casually known among students as a "Clicker". This 2.4GHz radio transceiver is used in undergraduate university classrooms for automated roll-call and in-class quizzing or voting. By dumping and analyzing its firmware, one can determine the radio protocol necessary to intercept and forge packets, as well as to build a custom base station. The radio hardware that I have used is a reprogrammed <a href="http://travisgoodspeed.blogspot.com/2010/06/hacking-next-hope-badge.html">Next HOPE Badge</a> running the <a href="http://goodfet.sourceforge.net/">GoodFET</a> firmware.<br /><br />A follow-up article will likely describe the writing of replacement firmware, but that can be easily enough discovered by an enterprising reader. My purpose instead is to provide the information necessary to build compatible products, as well as to teach the technique of reverse engineering these products to find such information when none is available.<br /><br /><h3>Disassembly</h3><br />The Clicker's keypad is attached only with adhesive, and it can be pulled off after lifting an edge with a knife blade. Beneath the keypad, there are four screws holding the board in place, plus a fifth from the rear of the device. If you are lucky, these will be small Phillips screws, but the unlucky will find tri-wing "Nintendo" screws. I was lucky to have one of each type, but those with neither a Phillips-screwed Clicker nor a tri-wing screwdriver can <a href="http://www.dealextreme.com/details.dx/sku.1887">buy one</a> or try one of <a href="http://www.mmmonkey.co.uk/console/other/diy-gamebit.htm">these tricks</a>.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4759210205/" title="Devil Screws by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4099/4759210205_560c334bbf.jpg" width="500" height="375" alt="Devil Screws"></a><br /><br />In either case, it isn't strictly necessary to open your clicker, as test-points for dumping and replacing its firmware are accessible from the battery compartment. Further, the radio communications are accessible with no hardware access whatsoever.<br /><br /><h3>Hardware</h3><br />The Clicker is built upon a <a href="http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=79">Nordic nRF24E1</a> chip, which combines an 8051 microcontroller with an <a href="http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=64">nRF2401</a> radio transceiver. Although the two cores have been combined into a single package, the 8051 core speaks to the radio through a few bit-field registers and an internal SPI bus, which is shared with the external SPI bus.<br /><br />As the nRF24E1 lacks internal non-volatile storage, a <a href="http://www.datasheetcatalog.org/datasheet/catalystsemiconductor/25C64.pdf">CAT25C32 (pdf)</a> SPI EEPROM is used for program and configuration storage. Within the microcontroller, there is a masked ROM bootloader from 8000h to 81FFh that loads executable code from the EEPROM into executable RAM from 0000h to 0FFFh.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4759210329/" title="Hacked Clicker Board by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4122/4759210329_c79c51be04.jpg" width="375" height="500" alt="Hacked Clicker Board"></a><br /><h3>Dumping Firmware</h3><br />At the base of the circuit board's primary side, there are test points for the SPI EEPROM. As the default firmware only uses the SPI bus when buttons are pressed, this EEPROM may be dumped at any point after the device has booted. The test points are as follows, which should be matched to those of equivalent names in the <a href="http://goodfet.sourceforge.net/apps/spi/">GoodFET SPI Table</a>. They were determined by use of a continuity tester.<table style="width: 120px; height: 160px;" border="1"><br /><tbody><tr><td>T4</td><td>MISO</td></tr><tr><td>T5</td><td>SCK</td></tr><tr><td>T6</td><td>MOSI</td></tr><tr><td>T3</td><td>!CS</td></tr><tr><td>T1</td><td>VCC</td></tr><tr><td>GND</td><td>GND</td></tr></tbody></table><br /><br />In order to dump the firmware, I quickly wrote a <a href="http://goodfet.sourceforge.net/">GoodFET</a> client for the 25C32 using its datasheet. A read is performed by sending {0x02, AL, AH, 0} as a SPI transaction, with the result coming back as the fourth byte. Doing it this way with the GoodFET's SPI driver is slower than having C code within the GoodFET dump the whole ROM, but it's fast enough for a dump and takes very little code.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749964096/" title="Quick and Dirty 25C32 Driver by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4135/4749964096_011e7d59c0.jpg" width="483" height="185" alt="Quick and Dirty 25C32 Driver"></a><br /><br />From this point, I dumped the firmware with 'goodfet.spi25c dump image.hex', converted the Intel Hex file to binary, and popped it open in Emacs/hexl. The result looks something like the following, whose format is described in the nRF24E1 datasheet. The opening passage is {u8 config, u8 entry offset, u8 blockcount}. Here {0x0B, 0x07, 0x0B} means that executable code begins at byte 0x07, and that the total image length is 0x0B*256==2,816 bytes. (Additional space within the SPI ROM is unused and left as 0xFF.)<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4747979687/" title="Clicker ROM by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4123/4747979687_40f4297fc0.jpg" width="350" height="86" alt="Clicker ROM"></a><br /><br />To produce an image suitable for a disassembler, I cut the bytes before 0x07 to make an image beginning with {0x02, 0x0A, 0xB7, ...}. The extra bytes in this region are the serial number and default frequency, but we'll get back to that later.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4756729850/" title="Clicker Dev Kit by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4121/4756729850_b0896e7a4b.jpg" width="500" height="375" alt="Clicker Dev Kit"></a><br /><br /><h3>Firmware Analysis</h3><br />As the firmware is only three kilobytes, it doesn't take terribly long to reverse engineer. First, the Special Function Registers (SFR) which are defined on pages 79 and 81 of the nRF24E1 datasheet are fed to the disassembler.<br /><br />(I'm using IDA Pro here, but any 8051 disassembler with a decent text editor could suffice. All of the following function labels are from my imagination, while Special Function Registers (SFRs) come from the nRF24E1 datasheet.)<br /><br />For example, "MOV 0xA0, #0x80" is rather opaque, but "MOV RADIO, #0x80" makes it clear that the immediate value 0x80 is being placed into the RADIO register. Page 89 of the datasheet will then explain that the high bit of the radio register is power control, so this instruction is powering up the radio for use. Similarly, "SETB RADIO.3" is setting the fourth bit of the RADIO register, which the datasheet describes as raising the CS signal.<br /><br />Once the SFR addresses are known, it becomes useful to search for them in order to identify the I/O routines. In the nRF24E1, the radio is accessed across a SPI bus, so a good first step is to identify the SPI routine. The function containing this code will always include a MOV involving the SPI_DATA register.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4750053432/" title="SPIRXTX for 8051 by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4138/4750053432_611d1cf9da.jpg" width="500" height="331" alt="SPIRXTX for 8051"></a><br /><br />Having this, a list of cross-references quickly shows that while few functions call the SPIRXTX function, each calls it many times. This is because the author has chosen to repeatedly call that function with immediate values, rather than to dump an array of bytes with a for(){} loop.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749434693/" title="Functions calling SPITXRX by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4074/4749434693_c4ae19b109.jpg" width="361" height="500" alt="Functions calling SPITXRX"></a><br /><br />While the disassembler can automatically identify the function entry points in the table above, it is not capable of giving them English names or descriptions. To understand how this is done, it is necessary to read the datasheets of the SPI devices.<br /><br />The SPI EEPROM chip, a CAT25C32, is used by dropping the !CS line then writing an opcode byte followed by its parameters or results. Opcodes include WREN/WRDI for write protection, RDSR/WRSR for accessing a status register, and READ/WRITE for reading and writing bytes. A WRITE may only be performed when the external !WP pin is low and the software write protect has been disabled by opcode. A transaction begins when !CS drops low and ends when it drops high.<br /><br />To identify the function which reads a byte from the 25C32, a few things can be safely assumed: (1) The function will begin by dropping some I/O pin (!CS). (2) The function will then broadcast the READ opcode, 0x03. (3) It will then broadcast a sixteen bit parameter; that is, DPL followed by DPH. (4) Finally, it will return the result of a fourth SPIRXTX call. In pseudocode, that would be something like<br /><pre>SPIROMPEEK(u16 ADR){<br /> SPIRXTX(0x03);<br /> SPIRXTX(ADRL);<br /> SPIRXTX(ADRH);<br /> return SPIRXTX();<br />}</pre><br /><br />Sure enough, one of the few functions calling SPIRXTX does exactly this. The constant pushing and popping of the parameters is a quirk of the compiler, which might possibly allow it to be identified. From the code below, it is clear that P0.0 is the !CS line of the CAT25C32.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749507983/" title="SPIROMPEEK by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4093/4749507983_f4ee298a0e.jpg" width="159" height="442" alt="SPIROMPEEK"></a><br /><br />The SPIROMPOKE function looks similar, except that two transactions are performed. First the WREN (0x06) opcode is sent to enable writing, then WRITE (0x02) is used to perform the actual write.<br /><br />The other SPI operations concern the nRF2401 radio core, which behaves differently from the EEPROM. Rather than transactions being an opcode followed by parameters, there is only a single SPI register that must be completely written during a transaction. A second register, selected by the CE line, contains the packets.<br /><br />The configuration is set by one big register, sent MSBit first. If fewer than the needed bytes are sent, the value is right-aligned into the lower bytes of the register. That is, the last byte sent is always (CHAN<<1)|RXMODE and the second to last always describes the radio configuration.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749548595/" title="nRF2401 Config Register by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4134/4749548595_7c36aafede.jpg" width="500" height="474" alt="nRF2401 Config Register"></a><br /><br />Searching around a bit yields the RADIOWRCONFIG function, the tail of which is below. It can be seen from the code that the 0x1A IRAM byte holds the channel number. That is, if 0x20 is stored at 0x1A, the radio will be configured to 2,432 MHz. The other configuration bytes reveal that the MAC addresses are 24 bits, the checksum is 16 bits, and the device broadcasts at maximum power sourced from a 16MHz crystal. (That the configured crystal is identical to the one on the board is very important. Some enterprising coders will lie to a chip about its crystal in order to access an unsupported radio frequency.)<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4750232304/" title="Clicker RF Config by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4119/4750232304_a2bcc94ab8.jpg" width="500" height="181" alt="Clicker RF Config"></a><br /><br />At this point, it still remains to sniff traffic is to find the target address to which packets are broadcast as well as the frequency. We'll start with the address, because that's a bit easier.<br /><br />The TXPACKET function involves a lot of PUSH and POP instructions, but it otherwise looks very similar to the RADIOWRCONFIG function, in that a series of bytes are written in order with repeated function calls to SPIRXTX. In pseudocode, this function becomes the following. From the radio documentation and configuration, it is clear that the first three bytes will be the target MAC address. From the RADIOWRCONFIG() function, it is equally clear that the three bytes at 0x1B are the receiving MAC address of the unit. (The parameter of the function happens to be the button press, as can be determined by tracking the keyboard I/O routines or viewing a few packets.)<br /><pre>void TXPACKET(u8 button){<br /> RADIOHOP(); //set channel<br /> <br /> //Target MAC address<br /> SPIRXTX(&0x1E);<br /> SPIRXTX(&0x1F);<br /> SPIRXTX(&0x20);<br /> <br /> //Source MAC address<br /> SPIRXTX(&0x1B);<br /> SPIRXTX(&0x1C);<br /> SPIRXTX(&0x1D);<br /> <br /> //Data value<br /> SPIRXTX(button);<br />}</pre><br />The radio itself will append a 16-bit CRC; therefore, the full packet then becomes {u24 tmac, u24 smac, u8 button}.<br /><br />To determine the value of the target MAC address, just grep the disassembly for "mov" and one of 0x1E, 0x1F, 0x20. The relevant instructions are as follows, setting the target MAC address to 0x123456. (In 8051 notation, the first instruction moves the immediate constant #0x12 into byte 0x1E of IRAM.)<pre>mov 0x1E, #0x12<br />mov 0x1F, #0x34<br />mov 0x20, #0x56</pre><br /><br />As this point, it would be possible to scan each channel for a few seconds, listening for packets sent to that address, but it's classier to find the value by static analysis. Acting on the hunch that the configuration is held in EEPROM and looking for references to the SPIROMPEEK() function, the READIDFREQ() function can be found. As can be seen in the fragment below, EEPROM[6] holds the channel number while the MAC address is at EEPROM[3,4,5].<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749663793/" title="Clicker Config by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4093/4749663793_e21e2a4c7c.jpg" width="500" height="304" alt="Clicker Config"></a><br /><br />As the EEPROM begins with "0b 07 0b <b>15 79 1b 29</b>", it's clear that the MAC address of the unit from which it came is 0x15791B and that it is broadcasting on 2400+0x29=2441MHz. This can be double-checked by the serial number "15791B" being printed on the label.<br /><br /><h3>Implementation</h3><br />Knowing the modulation scheme, target address, and packet contents, it becomes possible to sniff traffic from a Clicker. This is performed by use of the GoodFET firmware on a Next Hope badge, my <a href="http://travisgoodspeed.blogspot.com/2010/06/hacking-next-hope-badge.html">prior tutorial</a> for which describes the process of packet sniffing.<br /><br />The NHBadge board contains an <a href="http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=89">nRF24L01+</a> radio, which differs dramatically from the nRF2401 in terms of how it is configured. Still, the radios are sufficiently compatible. The following hack of the goodfet.nrf client allows packets to be sniffed from the air with proper checksumming.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749714857/" title="Sniffing TurningPoint Traffic by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4115/4749714857_4017a0df30.jpg" width="499" height="373" alt="Sniffing TurningPoint Traffic"></a><br /><br />Sure enough, here are some packets of the 5 button being pressed on unit 1F8760. The keypress is the final byte in ASCII.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4749724547/" title="Clicker Sniffing by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4093/4749724547_83f3ef94d4.jpg" width="255" height="157" alt="Clicker Sniffing"></a><br /><br /><h3>Response Codes</h3><br /><br />Now that it is clear how to receive and recognize button presses, it becomes necessary to reverse engineer the response codes which might be sent from the access point. Without hearing a reply of at least an ACK, the Clicker will continue to broadcast each message more than three hundred times. This takes more than ten seconds, during which all other key presses are ignored.<br /><br />The broadcast loop within the MAIN() function would look a little like this in C.<br /><pre>for(count=0;count< MAXCOUNT && !reply;count++){<br /> TXPACKET(button);<br /> reply=RADIORX();<br />}<br />switch(reply){...}<br /></pre><br /><br />This region is easy enough to find, but there's another command mode. An easier target is the channel hopping routine, which constantly broadcasts 0x3F while incrementing the channel, sticking with the last one on which a reply of 0x18 was received. Channels 1 through 83 are attempted; that is, 2,401 MHz to 2,483MHz at 1MHz steps.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4752399709/" title="Clicker SYN/ACK by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4121/4752399709_a0c292105c.jpg" width="395" height="314" alt="Clicker SYN/ACK"></a><br /><br />Checking this code within the MAIN() function reveals that its effect is to blink the green LED (P1.1) six times, exiting the broadcast loop. Other commands include 0x04 (LED Off), 0x06 (LED Green), 0x15 (LED Red), 0x11 (Blink Green), 0x14 (Blink Red), and 0x18 (Blink Green, Channel Lock). All undefined opcodes set the red LED.<br /><br /><h3>Conclusions</h3><br />By sniffing traffic within a classroom, it is possible to watch votes as they are being cast by students. Similarly, packets could be broadcast by a reprogrammed Clicker or NHBadge to make a student in virtual attendance, automatically voting with the majority so as to gain perfect attendance and a solid C quiz average. Where instant feedback is available, this might even allow for a solid A quiz average. Without taking advantage of the masked-ROM option of the nRF24E1, the code cannot be even slightly protected from extraction and reverse engineering.<br /><br />Less adventurous users can jam the network by running 'goodfet.nrf carrier 2441000000' to hold a carrier wave on the channel. The only attempt at a frequency change is made when pressing the GO button, at which point the new channel can be discovered and similarly jammed.<br /><br />Since performing this work, it has come to my attention that a USRP plugin for doing this to the competing 900MHz iClicker product is available as <a href="http://gr-clicker.sourceforge.net/">http://gr-clicker.sourceforge.net/</a>. Additionally, the infrared Clicker units were broken with a little tool called <a href="http://midnightresearch.com/projects/surveysays/">Survey Says</a>. I have ordered more sophisticated Clicker models from CPS and Turning Point, and proper descriptions of them will soon follow.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com224tag:blogger.com,1999:blog-3638505461399232379.post-79003035841320078132010-06-10T23:12:00.035-04:002010-10-08T11:30:00.495-04:00Hacking the Next Hope Badgeby Travis Goodspeed <travis at radiantmachines.com><br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4746123271/" title="NHBadge by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4093/4746123271_7888160588.jpg" width="500" height="375" alt="NHBadge" /></a><br /><br />In just less than a month, the <a href="http://thenexthope.net/">Next Hope</a> conference will bring a few thousand neighbors to Manhattan's Hotel Pennsylvania to share all sorts of neighborly ideas. The following are some notes that will help enterprising neighbors to hack these badges, which will be running an MSP430 port of the <a href="http://www.openbeacon.org/">OpenBeacon</a> firmware. These badges are active RFID tags which beacon the position of each attendee a few times a second, so that the god damned devil army of lies--by which I mean the Next Hope badge committee--can track each attendee around the Hotel Pennsylvania. A second part will continue just before the conference begins, but I hope that this will provide sufficient food for thought.<br /><br />See <a href="http://amd.hope.net/">http://amd.hope.net/</a> for a nice little video explaining the purpose of the project as a whole. Those who do not wish to broadcast their positions can remove batteries or reprogram them, but to be thorough, they should turn off their <a href="http://www.theregister.co.uk/2010/04/22/gsm_info_disclosure_hack/">cellular phones</a> as well.<br /><br />A public HTTP API for querying the badge database is defined in the <a href="http://amd.hope.net/openamd_api_1.1.1.html">OpenAMD API Manual</a>, and a server should be available for beta testing before the conference begins. For example, to find the location of user 31337, the client will fetch <i>/api/location?user=31337</i> then look at the X, Y, and Location fields to determine the users position. As for this article, I will stick the badge hardware, its design, and all sorts of neighborly and malicious things that may be done with it or to it. Little mention will be made of the higher levels of the stack, as those are not my specialty.<br /><br />Also, in order to keep things fun, I reserve the right to lie about any and all technical details of the badge, its operation, or its security mechanisms. This document by no means complete, and there are still plenty of secrets to find.<br /><br /><h3>Badge Hardware, Usage</h3><br />The badges themselves are built from an <a href="http://focus.ti.com/docs/prod/folders/print/msp430f2618.html">MSP430F2618</a> or <a href="http://focus.ti.com/docs/prod/folders/print/msp430f2418.html">MSP430F2418</a> microcontroller, as well as an <a href="http://www.nordicsemi.com/index.cfm?obj=product&act=display&pro=94">NRF24L01+</a> 2.4GHz radio. The MSP430 chips were kindly donated by Texas Instruments, and replace the energy guzzling PIC chips of yesteryear. Further, they've got a great C compiler and bootloader, so you cannot brick them no matter how bone-headed your replacement firmware might become.<br /><br />The back of the badge consists of just a battery clip, but it can optionally be populated with an SSOP28 FT232RL USB to Serial adapter an a mini-USB plug. This USB port then allows for replacement firmware to be loaded, as well as a high-speed serial link to that firmware. Kits will be available containing the parts necessary for this, though you should expect them to sell out quickly.<br /><br />For the schematic, grab the full-res version of this image.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4721793596/" title="NHBadge 12 Schematic by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1044/4721793596_0124ab7908.jpg" width="478" height="500" alt="NHBadge 12 Schematic" /></a><br /><br />The layout, for the moment, is private, but you can expect it to be similar to the following cropped image of the prototype. Badges will come in Blue for attendees, Green for speakers, and Red for goons, with prototypes having a white silkscreen.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4721369041/" title="NHBadge10, Cropped by Travis Goodspeed, on Flickr"><img src="http://farm2.static.flickr.com/1129/4721369041_68c50d3a77.jpg" width="500" height="286" alt="NHBadge10, Cropped" /></a><br /><br /><h3>GoodFET Firmware</h3><br />When the badges have been flashed with the <a href="http://goodfet.sf.net/">GoodFET</a> firmware, a prebuilt radio client is available in the form of <a href="http://goodfet.sourceforge.net/clients/goodfet.nrf/">goodfet.nrf</a>. For example, running 'goodfet.nrf sniffob' will sniff the OpenBeacon protocol, while 'goodfet.nrf carrier 2479000000' will place a carrier wave at 2.479 GHz, jamming any carrier-sensing radios on that frequency.<br /><br />The full Python scripting environment of the GoodFET is available to the NRF port, so it is easy to script this usage. If you'd like to broadcast Morse code by turning the carrier on and off, you can do so without ever touching a C compiler. The same goes for frequency hopping or packet sniffing, although some architectural limitations of the NRF24L01+ make sniffing difficult without knowing the first three bytes of the destination MAC address to be sniffed.<br /><br />This code is already committed to the mainstream GoodFET repository. Here it is running on Windows XP, sniffing encrypted traffic from a Last Hope badge.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4634725972/" title="GFNRF.EXE by Travis Goodspeed, on Flickr"><img src="http://farm4.static.flickr.com/3405/4634725972_b20d2fb650_o.png" width="671" height="332" alt="GFNRF.EXE" /></a><br /><br /><h3>Radio Configuration Extraction</h3><br />The exact radio channel and addresses will be a surprise for the conference, but there's little harm in my showing you how to extract them from a running firmware image.<br /><br />Start with a virgin badge; that is, one which has not been reflashed. Solder on a USB chip and connector, then perform the following <b>without disconnecting it from power</b>. The idea here is to replace the existing MSP430 firmware, then extract the contents of the radio's RAM which is not damaged by a reflashing of the MSP430. It might help to have already tested an installation of the <a href="http://goodfet.sourceforge.net/">GoodFET</a> client, as you rebooting the host PC might cause the radio to lose its settings.<br /><br />First, reflash the badge with the goodfet firmware by running 'goodfet.bsl --fromweb' in Unix or 'gfbsl.exe -e -p goodfet.hex' in Windows. Once this is complete, you can dump the radio settings by 'goodfet.nrf info'. For a Last Hope badge which was dumped in a similar manner, the results were as follows.<pre>air-2% goodfet.nrf info<br />Encoding GFSK<br />Freq 2481 MHz<br />Rate 2000 kbps<br />PacketLen 16 bytes<br />MacLen 5 bytes<br />SMAC 0x424541434f<br />TMAC 0x0102030201<br />air-2% </pre><br /><br />You can get more detail by dumping all registers,<pre>air-2% goodfet.nrf regs<br />r[0x00]=0x000000000a // CONFIG<br />r[0x01]=0x0000000000 // EN_AA<br />r[0x02]=0x0000000001 // EN_RXADDR<br />r[0x03]=0x0000000003 // SETUP_AW<br />r[0x04]=0x0000000003 // SETUP_RET<br />r[0x05]=0x0000000051 // RF_CH<br />r[0x06]=0x000000000f // RF_SETUP<br />r[0x07]=0x000000002e // STATUS<br />r[0x08]=0x0000000000 // OBSERVE_TX<br />r[0x09]=0x0000000000 // RPD<br />r[0x0a]=0x424541434f // RX_ADDR_P0<br />r[0x0b]=0xc2c2c2c2c2 // RX_ADDR_P1<br />r[0x0c]=0x00000000c3 // RX_ADDR_P2<br />r[0x0d]=0x00000000c4 // RX_ADDR_P3<br />r[0x0e]=0x00000000c5 // RX_ADDR_P4<br />r[0x0f]=0x00000000c6 // RX_ADDR_P5<br />r[0x10]=0x0102030201 // TX_ADDR<br />r[0x11]=0x0000000010 // RX_PW_P0<br />r[0x12]=0x0000000000 // RX_PW_P1<br />r[0x13]=0x0000000000 // RX_PW_P2<br />r[0x14]=0x0000000000 // RX_PW_P3<br />r[0x15]=0x0000000000 // RX_PW_P4<br />r[0x16]=0x0000000000 // RX_PW_P5<br />r[0x17]=0x0000000011 // FIFO_STATUS<br />r[0x18]=0x0000000000 // ?<br />r[0x19]=0x0000000000 // ?<br />r[0x1a]=0x0000000000 // ?<br />r[0x1b]=0x0000000000 // DYNPD<br />r[0x1c]=0x0000000000 // ?<br />r[0x1d]=0x0000000000 // ?<br />r[0x1e]=0x0000000000 // ?<br />r[0x1f]=0x0000000000 // ?<br />air-2%</pre><br /><br />Sniffing traffic with the GoodFET firmware requires only that these same registers be loaded back into the NRF chip, and also that the MAC addresses be swapped. That is, to sniff Last Hope badge traffic, you will want RX_ADDR_P0 to be 0x0102030201 rather than 0x424541434f.<br /><br />To perform this on a badge as prepared above, simply run the following.<pre>air-2% goodfet.nrf poke 0x0a 0x0102030201<br />Poking 0a to become 0102030201.<br />Poked to 102030201<br />air-2% goodfet.nrf sniff<br />Listening as 0102030201 on 2481 MHz<br /> dd 8f 4a 5b ff 7c bb 76 09 42 a6 ec 61 6f 9a db<br /> 90 bb 2f cd 06 81 e9 36 20 9c 4c 23 b3 10 6c c7<br /> 37 7a 37 c5 93 57 2b 24 6a 9d 9a 8b 3c 52 1c 23<br /> 56 a8 04 f5 a7 ed 26 0b 24 ec 39 9d 10 fb da 76<br /> ba b5 d0 5c 89 4d 1c 63 19 28 a1 9d 35 e6 7f a5<br /> ec 63 5f 60 b8 0f 1c bf 4c e6 af 93 c2 fe 93 ee<br /> ad fc a1 25 42 81 7a a1 28 a8 f5 21 4a 7a 55 af<br /> 79 42 5c 6d 38 ca 46 ab 1b 8c ab 90 ad 47 90 d1<br /> f6 9a 22 0d e4 37 19 b7 75 34 8d 4f f9 9c fd 2a<br />^C<br />air-2% </pre><br /><br /><h3>Key Extraction</h3><br />Concerning cryptography, the badges will have it, but that oughtn't stop you from having some fun. Badges are XXTEA encrypted, with keys being published after each conference. A list of old encryption keys can be found at <a href="http://wiki.openbeacon.org/wiki/EncryptionKeys">http://wiki.openbeacon.org/wiki/EncryptionKeys</a>, with the key for the above packets being {0x9c43725e,0xad8ec2ab,0x6ebad8db,0xf29c3638}. Example decryption routines are plentiful within the OpenBeacon source repository.<br /><br />If the badges used more sophisticated radio chips, such as the SPI 802.15.4 chips, an AES128 key would be present within the radio to be read out. Since this isn't the case, the key stays within Flash or RAM of the MSP430 microcontroller.<br /><br />Flash extraction requires that an attacker gain access to memory through the serial bootstrap loader (BSL) or through JTAG. The BSL is protected by a password, one which might or might not be vulnerable to my <a href="http://events.ccc.de/congress/2008/Fahrplan/events/2839.en.html">timing attack</a>. The timing attack is impossible to perform through the FTDI chip, so a second microcontroller must be wired up to the 0.1" serial port header.<br /><br />Additionally, it might be possible to extract the contents of Flash through the JTAG port through which these chips are initially programmed. Unlike the bootloader, there is no password protection, but rather a security fuse which is blown to disable future access.<br /><br />RAM is not protected by the serial bootstrap loader, and you can extract it by first erasing the chip by 'goodfet.bsl -e', then dumping the contents of RAM to disk for later perusal. Somewhere in this mess will be a copy of the XXTEA key, unless I took the time to ensure that is not copied into RAM at startup.<br /><br /><h3>Packet Format</h3><br />Once decrypted, packets look like the following.<br /><pre> SZ PR FL ST SEQUENCENUM SOURCEIDXXX RESVD CRC16 <br /> 10 17 00 ff 00 0a 6f a7 ff ff ff ff 00 00 e7 53 <br /> 10 17 00 ff 00 0a 6f ab ff ff ff ff 00 00 b5 38 <br /> 10 17 00 aa 00 0a 6f ae ff ff ff ff 00 00 54 79 <br /> 10 17 00 ff 00 0a 6f b3 ff ff ff ff 00 00 11 ee <br /> 10 17 00 ff 00 0a 6f b7 ff ff ff ff 00 00 d0 28 <br /> 10 17 00 aa 00 0a 6f ba ff ff ff ff 00 00 a2 c4</pre><br /><br />Fields in order are Size, Protocol, Flags, Strength, Sequence, Serial Number, Reserved, and a CRC16 checksum. The 8-bit Flags field indicates the bits of a capacitive multi-touch sensor, while the Reserved field has been co-opted for a secret project of mine. The Source ID is the badge's serial number, which can be found on a sticker that is present on the badge.<br /><br />The sequence number is incremented for each packet while the last few bits of it determine the broadcast strength. In this example, the badge is rather far from the reader, so all 00 and 55 strength packets are lost, while some AA and FF packets get through. FF being stronger, more of its packets go through. Comparing packet loss rates allows the aggregation server to determine badge positions.<br /><br />The received signal strength, RSSI, of each packet is not used in this calculation because it is rather primitive in the NRF24L01+, being only a single bit wide. Competing chips, such as the CC2420, would allow this but only at a significant increase in unit cost.<br /><br /><h3>Breakouts</h3><br />To facilitate badge hacking, there are four breakout headers, all of which have standard 0.1" spacing.<br /><br />The first is a 14-pin MSP430 JTAG connector, the same used by the MSP430 FET UIF and the GoodFET.<br /><br />The second is a 6-pin BSL header, in the style of FTDI breakout boards from Sparkfun. This has not been tested, and you had damned well better only use it at 3.3 volts.<br /><br />The third is a 7-pin breakout connector for the NRF24L01+ radio and SPI bus. You might use it to add an additional SPI chip, such as a second radio or an LCD. The pins are (1) GND, (2) CE, (3) !CS, (4) SCK, (5) MOSI, (6) MISO, and (7) !IRQ. The !IRQ signal is only asserted by the NRF when configured to do so, so it might be coopted to act as a !CS pin for a second SPI device.<br /><br />The fourth and final header is an 8-pin breakout of Port 3 of the MSP430 microcontroller. By default, it is used as a capacitive touch sensor, but it might also be used for any sort of I/O expansion. In addition to GPIO, some hardware accelerated ports are available on this pins. I'll leave you to the datasheet to figure them out.<br /><br /><h3>Compatible Hardware</h3><br />The <a href="http://thisisant.com/">ANT</a> wireless protocol can be implemented with the NRF24L01+ of this badge, though technical details on exactly how to do it are rather difficult to find. I'd be much obliged if some neighbors brought ANT equipment to the conference for the rest of us to play with.<br /><br />Sparkfun offers a number of <a href="http://www.sparkfun.com/commerce/advanced_search_result.php?keywords=nrf24l01&x=0&y=0&search_section=products">NRF24L01</a> modules, my favorite of which is a <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8602">Key Fob Remote</a>.<br /><br /><h3>Stay Tuned</h3><br />These details should help you to spend more time hacking, and less time researching, during the conference. A special prize will be given for the most original badge modification, with heavy credit going toward those of high technical caliber. There are also some secrets to be found within the badges, so best to bring b<br /><br />I will be presenting this and a several more tricks as a lecture during the conference, entitled "Building and Breaking the Next Hope Badge" at 22h00 on Saturday, July 17th in the Tesla room. There will also be a panel presentation entitled "The OpenAMD Project" at 18h00 on Friday, July 16th in the Lovelace room. Both rooms are on the 18th floor.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com39tag:blogger.com,1999:blog-3638505461399232379.post-42006921905556731942010-04-26T15:13:00.010-04:002010-04-27T01:37:35.086-04:00CUDA PTX Extractionby Travis Goodspeed <travis at radiantmachines.com><br />concerning CUDA 3.x on Darwin<br />as the first of several CUDA articles.<br /><br />The following are some brief introductory notes on dumping PTX kernels from modern CUDA applications, as well as techniques for embedding them within new applications. One or two copies of every shader are stored as ASCII strings within each CUDA executable by default. With a little ingenuity, the contents of this article and a decent machine with a G80 card should provide a decent start in reverse engineering general-purpose GPU applications.<br /><br />Nvidia's CUDA framework for GPU computing uses a portable meta-assembly language, PTX (<a href="http://developer.download.nvidia.com/compute/cuda/3_0/toolkit/docs/ptx_isa_2.0.pdf">ptx_isa_2.0.pdf</a>), to facilitate translation between multiple GPU devices. In this manner, they can escape the backward compatibility issues that hold most modern CPU architectures to a single instruction set. PTX vaguely resembled the underlying machine code, but it lacks features which would tie it to any particular GPU. In this brief article, I present a trivial method for extracting PTX assembly from CUDA applications, as well as some pointers for merging that code into new applications.<br /><br /><h3>Dumping</h3><br />The screenshot below shows a fragment of <i>libcublas.dylib</i> from CUDA 3.0 in Snow Leopard being edited in Emacs. Following the dozens of assembler directives are individual VM opcodes. (This contains Basic Linear Algebra Subprograms. As this comes from Fortran, not C, the code is a bit weird.) By default, CUDA will compile inline code in a language similar to C into PTX assembly, then include the PTX assembly string verbatim into the resulting executable or library. User comments are not preserved, but compiler comments are introduced and names are unaltered. Except where hand-written, the compiler will always be nvopencc.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4555853142/" title="CUDA PTX Extraction by Travis Goodspeed, on Flickr"><img src="http://farm4.static.flickr.com/3551/4555853142_23491d9ec6_o.png" width="498" height="275" alt="CUDA PTX Extraction" /></a><br /><br />The nvopencc compiler has a number of quirks when writing PTX:<br /><ul><li>Every line that is not a label is tabbed in at least once.</li><li>The first directive is .version, the second is .target.</li><li>Registers are declared in groups.</li><li>Names are preserved, with C++ mangling.</li></ul><br />Further,<br /><ul><li>Every PTX script ends with a null (0x00) byte.</li><li>While they can be big, no PTX script is larger than two megabytes.</li><li>PTX scripts come in pairs, one for sm_20 and another for sm_10.</li></ul><br /><br />To dump the PTX code from a binary, Mach-O executable, just scan the input for long strings, printing everything starting with "\t.version". In my own setup, I have an <a href="http://pastebin.com/xuVsKBf4">ugly C program</a> that prints these, passing them off to the unix <i>split</i> command for separation into multiple PTX files.<br /><br />The 312 PTX scripts from CUBLAS are mostly small, with only nine of them having source in excess of a megabyte but none being larger than two megabytes. Thus, you'll need a rather long string buffer. Additionally, it is handy to purge the buffer when no fragment of a PTX executable is found and whenever a null byte is encountered. You can find the PTX from the vectorAdd example at <a href="http://pastebin.com/nqKqKhNc">http://pastebin.com/nqKqKhNc</a>.<br /><br />Applications can be compiled without PTX inclusion, using machine-language CUBIN files instead. This has the disadvantage of not being forward-compatible, and thanks to Wladimir J. van der Laan's <a href="http://wiki.github.com/laanwj/decuda/">Decuda</a> project, it isn't much more difficult to read.<br /><br />To try this out yourself, first build a dumping script based upon the CUDA examples and libraries. Once you have that, try downloading a few of the more advanced demos. The <a href="http://www.nvidia.com/content/graphicsplus/us/download.asp">Nvidia Graphics Plus</a> demos might be a good target, as would any game advertising CUDA support.<br /><br /><h3>PTX JIT</h3><br />Having dumped a PTX script, it is handy to link it back into an existing project. For this, you will want to use the matrixMulDynlinkJIT or ptxjit examples that come with the CUDA development kit. These projects use the <i>cuModuleLoadDataEx()</i> method to link a PTX script from a string, then <i>cuModuleGetFunction()</i> to grab a CUfunction pointer to any function.<br /><br />Conveniently, the PTX scripts include symbol names, but as with any complex compiler, these have been somewhat mangled. In the <a href="http://pastebin.com/nqKqKhNc">addVector</a> example, the entry point hask been mangled to _Z6VecAddPKfS0_Pfi for both sm_10 and sm_20. It is this function name, and not the simpler VecAdd, that must be passed to <i>cuModuleGetFunction()</i>.<br /><br />This is the code that the ptxjit example uses to load a kernel named _Z8myKernelPi kernel contained within the myPtx[] character array. Looking at the string itself, which is defined within ptxjit.h, it can be seen that the code was rather hastily dumped by a method similar to the one I describe above.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4556441221/" title="PTX JIT by Travis Goodspeed, on Flickr"><img src="http://farm4.static.flickr.com/3650/4556441221_35b7223c69_o.png" width="479" height="298" alt="PTX JIT" /></a><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4557112022/" title="myPtx from PTXJIT by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4067/4557112022_bfaa6f2397_o.png" width="287" height="170" alt="myPtx from PTXJIT" /></a><br /><br /><h3>Caveats</h3><br />GPU programming is sufficiently confusing when source code is available that the lifting of code oughtn't be a concern. Generally only small fragments are executed within the GPU, with the majority of development time being spent debugging those fragments and twisting them for different physical optimizations.<br /><br />Daniel Reynaud's talk on <a href="http://indefinitestudies.files.wordpress.com/2008/12/gpgpu_slides1.pdf">GPU Powered Malware</a> at Ruxcon 2008 proposed that GPU programs might be useful for malware URL generation. It goes without saying that sophisticated malware will do better than to include an unencoded ASCII string. Pre-assembled bytecode can be provided directly to the card, avoiding the inclusion of a PTX string. While some of Reynaud's points are less relevant now that CUDA has debugging and bytecode emulation, the core of his argument that GPU packers will become important is still valid. For starters, it is possible use a pegged memory segment to have GPU code rewrite host X86 code on the fly without a context switch!<br /><br />Expect some follow-up articles on the neighborly things that can be done once your hands are inside the beast that is CUDA.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com36tag:blogger.com,1999:blog-3638505461399232379.post-9250852755860852162010-03-24T06:39:00.002-04:002010-03-24T06:44:41.782-04:00Smartgrid SkunkworksDearest engineers and hackers, and also their management,<br /><br />Recent vulnerabilities found in smart meters and HAN devices have shown a number of weaknesses in the engineering practices used to build these devices and their constituent components. A vulnerability in a chip or library is fixed slowly, and it is a very rare event that the meter and thermostat vendors affected by the vulnerability are notified by their suppliers. Because of this, vulnerabilities are spreading downward through the supply chain, and the engineers of smart grid devices are left uninformed.<br /><br />While those utilities that actively investigate security have a considerable amount of bargaining power with their immediate suppliers, the rest of the supply chain has no similar leverage to compel security notifications. Chip and library vendors are failing to notify the meter vendors that depend upon their components. Even when the meter vendors are notified directly of vulnerabilities, thermostat and other HAN vendors can have no realistic expectation of such a privilege.<br /><br />Despite having found many vulnerabilities in microcontrollers and LPAN radio chips, I have never seen one single security issue mentioned in the errata sheets of these devices. It has been a year since I first reported to Texas Instruments that the RAM of their Chipcon 8051 core is exposed to an attacker, but there's not one scrap of documentation from the firm to its customers suggesting that they make the simple patch of moving the key variables to Flash memory. The example ZigBee stack for the chip is still vulnerable to this attack, even after recent patches! A year later, exactly two debugger commands are all that are required to extract keys from nearly every ZigBee SEP device with a Chipcon radio, and no one knows to patch their code! (Do not be smug if you are an Ember customer. The EM2xx chips are unpatchably vulnerable to debugger key extraction, and there is no mention of this in the chip's errata sheet either.)<br /><br />As chip and library vendors have failed to document the publicly known vulnerabilities in their products, and as they have often been unable or unwilling to repair them, the most expedient remedy to this problem is a separate line of communication. At least one point of reference must exist for the engineers trying to build these products.<br /><br />For these reasons, I have created a skunkworks mailing list for the announcement and discussion of smart grid vulnerabilities, particularly but not exclusively those in AMI equipment. This is to be a list for engineering discussion, by engineers and security researchers. Anonymous posts and lurking are welcome, but politics and committee items are not.<br /><br />For this reason, I especially request that those firms which care about security ask--or perhaps even require--their engineering staff to subscribe. This list is the appropriate place to post questions concerning the secure use of a particular radio chip, fragment of code, or anything else which is too low level or vendor-specific to be mentioned in standards.<br /><br />If your firm is unwilling to allow its engineers to post, please at least compel them to follow the posts of others. In saying nothing, they will still learn how to make more secure products along with all sorts of fascinating gossip about your competitors. Your firm has every right to keep its mouth shut, but keeping its ears shut is a betrayal of each and every one of your customers.<br /><br />To kickstart this mailing list, I will make it my first site of public disclosure for smart grid vulnerabilities over the coming months. The subscription link is below, and I invite you to join me in preventing smart grid vulnerabilities before they are created.<br /><br /><a href="http://groups.google.com/group/smartgrid-skunkworks">http://groups.google.com/group/smartgrid-skunkworks</a><br /><br />Thank you kindly,<br />--Travis Goodspeed<br />Belt Buckle Engineer<br />Security HobbyistTravis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com43tag:blogger.com,1999:blog-3638505461399232379.post-88837226125911639692010-03-09T21:11:00.002-05:002011-09-04T10:30:17.929-04:00IM ME GoodFET Wiring Tutorialby Travis Goodspeed <travis at radiantmachines.com>
<br />concerning the Girltech IM ME,
<br />with a million thanks to <a href="http://daveshacks.blogspot.com/">Dave</a>.
<br />
<br /><b>WARNING: Reflashing the CC1110 while batteries are low will permanently lock the chip. Either be damned sure to use fresh batteries or leave the batteries out and power the IMME from your GoodFET.</b>
<br />
<br />Howdy y'all,
<br />
<br />This brief tutorial describes the process of reflashing the <a href="http://www.girltech.com/electronics-imMe.aspx">Girltech IM ME</a> with custom firmware, so that it may be used as a development platform for the <a href="http://focus.ti.com/docs/prod/folders/print/cc1110f32.html">Chipcon CC1110</a> sub-GHz ISM System-on-Chip. I assume the reader to have an assembled <a href="http://goodfet.sourceforge.net/">GoodFET</a> with recent firmware, but other programmers may of course be substituted.
<br />
<br />You should also read Dave's <a href="http://daveshacks.blogspot.com/2010/01/im-me-hacking.html">first article</a> on IM ME hacking, as it describes his method for reprogramming the device. All the pinouts below were taken from his articles, as well as the keyboard and LCD information that he was so neighborly as to publish.
<br />
<br /><h3>Wiring</h3>
<br />First, you'll need to purchase an IM ME, which can be had for $20 USD on a few toy sites while it remains in stock. You'll also need an assembled <a href="http://goodfet.sourceforge.net/">GoodFET</a> and basic electronics tools.
<br />
<br />The testpoints used for programming the IM ME are located behind the batteries in the rear compartment of the device. Ideally, a bed of nails should be used to clip into it, but failing that, just solder on to the Debug Data (DD), Debug Clock (DC), Reset (!RST), and GND pins. Run these to the GoodFET's 14-pin header as shown below.
<br />
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4322361457/" title="Testpoints by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4041/4322361457_5279ec0d1c_m.jpg" alt="Testpoints" height="180" width="240" /></a>
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4323095748/" title="Exposed Testpoints by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2720/4323095748_a68b41993e_m.jpg" alt="Exposed Testpoints" height="180" width="240" /></a>
<br />
<br />From left to right on the IM ME, the pins are !RST, DD, DC, +2.5V, and Ground. Because the GoodFET is a low-voltage device, there's no need for the resistor dividers in Dave's article. Use <i>EITHER</i> the GoodFET <i>OR</i> the batteries for VCC, but not both.
<br /><table style="width: 180px; height: 210px;" border="1"><tbody><tr><th>Name</th><th>Pin</th><th>
<br /></th><th>Name</th></tr><tr><td>DD</td><td>1</td><td>2</td><td>Vcc</td></tr><tr><td>
<br /></td><td>3</td><td>4</td><td>Vcc</td></tr><tr><td>RST</td><td>5</td><td>6</td><td>
<br /></td></tr><tr><td>DC</td><td>7</td><td>8</td><td>
<br /></td></tr><tr><td>GND</td><td>9</td><td>10</td><td>
<br /></td></tr><tr><td>
<br /></td><td>11</td><td>12</td><td></td></tr><tr><td>
<br /></td><td>13</td><td>14</td><td>
<br /></td></tr></tbody></table>
<br />
<br /><h3>Flashing</h3>
<br />Once you have the IM ME wired up, you can check its model number and status by running `goodfet.cc status'. This will tell you that the chip is locked, so making a backup of its firmware is non-trivial. If you continue from here, the IM ME will no longer function as an instant messenger.
<br />
<br />Erase the chip by 'goodfet.cc erase' then dump an image of RAM as 'goodfet.cc dumpdata immeram.hex' to see if anything neighborly can be found inside.
<br />
<br />You now have a blank IM ME, with the LCD most likely showing the last gasping breaths of its firmware. To flash a new firmware image, just grab its ihex file and run 'goodfet.cc flash foo.hex'.
<br />
<br />I've placed a few example binaries in the repository of an operating system that I've started for the IM ME called GoodME. To flash <a href="http://daveshacks.blogspot.com/2010/01/im-me-lcd-interface-hacked.html">Dave's LCD Test</a>, run the following commands.
<br /><i>svn co https://goodfet.svn.sourceforge.net/svnroot/goodme
<br />goodfet.cc flash goodme/bins/dave-lcdtest.hex</i>
<br />
<br />For a more functional demo, try <i>bins/term-morse824mhz.hex</i>, an ugly hack of an operating system for the IM ME with a Morse code transmitter and random number generator demo. In the Radio demo, holding any of the letter buttons broadcasts on 824MHz. The PRNG demo, shown below, demonstrates the repetition of strings withing the psuedo-random number generator and counts the number of bytes between them. This is sometimes used for <a href="http://travisgoodspeed.blogspot.com/2009/12/prng-vulnerability-of-z-stack-zigbee.html">key material</a>.
<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4323097176/" title="CC RNG Test by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4063/4323097176_11d1d5a8b0_m.jpg" width="240" height="180" alt="CC RNG Test" /></a>
<br />
<br />
<br />
<br /><h3>Custom Development</h3>
<br />
<br />The <a href="http://sdcc.sourceforge.net/">SDCC</a> compiler is in the package repositories of most civilized operating systems. You might need a more recent version for the cc1110.h header, though building this compiler is a thousand times simpler than GCC. Compiling an example is as simple as <i>sdcc foo.c; packihx <foo.ihx >foo.hex</i>, which will produce a suitable Intel Hex file for flashing. The 8051 memory model makes specifying a chip model unnecessary, a handy deviation from those of us with a thousand MSP430 linking scripts.
<br />
<br />Within the GoodME repository, you'll find my bastard child of an operating system at /branches/rough/. It was used to make the term-morse824mhz.hex, and its keyboard, font, and LCD drivers are ripe for organ transplants. /trunk/ ought to someday contain a proper operating system for the device, but for now, I haven't the time to complete it.
<br />
<br />Have fun, and build something neighborly,
<br />--TravisTravis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com248tag:blogger.com,1999:blog-3638505461399232379.post-12794277952026467192010-02-21T19:12:00.022-05:002010-02-26T15:38:21.037-05:00XML of SmartRF Studio 7by Travis Goodspeed <travis at radiantmachines.com><br />concerning <a href="http://focus.ti.com/docs/toolsw/folders/print/smartrftm-studio.html">TI SmartRF Studio 7</a>.<br /><br />For those who have not personally suffered the experience, choosing radio register values is an absolute pain. In this brief article, I will demonstrate a method for extracting settings in bulk from SmartRF 7 Studio for use in other projects.<br /><br />Suppose that a program should configure a CC1110 to operate on a particular frequency, in a particular encoding, etc. The code will like the following, which is from the CC1110 examples. This will generate a carrier wave near 823 MHz, as the 2.433GHz FREQ[] value is outside of the allowed range.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4387813979/" title="Chipcon Settings by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4024/4387813979_333a64a769_o.png" width="493" height="510" alt="Chipcon Settings" /></a><br /><br />To choose a different center frequency, the engineer is expected to either find the register's definition within the datasheet or use SmartRF Studio, a screenshot of which is below. The software is a Windows application for communicating with a radio through a serial port. It also allows an engineer to load preconfigured profiles for certain types of modulation, such as IEEE 802.15.4 or SimpliciTI. Once loaded, the settings may be tweaked and loaded into a packet-sniffer firmware for debugging projects.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4342534270/" title="Chipcon Range Limits by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4046/4342534270_f1422f8014.jpg" width="500" height="239" alt="Chipcon Range Limits" /></a><br /><br />The screenshot above, from SmartRF 6, can provide a decent idea of how infuriating the software might become. For product development, the register settings are to be copied and pasted into opaque source files. It can instill the same sort of anger as an uncooperative web form, even after the old Visual Studio 6 libraries have been located to make it work under Wine.<br /><br />SmartRF 7--at Beta 0.9.1 as of this writing--is a new client under active development, one which seems to have been rewritten from scratch or at least significantly refactored. The old Win32 GUI has been replaced with QT4, making a future Linux or Mac port possible. Most importantly of all, however, is that the default configurations, as well as register explanations, are stored as XML.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4387852455/" title="SmartRF 7 by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4010/4387852455_2250576d18.jpg" width="500" height="341" alt="SmartRF 7" /></a><br /><br />The screenshot above shows how default configurations are chosen for the target radio. Users can select an example, then change any of the settings they like. These configurations are further abstracted into an "Easy Mode" which hides all the messy minutia of radio, abstracting use to standards and channel numbers.<br /><br />These configuration settings are to be found as XML in the <i>config/xml/</i> directory, organized by chip and presentation. The following is an example of one such configuration file for the CC1110.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4387864423/" title="SmartRF 7 XML by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4064/4387864423_4c6eea664e_o.png" width="463" height="407" alt="SmartRF 7 XML" /></a><br /><br />Patching these configurations allows for the easy addition of new standards. For example, I added support for my Tennessee Belt Buckle radio by adding a new stanza to <i>easymode_settings.xml</i>.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4388633156/" title="SmartRF Belt Buckle by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2713/4388633156_b3aae46c25_o.png" width="222" height="185" alt="SmartRF Belt Buckle" /></a><br /><br />The register definitions and their bitfields are also defined in XML. The following from <i>register_definition.xml</i> for the CC1110 described the FREQ2 register's meaning.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4388651918/" title="SmartRF 7 XML Register Def by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4059/4388651918_fc7439e990_o.png" width="550" height="335" alt="SmartRF 7 XML Register Def" /></a><br /><br />Printing SDCC special-function register definitions, such as those found in <i>cc1110.h</i>, is as easy as a bit of Python magic,<br /><pre><br /><font color="#444444">#!/usr/bin/python</font><br /><br /><font color="#444444"># Simple script for dumping Chipcon register definitions to SDCC header.</font><br /><font color="#444444"># Only intended as a rough example.</font><br /><font color="#444444"># by Travis Goodspeed, Engineer of Superior Belt Buckles</font><br /><br /><strong>import</strong> <font color="#2040a0">xml</font>.<font color="#2040a0">dom</font>.<font color="#2040a0">minidom</font><br /><font color="#2040a0">def</font> <font color="#2040a0">get_dom</font><font color="4444FF">(</font><font color="#2040a0">chip</font><font color="4444FF">=</font><font color="#008000">"cc1110"</font>,<font color="#2040a0">doc</font><font color="4444FF">=</font><font color="#008000">"register_definition.xml"</font><font color="4444FF">)</font><font color="4444FF">:</font><br /> <font color="#2040a0">fn</font><font color="4444FF">=</font><font color="#008000">"/opt/smartrf7/config/xml/%s/%s"</font> <font color="4444FF">%</font> <font color="4444FF">(</font><font color="#2040a0">chip</font>,<font color="#2040a0">doc</font><font color="4444FF">)</font><font color="4444FF">;</font><br /> <strong>return</strong> <font color="#2040a0">xml</font>.<font color="#2040a0">dom</font>.<font color="#2040a0">minidom</font>.<font color="#2040a0">parse</font><font color="4444FF">(</font><font color="#2040a0">fn</font><font color="4444FF">)</font><br /><br /><font color="#2040a0">dom</font><font color="4444FF">=</font><font color="#2040a0">get_dom</font><font color="4444FF">(</font><font color="4444FF">)</font><font color="4444FF">;</font><br /><br /><strong>for</strong> <font color="#2040a0">e</font> <strong>in</strong> <font color="#2040a0">dom</font>.<font color="#2040a0">getElementsByTagName</font><font color="4444FF">(</font><font color="#008000">"registerdefinition"</font><font color="4444FF">)</font><font color="4444FF">:</font><br /> <strong>for</strong> <font color="#2040a0">f</font> <strong>in</strong> <font color="#2040a0">e</font>.<font color="#2040a0">childNodes</font><font color="4444FF">:</font><br /> <strong>if</strong> <font color="#2040a0">f</font>.<font color="#2040a0">localName</font><font color="4444FF">=</font><font color="4444FF">=</font><font color="#008000">"DeviceName"</font><font color="4444FF">:</font><br /> <strong>print</strong> <font color="#008000">"// %s=%s"</font> <font color="4444FF">%</font> <font color="4444FF">(</font><font color="#2040a0">f</font>.<font color="#2040a0">localName</font>,<font color="#2040a0">f</font>.<font color="#2040a0">childNodes</font><font color="4444FF">[</font><font color="#FF0000">0</font><font color="4444FF">]</font>.<font color="#2040a0">nodeValue</font><font color="4444FF">)</font><font color="4444FF">;</font><br /> <strong>elif</strong> <font color="#2040a0">f</font>.<font color="#2040a0">localName</font><font color="4444FF">=</font><font color="4444FF">=</font><font color="#008000">"Register"</font><font color="4444FF">:</font><br /> <font color="#2040a0">name</font><font color="4444FF">=</font><font color="#008000">"unknownreg"</font><font color="4444FF">;</font><br /> <font color="#2040a0">address</font><font color="4444FF">=</font><font color="#008000">"0xdead"</font><font color="4444FF">;</font><br /> <font color="#2040a0">description</font><font color="4444FF">=</font><font color="#008000">""</font><font color="4444FF">;</font><br /> <strong>for</strong> <font color="#2040a0">g</font> <strong>in</strong> <font color="#2040a0">f</font>.<font color="#2040a0">childNodes</font><font color="4444FF">:</font><br /> <strong>if</strong> <font color="#2040a0">g</font>.<font color="#2040a0">localName</font><font color="4444FF">=</font><font color="4444FF">=</font><font color="#008000">"Name"</font><font color="4444FF">:</font><br /> <font color="#2040a0">name</font><font color="4444FF">=</font><font color="#2040a0">g</font>.<font color="#2040a0">childNodes</font><font color="4444FF">[</font><font color="#FF0000">0</font><font color="4444FF">]</font>.<font color="#2040a0">nodeValue</font><font color="4444FF">;</font><br /> <strong>elif</strong> <font color="#2040a0">g</font>.<font color="#2040a0">localName</font><font color="4444FF">=</font><font color="4444FF">=</font><font color="#008000">"Address"</font><font color="4444FF">:</font><br /> <font color="#2040a0">address</font><font color="4444FF">=</font><font color="#2040a0">g</font>.<font color="#2040a0">childNodes</font><font color="4444FF">[</font><font color="#FF0000">0</font><font color="4444FF">]</font>.<font color="#2040a0">nodeValue</font><font color="4444FF">;</font><br /> <strong>elif</strong> <font color="#2040a0">g</font>.<font color="#2040a0">localName</font><font color="4444FF">=</font><font color="4444FF">=</font><font color="#008000">"Description"</font><font color="4444FF">:</font><br /> <strong>if</strong> <font color="#2040a0">g</font>.<font color="#2040a0">childNodes</font><font color="4444FF">:</font><br /> <font color="#2040a0">description</font><font color="4444FF">=</font><font color="#2040a0">g</font>.<font color="#2040a0">childNodes</font><font color="4444FF">[</font><font color="#FF0000">0</font><font color="4444FF">]</font>.<font color="#2040a0">nodeValue</font><font color="4444FF">;</font><br /> <strong>print</strong> <font color="#008000">"SFRX(%10s, %s); /* %50s */"</font> <font color="4444FF">%</font> <font color="4444FF">(</font><font color="#2040a0">name</font>,<font color="#2040a0">address</font>, <font color="#2040a0">description</font><font color="4444FF">)</font><font color="4444FF">;</font><br /></pre><br /><br />These configuration files should allow for new Chipcon radio applications and development tools to be written in short order. Please contact me if you would be so kind as to write a complete Python class for querying this data.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com100tag:blogger.com,1999:blog-3638505461399232379.post-55135933628231512902010-02-05T05:35:00.004-05:002010-02-05T05:46:32.098-05:00Call for Info Flashby Travis Goodspeed <travis at radiantmachines.com><br />continuing a discussion of <a href="http://travisgoodspeed.blogspot.com/2009/10/msp430-info-flash.html">MSP430 Info Flash</a><br /><br />Neighborly MSP430 developers, please do me a favor and email me the contents of memory from 0x1000 to 0x1100 of every MSP430F2xx device that you can. I'm trying to reverse engineer the exact distributions of the CALBC1_16MHZ and CALDCO_16MHZ values in order to build a UART library that operates without Info Flash. The <a href="http://goodfet.sourceforge.net/">GoodFET</a> does this well enough, but I still get the occasional bug report when a device is slightly out of range. I can reduce the default to baud rate or try similar tricks to get around this, but I want to know exactly which values are safe.<br /><br />If your GoodFET can be programmed by goodfet.bsl but does not respond after programming, try the info flash images available in /contrib/infos/ to see if any of them work.<br /><pre>air% goodfet.bsl -e -p 2618-002.txt;\<br />goodfet.bsl -p ../../trunk/firmware/goodfet.hex <br />MSP430 Bootstrap Loader Version: 1.39-goodfet-8<br />Mass Erase...<br />Transmit default password ...<br />Invoking BSL...<br />Transmit default password ...<br />Current bootstrap loader version: 2.13 (Device ID: f26f)<br />Program ...<br />256 bytes programmed.<br />MSP430 Bootstrap Loader Version: 1.39-goodfet-8<br />Invoking BSL...<br />Transmit default password ...<br />Current bootstrap loader version: 2.13 (Device ID: f26f)<br />Program ...<br />10596 bytes programmed.<br />air% goodfet.monitor peek 1000 100A<br />1000 55aa<br />1002 3fff<br />1004 abcd<br />1006 55aa<br />1008 1234<br />air%</pre><br /><br />Previously programmed GoodFETs have info flash wiped during programming, but if yours has never been programmed, you can dump the info with<br /><pre>goodfet.bsl --dumpinfo >info.txt</pre>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com24tag:blogger.com,1999:blog-3638505461399232379.post-8742430808208778352010-01-25T14:00:00.001-05:002010-01-25T14:35:14.501-05:00ZStack PRNG Fixedby Travis Goodspeed <travis at radiantmachines.com><br />concerning versions 2.2.2 and 2.3.0 of TI <a href="http://focus.ti.com/docs/toolsw/folders/print/z-stack.html">Z-Stack</a><br />and a fix of the <a href="http://travisgoodspeed.blogspot.com/2009/12/prng-vulnerability-of-z-stack-zigbee.html">ZigBee Smart Energy Profile ECC vulnerability</a>.<br /><br />Texas Instruments has released version 2.3.0 of <a href="http://focus.ti.com/docs/toolsw/folders/print/z-stack.html">Z-Stack</a>, their ZigBee stack for the TI/Chipcon CC2530, MSP430, and CC430 chips. The new version adds a variety of new features, but chief among them is a fix to the random number generator which used to be utterly insufficient for cryptographic use. Technical details on the vulnerability were first revealed publicly in <a href="http://travisgoodspeed.blogspot.com/2009/12/prng-vulnerability-of-z-stack-zigbee.html">my last article</a>. (Nate Lawson's translation is <a href="http://rdist.root.org/2010/01/11/smart-meter-crypto-flaw-worse-than-thought/">here</a>.)<br /><br />Source code for the new generator is not included, but rather references as a Security Service Provider (SSP). Since 2.2.3, they have extended the SSP API to include <i>SSP_GetTrueRandAES()</i> for generating random numbers by an AES key.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4293077271/" title="ZStack 2.3.0-1.40 TrueRand Functions by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2726/4293077271_4bf43a34ff_o.png" width="447" height="145" alt="ZStack 2.3.0-1.40 TrueRand Functions" /></a><br /><br />This is then called in <i>zclGeneral_KeyEstablishment_GetRandom()</i>, which in previous versions used the 16-bit LFSR.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4291169557/" title="ZStack 2.3.0-1.4.0 by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2750/4291169557_f2e0a4189a_o.png" width="642" height="401" alt="ZStack 2.3.0-1.4.0" /></a><br /><br />Authors of firmware for ZigBee Smart Energy devices that have used this code should patch their source code and issue firmware upgrades as quickly as possible. Those with independent crypto implementations should check to ensure that they have not made similar mistakes. Programmers should also note that <br /><br />Electric utilities with equipment using the MSP430 or Chipcon CC2530 should contact their vendors for such updates. Unlike Windows and Linux, there's no easy way to perform an upgrade of a fragment of microcontroller firmware to which you haven't got the source.<br /><br />This fix only applies to the remote recovery of keys by PRNG attacks; local key extraction is still possible by the methods that I outlined in <a href="http://travisgoodspeed.blogspot.com/2009/08/extracting-keys-from-soc-zigbee-chips.html">Extracting Keys from Second Generation ZigBee Chips</a>.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com19tag:blogger.com,1999:blog-3638505461399232379.post-26668489848160653302010-01-09T10:32:00.001-05:002010-01-14T10:07:01.519-05:00PRNG Vulnerability of Z-Stack ZigBee SEP ECCby Travis Goodspeed <travis at radiantmachines.com><br />with neighborly thanks to Nick DePetrillo,<br />concerning version 2.2.2-1.30 of TI <a href="http://focus.ti.com/docs/toolsw/folders/print/z-stack.html">Z-Stack</a><br />and a ZigBee Smart Energy Profile ECC vulnerability.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4142923916/" title="Not Quite Random by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2544/4142923916_92b6bcd62d_o.png" width="425" height="87" alt="Not Quite Random" /></a><br /><br />In past articles, I've presented a variety of local attacks against microcontrollers and ZigBee radios. While I maintain that local vulnerabilities are still very relevant to ZigBee devices, this article presents a remotely exploitable vulnerability in the way that random keys are generated by TI's Z-Stack ZCL implementation of the ZigBee Cluster Library. Randomly generated numbers--those fed into the Certicom ECC crypto library--are predictable, repeated in one of two 32kB cycles. Details follow, with links to source code and a complete list of random numbers.<br /><br /><h3>Dumping Random Bytes</h3><br />I dumped byte sequences from the CC2430 using the <a href="http://goodfet.sourceforge.net/">GoodFET</a> to debug a live chip. The chip runs a program which populates IRAM with PRNG bytes, then halts with a soft breakpoint (Opcode 0xA5) for the debugger to grab all sampled values. The main loop looks something like this:<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4209687695/" title="Chipcon RNG Dumper by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2751/4209687695_b1e24c2042_o.png" width="321" height="428" alt="Chipcon RNG Dumper" /></a><br />The firmware was compiled with the Small Device C Compiler, flashed by the GoodFET. A quick Python script then used the GoodFET library to debug the target, dumping random values through the same interface that programmed the chip.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4210466906/" title="Chipcon Byte Dumper by Travis Goodspeed, on Flickr"><img src="http://farm5.static.flickr.com/4007/4210466906_1b7c7f7450_o.png" width="390" height="284" alt="Chipcon Byte Dumper" /></a><br /><br /><h3>Short PRNG Period</h3><br />Page 18 of the <a href="/Users/travis/svn/doodles/chipcon/cc2530.pdf">CC2530 Datasheet</a> describes the random number generator peripheral, which is shared by all other 8051-based ZigBee SoC devices in the series.<br /><i>The <b>random-number generator</b> uses a 16-bit LFSR to generate pseudorandom numbers, which can be read by the CPU or used directly by the command strobe processor. The random numbers can, e.g., be used to generate random keys used for security. </i><br /><br />The state of this RNG is initialized in the hardware abstraction library by feeding 32 bytes from the ADCTSTH special function register into RNDH register. Bytes read from ADCTSTH are physically random, but poorly distributed. RNDH and RNDL are the High and Low bytes of a 16-bit CRC Linear Feedback Shift Register, the state of which can be advanced by writing to RNDH or overwritten by writing to RNDL. In between reading or writing from RND, the state is advanced by setting the fourth bit of ADCCON1. Detailed descriptions of these registers can also be found within the datasheet.<br /><br />CC2430 examples randomize the seed by mixing 32 values into the RNG,<br /><pre>for(i=0;i<32;i++){<br /> RNDH=ADCTSTH;<br /> ADCCON1|=0x04;<br />}</pre><br />Because these numbers are not evenly distributed, Z-Stack prefers to sample just the least significant bit of the RF random number generator sixteen times, then write them in directly as the state without mixing them. Further, it checks to ensure that the state is not a dead-end, substituting another if it is. This method is also advocated within the CC2530 programming guides.<br /><pre>for(i=0; i<16; i++)<br /> rndSeed = (rndSeed << 1) | (RFRND & 0x01);<br />if (rndSeed == 0x0000 || rndSeed == 0x0380)<br /> rndSeed = 0xBABE;<br />RNDL = rndSeed & 0xFF;<br />RNDL = rndSeed >> 8;</pre><br /><br />Once the RNG has been seeded, it has an initially random 16-bit state. From then on, however, it produces random bytes in a predictable sequence. Only the starting point is random, as ADCTSTH is never used for future reseeding. As shown in the screenshot above, if the sequence "7c e1 e8 4e f4 87" is observed, the probability of the next bytes being "62 49 56 fe 80 00 60" is 100 percent. Further, because the domain is so small, it can be exhaustively searched for keys in little time.<br /><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4142923916/" title="Not Quite Random by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2544/4142923916_92b6bcd62d_o.png" width="425" height="87" alt="Not Quite Random" /></a><br /><br />Code for dumping these values through the <a href="http://goodfet.sourceforge.net/">GoodFET</a> debugger can be found by svn, along with a complete dump of the PRNG sequence.<br />svn co https://goodfet.svn.sourceforge.net/svnroot/goodfet/contrib/ccrandtest<br /><br /><h3>Seed Values</h3><br /><a href="http://www.flickr.com/photos/travisgoodspeed/4142689541/" title="Seed Histogram by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2731/4142689541_7a3ef5c14f.jpg" width="500" height="383" alt="Seed Histogram" /></a><br /><br />The plot above shows the histogram of radio ADCTSTL values used to seed the PRNG. These are far from random, but when sampled slowly enough, their least significant bit is probably good enough for key generation. There are, however, two things of interest with this.<br /><br />First, if the crypto library is used infrequently, it would make sense to use this source of entropy instead of the inadequately random PRNG output. There would be a cost in power consumption, as ADCTSTL is only random while the radio is operating, but the resulting increase to security is necessary.<br /><br />Second, if the peaks on the histogram come from a measurement of the radio, it might be possible to generate a radio signal that forces even the least significant bit to be a predictable value. Steps such as AES whitening should be taken to avoid such an attack.<br /><br /><h3>ZigBee SEP, ECC</h3><br />A less than perfect random number generator is not much of an issue when symmetric keys are pre-shared, but because pre-shared keys are vulnerable to local attacks, the <a href="http://www.zigbee.org/Markets/ZigBeeSmartEnergy/tabid/224/Default.aspx">ZigBee Smart Energy</a> profile recommends the use of session keys signed by elliptic curve cryptography. See the USAF paper <a href="http://portal.acm.org/citation.cfm?id=1359033">Cryptanalysis of an elliptic curve cryptosystem for wireless sensor networks</a> for a prior break of ECC with a poor RNG.<br /><br />As will be shown in the next section, Chipcon's ZStack makes use of poorly random PRNG data as key material, allowing for a key domain of only 16 bits. This is small enough to be exhaustively searched, either by a PC or by a "Chinese Lottery" of previously compromised wireless sensors.<br /><br /><h3>ZStack Usage</h3><br /><a href="http://focus.ti.com/docs/toolsw/folders/print/z-stack.html">ZStack</a> 2.2.2-1.30 for the CC2530 makes use of the PRNG to implement the Smart Energy Profile's asymmetric cryptography. The Windows installer works perfectly under Wine, leaving ZStack installed to an awkward directory. I symlink it to /opt/zstack for convenience.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4155768502/" title="CC2530 in Wine by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2715/4155768502_76f42fa07c.jpg" width="500" height="375" alt="CC2530 in Wine" /></a><br /><br />Once installed, the following Functions are of interest.<br /><br /><b>mac_mcu.c</b> contains <i>macMcuRandomByte()</i> and <i>macMcuRandomWord()</i>. As the two are largely the same, take the former for an example. First the PRNG is clocked, then the high byte is sampled.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4236266158/" title="ZStack macMcuRandomByte() by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2699/4236266158_54a2522561_o.png" width="376" height="127" alt="ZStack macMcuRandomByte()" /></a><br /><br /><b>zcl_key_establish.c</b> is used to generate keys by the ZigBee Cluster Library specification, available for free by form from <a href="http://www.zigbee.org/ZigBeeClusterLibrary/tabid/314/Default.aspx">ZigBee.org</a>. The code fragment below takes the low bytes of <i>macMcuRandomWord()</i>, redefined as <i>osal_rand()</i>, to populate a session key before signature.<br /><a href="http://www.flickr.com/photos/travisgoodspeed/4235520885/" title="ZCL KeyEstablishment GetRandom by Travis Goodspeed, on Flickr"><img src="http://farm3.static.flickr.com/2758/4235520885_7aa48dfbd4_o.png" width="545" height="208" alt="ZCL KeyEstablishment GetRandom" /></a><br /><br />The ultimate function for ECC key generation is <i>ZSE_ECCGenerateKey()</i>, which is defined in <b>eccapi.h</b> but whose source is missing. Reading <b>ecc.r51</b> yields a few filenames as part of stored compiler warnings. The developer's filename was "C:\SVN-ZStack-2.2.0\Components\stack\sec\eccapi.c", but it is only a stand-in for the Certicom <a href="http://www.certicom.com/zigbee/zigbee.php">Security Builder MCE</a> library that is not shipped with the development kit. In any case, the vulnerability here lies in ZStack and not in Security Builder.<br /><br /><h3>Conclusions</h3><br />This article has shown that the Chipcon ZStack library, as of version 2.2.2-1.30 for CC2530, uses an insufficiently random PRNG for cryptographic signatures and session keys. PRNG data repeat every 32,767 samples, and there are at most 16 bits of entropy in any key. Searching the entire key space ought to be possible in very little time. Contrary to the CC2530's documentation, these random numbers must <b>not</b> be used to generate random keys used for security. <br /><br />All users of this library, particularly those using it for Smart Grid devices and other industrial applications, are recommended to re-implement <i>macMcuRandomWord()</i> and to ensure that nothing requiring cryptographic security operates from the PRNG alone. Users of other libraries for the Chipcon devices should ensure that those libraries are not using the PRNG data.<br /><br />Competing devices and libraries should also be checked for similar vulnerabilities, as well as commercial products such as Smart Meters that might have forked the ZStack code or followed the datasheet's recommendation of using the PRNG for key generation.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com47tag:blogger.com,1999:blog-3638505461399232379.post-614200476464758282009-11-02T08:00:00.000-05:002009-11-02T08:02:58.441-05:00S4 PaperHowdy Y'all,<br /><br />A paper of mine from S4/Miami, <a href="http://digitalbond.com/s4papers/2009/enernex/low-level-design-vulnerabilities-in-wireless-control-systems-hardware/">Low-Level Design Vulnerabilties in Wireless Control Systems Hardware</a>, has recently been made publicly available by Digital Bond. Coauthored with Brad Singletary and Darren Highfill, it provides a detailed survey of vulnerabilities that might be found in the hardware and firmware of AMI Smart Meters and similar equipment.<br /><br />Please note that the paper, written late last year, is now outdated in two respects. First, the self-propagating worm presented hypothetically in Section 3.1 is no longer hypothetical. Mike Davis has <a href="http://www.blackhat.com/presentations/bh-usa-09/MDAVIS/BHUSA09-Davis-AMI-SLIDES.pdf">written one</a>. Second, the System-on-Chip Zigbee devices advocated in the conclusion of Section 4.1 are not secure, as I have since demonstrated in <a href="http://www.blackhat.com/presentations/bh-usa-09/GOODSPEED/BHUSA09-Goodspeed-ZigbeeChips-PAPER.pdf">Extracting Keys from Second Generation Zigbee Chips</a>.<br /><br />--Travis Goodspeed<br /><travis at radiantmachines.com>Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com37tag:blogger.com,1999:blog-3638505461399232379.post-88708951141866749752009-10-28T21:37:00.004-04:002009-11-11T10:27:15.196-05:00MSP430 Info Flashby Travis Goodspeed <travis at radiantmachines.com><br /><br />The following is a description of the MSP430F2xx Info Flash, as well as my ugly--yet reliable--hack for initializing the DCO of MSP430F2xx chips after my use of the Serial Bootstrap Loader (BSL) has destroyed the contents of that flash on the GoodFET. This ought to be of use to anyone who wishes to make an MSP430 design without a crystal, as well as for anyone who has accidentally erased info flash.<br /><br />The mask-ROM bootstrap loader, BSL, of the MSP430 chips is damned handy, despite some <a href="http://frob.us/slides/goodspeed_25c3_bslc.pdf">security concerns</a>. It allows you to very quickly program a chip by the same USB/serial converter that you use to interface it with a computer, without any of the hassles of having to flash a bootloader onto the chip. In this article, I describe the way in which the MSP430F2xx flash can be accidentally corrupted by the bootloader, as well as a method for repairing that damage by backing up the info flash while the password is left as the default.<br /><br />The MSP430F2xx family has another dandy feature, that clock configuration values need not be calibrated to an external clock, such as the 32KHz crystal of the older <a href="http://goodfet.sourceforget.net/">GoodFET</a> models. Instead, configuration data is calculated at the factory and placed into info1 flash, a region of 256 bytes at 0x1000. Using this, code that would be rather complicated can become trivially simple.<br /><br />The code that configures the clock is configured on the GoodFET with MSP430F1xx chips is too complicated for me to include here. By contrast, on the MSP430F2xx chips, it becomes just<br /><pre>void msp430_init_dco() {<br /> BCSCTL1 = CALBC1_16MHZ;<br /> DCOCTL = CALDCO_16MHZ;<br />}</pre><br /><br />The security model of the BSL is a bit confusing. Upon connecting, you are required to present a password before reading, writing, or doing anything else that might affect the security of the device. You are, however, allowed to erase all of flash memory--including the info flash--to 0xFFFF. As this is traditionally the first command that you send upon connecting to a device, you will wipe all of the configuration data of a chip in programming it. Finding this problem is hellish, because the exact same code will work if programmed by JTAG and you quite often have not got JTAG handly if you intend to program everything by the BSL.<br /><br />As part of the GoodFET project, I've forked TinyOS's tos-bsl client to add support for the MSP430F2xx. I've also implemented a "--dumpinfo" command for dumping info flash to a TI Text file. This file can be reflashed after the chip has been erased to restore its factory settings.<br /><br /><pre>petite% goodfet.bsl --dumpinfo <br />MSP430 Bootstrap Loader Version: 1.39-goodfet-8<br />Use -h for help<br />Transmit default password ...<br />@1000<br />aa 55 ff 3f cd ab aa 55 34 12 ff ff aa 55<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff ff ff b4 85 fe 16<br />ff ff ff ff ff ff ff ff ff ff ff ff ff ff<br />ff ff ff ff ff ff ff ff 08 10 00 80 01 00<br />62 7f b2 0b e8 0d 98 7f 01 07 56 08 fe 08<br />ff ff ff ff ff ff ff ff 01 08 7f 8f 85 8e<br />74 8d c2 86 <br />q<br /><br />petite%</pre><br /><br />This output is in the TI Text format, which is easily converted to Intel-hex, but is a hell of a lot easier to write. Piping it into a file allows me to restore the contents of flash after erasure, and also to extract the configuration values which are used on this chip. Because the chips are similar physically, it turns out that the calibration values for one are often sufficient to program another. So by observing the model number (in big endian at 0x0FF0), I can guess in the absence of calibration values.<br /><br /><pre><br />//! Initialize the MSP430 clock.<br />void msp430_init_dco() {<br /> if(CALBC1_16MHZ!=0xFF){<br /> //Clear DCL for BCL12<br /> DCOCTL = 0x00;<br /> //Info is intact, use it.<br /> BCSCTL1 = CALBC1_16MHZ;<br /> DCOCTL = CALDCO_16MHZ;<br /> }else{<br /> //Info is missing, guess at a good value.<br /> BCSCTL1 = 0x8f; //CALBC1_16MHZ at 0x10f9<br /> DCOCTL = 0x7f; //CALDCO_16MHZ at 0x10f8<br /> }<br />}</pre><br /><br />When I find the time, I intend to test a large quantity MSP430 chips to determine the exact tolerances of manufacturing, the variances of CALBC1_16MHZ and CALDCO_16MHZ, and the probability that a given unit will so drastically differ from these values that serial communications become impossible. For now, I've found that the hardwired values above seem to work for all recently acquired MSP430F2274, MSP430F2254, and MSP430F2618 microcontrollers when using the hardware UART at 115,200 bits per second. Further, the GoodFET firmware does not require a crystal when running on these chips.Travis Goodspeedhttp://www.blogger.com/profile/09826896758948270949noreply@blogger.com27