tag:blogger.com,1999:blog-40564370030225679272024-02-19T08:51:55.789-08:00ICE9 BlogResearch and development blog. <a href="https://ice9.us/">Visit ICE9 Consulting</a>.Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-4056437003022567927.post-68824524045239321592022-08-24T08:53:00.002-07:002022-08-24T08:53:47.454-07:00Reversing the Pokit Meter's Bluetooth Protocol<p>Travis Goodspeed went to Twitter recently looking for a good BLE voltmeter for some vehicles.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPmgru4Op65yqqMoMhbzPXUmweRczP2GWJAcHjfjTcJOABBSFTEKqRm-rHR8JtV5jsIFAbJH5PfCwC_Kne8I09nC8CWHN23-mY2RWkWNuXwvYKxQDzSn_BmJc1Y8uPdjP-ay3taiPjGE9_NWTYN1VIdpDkXCFbcz5puOuCNiL8hmZiCsYmBivbERxP/s1126/Screen%20Shot%202022-08-13%20at%2019.34.30.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="622" data-original-width="1126" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPmgru4Op65yqqMoMhbzPXUmweRczP2GWJAcHjfjTcJOABBSFTEKqRm-rHR8JtV5jsIFAbJH5PfCwC_Kne8I09nC8CWHN23-mY2RWkWNuXwvYKxQDzSn_BmJc1Y8uPdjP-ay3taiPjGE9_NWTYN1VIdpDkXCFbcz5puOuCNiL8hmZiCsYmBivbERxP/w400-h221/Screen%20Shot%202022-08-13%20at%2019.34.30.png" width="400" /></a></div>
<p>Pokit Meter quickly came up as a possible solution. For around $100 it has all the features you'd expect out of a basic multimeter: voltage, current, resistance, continuity, diode check, and even temperature. The only caveat is that the app is apparently not that good.</p><p>Reversing BLE devices like this is the exact sort of thing we specialize in at <a href="https://ice9.us/">ICE9</a>, so I thought I'd volunteer my services to take a look at the protocol and see how complex it is. For an overview of the process, see my talk <a href="https://media.hardwear.io/bluetooth-hacking-tools-and-techniques-mike-ryan/" target="_blank">Bluetooth Hacking: Tools and Techniques</a> from Hardwear.io 2019.</p><p>My usual approach with a device like this that is mainly operated from an app is to install that app on an Android test device and log the Bluetooth communications. This proved to be extremely effective with Pokit. I began by measuring the voltage of a battery and noting the values on the screen. I then tested other functions, always noting what I did and what values were displayed on the screen. Finally, I transferred the log file to my laptop and opened it in Wireshark.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuFrJmwpOvurcpDdwRs39GS8pgzqyOLoC4rN-NSt3zsbnlwJqKvzzd3dmn8nDA8haVxO9T2rUyL-HIz44HmgDuZeqxwbXfLwxyckAjWyuNdu4DTF3oYTivaPPyEum0_edeKsjNrjgJN6CWj6Fa_5z3no2UMpnFuTGqzA5CyFtsasOtAlAwuXsz2r5x/s2310/wireshark.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1504" data-original-width="2310" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuFrJmwpOvurcpDdwRs39GS8pgzqyOLoC4rN-NSt3zsbnlwJqKvzzd3dmn8nDA8haVxO9T2rUyL-HIz44HmgDuZeqxwbXfLwxyckAjWyuNdu4DTF3oYTivaPPyEum0_edeKsjNrjgJN6CWj6Fa_5z3no2UMpnFuTGqzA5CyFtsasOtAlAwuXsz2r5x/w493-h320/wireshark.png" width="493" /></a></div><p>Immediately it became evident that this device uses a very simple command-response protocol. No pairing or encryption are used. On boot, the app subscribes to notifications on a number of characteristics. It then sends a command to put the device into the user-requested mode. Measurements come as notifications from a specific characteristic. From here it was just a matter of comparing the log file to my notes to align which commands referred to which modes and which notifications referred to which measurements.</p><p>I observed all commands as write requests on characteristic <tt>0x2f</tt> with UUID <tt>53dc9a7a-bc19-4280-b76b-002d0e23b078</tt> and responses were handle value notifications on chracteristic <tt>0x31</tt> with UUID <tt>047d3559-8bee-423a-b229-4417fa603b90</tt>. Here is a list of commands I was able to figure out from interacting with the app:</p><p></p><ul><li><tt>00 ff f4 01 00 00</tt> - disable</li><li><tt>01 ff f4 01 00 00</tt> - voltage DC</li><li><tt>02 ff f4 01 00 00</tt> - voltage AC</li><li><tt>03 ff f4 01 00 00</tt> - current DC</li><li><tt>04 ff f4 01 00 00</tt> - current AC</li><li><tt>05 ff f4 01 00 00</tt> - resistance</li><li><tt>06 00 f4 01 00 00</tt> - diode check</li><li><tt>07 00 96 00 00 00</tt> - continuity</li><li><tt>08 00 d0 07 00 00</tt> - temperature</li></ul><p></p><p>I don't know the meaning of the five bytes following the command number. It's possible they may be range related arguments, but there does not appear to be a way to manually specify ranges from the app and I have never observed values other than those above.</p><p>The responses for all modes all come in a similar form. Some examples follow, but they clearly are a single byte flag followed by a 32-bit value followed by some more gibberish. The 32-bit value left me stumped for a bit. It was clearly little endian and roughly correlated with the values I had observed, but not exactly. Finally it dawned on me to treat it as a 32-bit float, and there were my measurements, exactly as I recorded from the app.</p><p></p><ul><li><tt>01 67 b4 cf 3f 01 01</tt> - voltage of <tt>0x3fcfb467</tt>: 1.6v</li><li><tt>00 00 00 80 7f 07 00</tt> - no continuity, positive infinity</li><li><tt>01 b5 18 93 41 07 00</tt> - some continuity (see flag), resistance of 18.4Ω</li><li><tt>00 47 35 fe 41 08 00</tt> - temperature measurement of 31.8°C / 89.2°F (it's hot where I did this work!)</li></ul><p>That's about all the info you need to communicate with the device. For Mr. Goodspeed's application, leaving a Pokit connected to each vehicle battery and connecting to them once a day (or as often as needed), putting them into voltage DC mode, taking one measurement, and disconnecting solves the problem.</p><p>For myself, I think I'll be keeping it as a useful tool in my bag and a handy temperature logger.</p><p>I hope this information aids people who are trying to replicate the functionality of the app! As always, if you have any Bluetooth or embedded development or security needs, feel free to <a href="mailto:info@ice9.us">reach out to us</a>.</p><p>P.S., oscilloscope functions quite a bit differently from the modes listed above, and due to time constraints I did not look into it. Following the process I described above would be a great project for someone looking to get into reverse engineering BLE devices!</p><p>P.P.S., I was also able to observe a firmware update from version 1.4 to version 1.6. Extracting the blob from the btsnoop file is quite straightforward. It appears to be encrypted, compressed, or both, and I will not be posting it here.</p>Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com0tag:blogger.com,1999:blog-4056437003022567927.post-17992508140869063792018-12-04T22:28:00.000-08:002018-12-05T19:47:23.695-08:00Uberducky - a wireless USB Rubber Ducky triggered via BLEI'm excited to announce a new tool: <a href="https://github.com/mikeryan/uberducky">Uberducky</a>, a wireless <a href="https://www.hak5.org/gear/usb-rubber-ducky">USB Rubber Ducky</a> that can be triggered via BLE. If you have an <a href="https://greatscottgadgets.com/ubertoothone/">Ubertooth One</a> I would love you to give it a try. Instructions for building and using it are in the GitHub repo.<br />
<br />
This post covers why I decided to build Uberducky and the technicial details on how it's actually built.<br />
<br />
<h2>
Backstory</h2>
I recently found myself in a situation where I needed a shell on a laptop. The usual methods wouldn't work: all network-accessible services were disabled on the laptop, and the owner of the laptop was a hard target with good screen locking discipline so a USB Rubber Ducky wouldn't do the trick. I did identify one weak point: the monitor that the laptop was regularly plugged into had USB ports hidden on the back. Ideally I'd be able to plug in something like a USB Rubber Ducky that I could trigger remotely. Distract the target while their screen is unlocked, send the signal, and the backconnect shell drops.<br />
<br />
This is not a new idea: the <a href="https://github.com/whid-injector/WHID">Cactus WHID</a> is an inexpensive tool for doing exactly this. In its default configuration, it broadcasts a WiFi network named "Exploit" that allows you to configure a duckyscript payload and trigger it remotely. Out of the box it's not the stealthiest option, but it's very cool and definitely worth a look.<br />
<br />
I've worked extensively with Ubertooth (having written most of the BLE sniffing code) and I thought the platform would be a great fit for something a little stealthier. It has a USB microcontroller on which it is possible to implement the USB HID spec, and it has a generic radio that can be coerced to speak something akin to BLE.<br />
<br />
<h2>
Building Uberducky</h2>
The project started out as an empty firmware for Ubertooth because the main repo is too crufty. I did submodule in the main repo, as well as copying the firmware Makefiles into the root of the project. Quite a bit goes into bringing up the platform, but it's entirely hidden behind <span style="font-family: "courier new" , "courier" , monospace;">ubertooth_init()</span>. While the Ubertooth repo wasn't really designed for out-of-tree builds like this, it was surprisingly painless to make it all work. Check out Makefile and common.mk if you're interested.<br />
<br />
As a starting point, I made a very simple PoC that would inject a random keystroke at intervals. LPCUSB is the USB stack used by Ubertooth, and it comes with rudimentary HID example code. In no time flat I was injecting random keystrokes every few seconds.<br />
<br />
I ran into my first snag at this point: if you insert the example HID keyboard into an Apple computer, it pops open a dialog asking you to press certain keys so it can identify the layout. This obviously won't work for stealthy keystroke injection, so I needed to find a way to prevent this from happening. I knew that this dialog does not open on plugging in Apple branded keyboards, so I theorized that the OS uses the USB vendor and product IDs to determine whether the keyboard has a known layout. Fortunately these values can be set within LPCUSB, and sure enough by changing them to an Apple keyboard (05ac:2227) the dialog never opened.<br />
<br />
Just injecting one keystroke wasn't very interesting, so I set to expanding to a complete alphabet. I've implemented HID before over BLE so it wasn't completely new to me. See my <a href="https://blog.ice9.us/2016/12/building-bluetooth-conference-badge.html">BLE Slide Quacker</a> and some older work I did <a href="https://www.youtube.com/watch?v=_Z4gYyrKVFM">hacking Bluetooth keyboards</a>. General HID is extremely flexible, but keyboards can be implemented very simply. Every time a key is pressed or released, the keyboard sends an 8 byte report via a USB interrupt descriptor. The first byte encodes modifiers (such as control and shift) using a bitfield, and the third byte encodes all other keys. I'm not sure what the other six bytes are used for, so I left them all set to 0 and was never an issue!<br />
<br />
In order to learn the HID keycodes as well as perform general debugging of my implementation, I used Linux's debugfs capabilities. Under most kernels from the last few years, this is mounted under <span style="font-family: "courier new" , "courier" , monospace;">/sys/kernel/debug</span>. HID devices show up under <span style="font-family: "courier new" , "courier" , monospace;">/sys/kernel/debug/hid/[hex_string]/</span>, and you can watch the reports come in live by <span style="font-family: "courier new" , "courier" , monospace;">cat</span>'ing the <span style="font-family: "courier new" , "courier" , monospace;">events</span> file. I used a normal keyboard and pressed each key, making note of the value of the report descriptor. I later found a handful of HID keycode tables online and the values matched up.<br />
<br />
At this point it was a SMOP (small matter of programming) to convert a given key and set of modifiers into a valid HID report. You can see the code in <a href="https://github.com/mikeryan/uberducky/blob/master/hid.c">hid.c</a>.<br />
<br />
<h2>
Injecting Duckyscript</h2>
The goal, of course, was to inject a sequence of keystrokes that would cause the target system to perform some malicious action. The people behind the USB Rubber Ducky invented a scripting language called Duckyscript to simplify this process and make it possible to share such scripts.<br />
<br />
Duckyscript is designed for humans to read and write, but trying to implement a bulky parser on the microcontroller doesn't make much sense. Instead I wrote a <a href="https://github.com/mikeryan/uberducky/blob/master/script_gen.py">Python parser to compile Duckyscript</a> down into a binary language that's suitable for use on the MCU. The parser outputs a C file with an array that gets compiled into the firmware.<br />
<br />
On the microcontroller, I use a state machine driven by the LPC1752's timer peripheral to run the script and actually do the keystroke injection. TIMER0 is configured to tick with a 1 millisecond period, and by using the match registers it is possible to cause an interrupt to occur at any given time. I chose 1 ms because Duckyscript encodes delays in units of milliseconds, and a single keypress takes around 10 ms to complete. The state machine lives in <a href="https://github.com/mikeryan/uberducky/blob/master/uberducky.c">uberducky.c</a>.<br />
<br />
The compiled version of Duckyscript uses four opcodes: key, delay, string, and repeat. Key is a single keypress usually combined with a modifier, such as control-v, windows, or any printable ASCII character. Delay pauses the script for a specified number of ms. String is a sequence of characters all typed in a row, such as "echo hello". Repeat will repeat the previous opcode one or more times.<br />
<br />
With the Duckyscript injector completed, the Ubertooth hardware was acting effectively as a clone of a real USB Rubber Ducky. As soon as it was inserted to a computer, it would run the script and inject the keystrokes. Now I just needed a way to trigger it wirelessly.<br />
<br />
<h2>
Triggering via BLE</h2>
For initial testing, I abused some of the range testing code from Ubertooth to trigger the Duckyscript injection using a second Ubertooth. While I personally have a lot of Uberteeth, most people probably only have one and wouldn't like to spend an extra $120 just for triggering their Uberducky. Ultimately I wanted a mechanism that would be accessible for most people with a single Ubertooth as well as being nearly impossible to accidentally trigger.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjosB_Lp_BEw3vfITYF9-pZGVigTsda3m74tkJn-BlLRPFkneNQX0CrACwq6UPlNTE00NdC84SjVb62VbppPxbXdBULlIisgSL4Gc84fwarVywnzMrpkAb6yYgow4L8rO4AbACuyL-qugA/s1600/IMG_8269.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1600" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjosB_Lp_BEw3vfITYF9-pZGVigTsda3m74tkJn-BlLRPFkneNQX0CrACwq6UPlNTE00NdC84SjVb62VbppPxbXdBULlIisgSL4Gc84fwarVywnzMrpkAb6yYgow4L8rO4AbACuyL-qugA/s320/IMG_8269.JPG" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The author owns many Uberteeth</td></tr>
</tbody></table>
BLE advertising packets make the perfect solution. Nearly every laptop and smart phone from the past five years can speak BLE, and while a full link layer is complex just receiving advertising packets is very simple. Set the CC2400 to listen on one of three advertising channels, set the modulation parameters to match those of BLE, set the correct access code, and dewhiten the data received from the air.<br />
<br />
I initially planned to lift some of the BLE code from Ubertooth, but like the rest of the firmware it is not written modularly and is overly complex for the task at hand. Instead I implemented it as simply and stupidly as possible using the CC2400's built-in FIFO. When a packet is received, the 32 byte FIFO fills. Once it is full, the radio stops receiving and goes into idle mode. Normally you might parse the packet header to read the length and turn off the radio when the full packet is received, but that would take more lines of code! Instead, Uberducky blindly receives 32 bytes no matter what, even if we're just decoding random radio noise. All the BLE code fits into fewer than 100 lines, check it out in <a href="https://github.com/mikeryan/uberducky/blob/master/ble.c">ble.c</a>.<br />
<br />
The FIFO trick allows us to receive any advertising packet sent on a given channel, but we still need a trigger. Instead of even attempting to parse the packet, Uberducky searches for a magic 128-bit string of bytes anywhere within the packet. The magic string is defined at compile time and can be changed to suit the user's needs.<br />
<br />
That only leaves us with how to send the trigger. Once again, a second Ubertooth is the simplest approach, but normal BLE devices also have a mechanism for sending 128-bit values: by including a list of 128-bit UUIDs in the AD data section of the advertising packet. The only trick is that the UUID needs to be within the first 32 bytes of the packet.<br />
<br />
On Linux, it's possible to do this with the following commands:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">sudo btmgmt add-adv -D 1 -u fd123ff9-9e30-45b2-af0d-b85b7d2dc80c 1 &&</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> sudo btmgmt clr-adv</span><br />
<br />
This very briefly sets the system to advertise with the specified UUID and then disables advertising. The only caution is that if the script is very short it can be triggered multiple times.<br />
<br />
It is possible to similar tricks on other OSes, but that is left as an exercise to the reader.<br />
<br />
<h2>
Wishlist</h2>
There are a few things I'd love to implement in the medium to long term. Primarily I'd like the ability to update the Duckyscript or trigger UUID without reflashing the entire firmware. It would also be nice to change the magic UUID in the same way.<br />
<br />
I envision two possible approaches. The first is to implement a USB serial port. While this reduces stealthiness, it is very straightforward and accessible. A second (and cooler) approach would be to implement a wireless protocol that could be managed using a second Ubertooth. The dream, of course, is to drive it entirely from BLE, but that would entail building an entire link layer to run on Ubertooth. Easier said than done!<br />
<br />
Finally, I would love to see ways of triggering it from other platforms. In particular, OS X or Android would be stupendous and I imagine not much code.<br />
<br />
If these ideas or any others strike your fancy, I will happily accept pull requests on GitHub.<br />
<br />
<h2>
Parting thoughts</h2>
Please give Uberducky a try and let me know if it works for you! I'm a little suspect that my Duckyscript parser and injection are 100% complete and accurate, so bug reports are certainly welcome.<br />
<div>
<br /></div>
Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com3tag:blogger.com,1999:blog-4056437003022567927.post-67238410938383086472018-04-04T08:48:00.002-07:002023-11-06T14:26:53.672-08:00Stealing Credit Cards from FUZE via BluetoothThis article covers <a href="https://www.fuzecard.com/">FUZE Card</a>, a Bluetooth-enabled reprogrammable credit card. The size and shape of a regular credit card, FUZE promises to be "your whole wallet in one card."<br />
<br />
After receiving a FUZE Card from <a href="https://twitter.com/mbhbox">@MBHbox</a> (<a href="http://blog.mbhbox.net/">his blog</a>), I decided to take a careful look at it. In the process, I X-rayed the card, fully reverse engineered its Bluetooth protocol, and found a security vulnerability that allows credit card numbers to be stolen via Bluetooth (<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-9119">CVE-2018-9119</a>).<br />
<br />
<a href="https://ice9.us/">ICE9</a> reported this vulnerability to BrilliantTS, the maker of FUZE, but they did not respond to repeated follow-ups and did not take action on the basis of our report. As of this writing, CVE-2018-9119 continues to be exploitable on production FUZE Cards in the wild.<br />
<br />
<span style="color: red; font-size: 120%; font-weight: bold;">Update 2018-04-07:</span> BrilliantTS reached out to ICE9 and informed us that they were already aware of this issue and are planning to release an updated firmware on 2018-04-19. They have also added a security@fuzecard.com email address so issues can be more easily reported in the future. Refer to their <a href="https://fuzecard.com/FUZE_NOTICE_20180406.png">security notice</a> for further details. I applaud BrilliantTS for taking steps to remediate this issue once it reached their attention.<br />
<br />
The remainder of this article is organized into the following sections:<br />
<ul>
<li><a href="#description">Description of FUZE Card</a></li>
<li><a href="#xray">X-ray hardware "teardown"</a></li>
<li><a href="#bluetooth">Bluetooth reverse engineering</a></li>
<li><a href="#vuln">Security vulnerability and exploit PoC</a></li>
<li><a href="#coin">A few words about Coin</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<div>
Feel free to skip directly to the <a href="#vuln">vulnerability and exploit</a> if you are impatient.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<video width="560" poster="https://ice9.us/fuze_vuln.jpg" controls>
<source src="https://ice9.us/fuze_vuln.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<a name="description"></a>
<br />
<h2>
Description of FUZE Card</h2>
FUZE is an IoT device the size, shape, and thickness of a normal credit card. You program credit cards into it via Bluetooth (BLE) using a smart phone app. When you go to pay, you use the buttons and e-Paper display to select which card to emulate. The magnetic stripe reprograms itself to impersonate that card, and then FUZE can be swiped like a regular credit card.<br />
<br />
To configure FUZE and add or remove credit cards, BrilliantTS publishes an app called <a href="https://www.ecardmanager.com/page/home/ecardmanager.html">eCARD Manager</a>. To add a card, you must swipe it on your phone using an included card reader that plugs into the headphone jack (like a Square dongle). I found this process to be extremely unreliable, taking in excess of 20 swipes to finally accept my card. BrilliantTS claims FUZE can hold up to 30 cards.<br />
<br />
FUZE does attempt to provide some level of security. When you set up FUZE for the first time you are prompted to configure a passcode as a sequence of six button presses, although this step can be skipped. With a passcode configured, the device remains locked unless you manually unlock it or your smartphone is nearby. In the locked state, you can't access any of the data on the card or program the magstripe. It also has a higher security mode in which the card will only function when it is connected to a phone via Bluetooth.<br />
<br />
Based on promotional images on their site, BrilliantTS plans to release a version with EMV (chip) support. At the time of this writing, only the magnetic stripe version is available. The card also contains NFC circuitry to support contactless payment, but this does not work with the latest firmware.<br />
<br />
<a name="xray"></a>
<br />
<h2>
X-ray hardware "teardown"</h2>
<div>
<div>
I wanted to get an understanding of how the device was built. With a typical IoT device, this usually involves removing the case with a few screws or a spudger and taking a glance at the PCB. At worst you're foiled by an epoxy-encased die.</div>
<div>
<br /></div>
<div>
In the case of FUZE, the device is a solid construction that is a mere 0.03" thick. It may be possible to very carefully remove the plastic packaging, but I only had one and did not want to risk destroying it.</div>
<div>
<br /></div>
<div>
X-ray imaging is great in this scenario. I reached out to <a href="https://twitter.com/johndmcmaster">John McMaster</a> who has taken <a href="https://twitter.com/mpeg4codec/status/623658059282280448">X-rays for me in the past</a>. He captured the following image, which I have annotated:</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinsT6urey3FeY606CKvYR7pxWSWLUvTIolvpzfTtr8ejoZ0YQyVad5u5PyzXIkmjWV1y5gmPEJJNiEEopE8Lsbcg73UmzdTd-SnQ-mrANeAshtTi5bqccE1W4V7OuXrgoaTpO8O8QuYyY/s1600/card-labels.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="862" data-original-width="1600" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinsT6urey3FeY606CKvYR7pxWSWLUvTIolvpzfTtr8ejoZ0YQyVad5u5PyzXIkmjWV1y5gmPEJJNiEEopE8Lsbcg73UmzdTd-SnQ-mrANeAshtTi5bqccE1W4V7OuXrgoaTpO8O8QuYyY/s640/card-labels.jpg" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
From the image we can see some key features of FUZE's architecture. The main chips on the board are a microcontroller, an e-Paper driver, and a Bluetooth SoC. A number of features are present on the board but are not used, including NFC and EMV (chip card support).</div>
<div>
<br /></div>
<div>
The footprint of the Bluetooth chip is some BGA variant, and the ball land pattern is somewhat unique. With a little sleuthing, Alvaro Prieto[twitter] was able to pinpoint it to the <a href="https://www.qualcomm.com/products/csr1013">CSR1013</a>. Similar to the nRF51, the CSR101x series is a complete system-on-chip (SoC) with the ability to run custom code. Some of the application code likely lives on the CSR1013.</div>
<div>
<br /></div>
<div>
The microcontroller is an unidentified 68 pin QFP. The bulk of the application likely runs on this, including the code for displaying the screen, button input, and yet-to-be implemented NFC and EMV functionality. The QFP next to the microcontroller is likely a driver for the e-Paper display.</div>
<div>
<br /></div>
<div>
BrilliantTS plans to release a version of FUZE with EMV support, and their site has marketing images of that variant of the card. It is interesting (but not surprising) to note that they use a single board design for both cards. On the magstripe version of the card, the plastic packaging simply covers the smart card contacts for EMV.</div>
<div>
<br /></div>
<div>
A bit of Googling does reveal some press release and marketing photos showing the inside of the card. <a href="http://seoulspace.com/2016/01/04/korean-startup-company-launches-brilliant-card/">A review on Seoul Space</a> shows a bare board for a prototype version of the card, and <a href="https://fuzecard.com/">FUZE's main site</a> includes a promotional photo of the hardware stackup.</div>
<div>
<br /></div>
<a name="bluetooth"></a>
<br />
<h2>
Bluetooth Reverse Engineering</h2>
</div>
<div>
<div>
For a piece of technology like FUZE, the Bluetooth interface is of primary interest for reverse engineering. My toolchest for reverse engineering a Bluetooth device:</div>
<div>
<ul>
<li>Android phone</li>
<li><a href="https://portswigger.net/burp">Burp Suite</a> (optional)</li>
<li><a href="https://www.wireshark.org/">Wireshark</a> + crusty Perl scripts</li>
<li>gatttool / BlueZ</li>
</ul>
</div>
<div>
Android is absolutely indispensable for performing a blackbox analysis of a Bluetooth device. Out of the box, we can log all Bluetooth traffic from an app to a device. It is also possible to modify app code directly by disassembling and reassembling the Java bytecode, but I didn't have to perform any such app surgery on this assessment.</div>
<div>
<br /></div>
<div>
Burp acts as an HTTP proxy and allows you to inspect API requests made by the Android app to backend servers. Although it wasn't critical for understanding how the FUZE card worked, it did provide some clues.</div>
<div>
<br /></div>
<div>
Android ships a feature called "HCI snoop log" in the "Developer options" settings menu. Enabling this feature saves all Bluetooth activity on the phone to a file, and that includes every message exchanged between the app and device.</div>
<div>
<br /></div>
<div>
Wireshark can read the files produced by Android's HCI snoop log. It's useful for doing basic analysis and filtering. For bulk and semi-automated analysis I like to export the data to text files and munge them using Perl.</div>
<div>
<br /></div>
<div>
Finally, gatttool (and other BlueZ tools) can be used to probe the device directly. It's often useful to take a quick peek with gatttool before even firing up the app. It shines during analysis for experimenting with sending and receiving partially understood protocol messages.</div>
<div>
<br /></div>
<h3>
Reversing FUZE</h3>
<div>
Using gatttool to connect to FUZE not work out as well as hoped. Immediately upon connecting to the card, it sends a "Security Request" over the Security Manager Protocol. This is the card demanding that we pair with it, which is actually uncommon among IoT devices in my experience. <a href="https://blog.ice9.us/2014/01/ble-fun-with-ubertooth-sniffing.html">BLE's pairing protocol is known to be flawed</a> and most devices implement their own security instead of relying on it. FUZE absolutely refuses to send any data to a device that isn't paired with it and isn't using BLE link layer encryption.</div>
<div>
<br /></div>
<div>
Since gatttool didn't work out, I moved onto my Android-based reverse engineering approach, which looks something like this:</div>
<div>
<ol>
<li>Enable Bluetooth HCI snoop on Android</li>
<li>Do things in the app and with the card</li>
<li>Transfer HCI log to PC using adb</li>
<li>Review in Wireshark</li>
<li>Filter / export as text</li>
<li>Parse with crusty Perl</li>
<li>Smash face against keyboard repeatedly</li>
</ol>
</div>
<div>
Loading and filtering the data in Wireshark allowed me to discern that FUZE uses two characteristics for communication: the app writes to the card using write requests on one handle, and receives responses via notifications on another handle. This is extremely common, as it allows developers to treat the BLE channel almost as though it were a TCP socket or serial port.</div>
<div>
<br /></div>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0cmIvjkoJHaVvLk6ZzTAc1xnz9dceisW_MJMYtxPVR4DHLmSInaqZd1EufvaLH1FzHF1Ut5_096VPz0taSdonRoKV1FaJwiIYqhVIgZ7E1o4MIGicS-XrrMxyTZ0Ie8SNncGtku9RDxI/s1600/wireshark.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="645" data-original-width="1084" height="380" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0cmIvjkoJHaVvLk6ZzTAc1xnz9dceisW_MJMYtxPVR4DHLmSInaqZd1EufvaLH1FzHF1Ut5_096VPz0taSdonRoKV1FaJwiIYqhVIgZ7E1o4MIGicS-XrrMxyTZ0Ie8SNncGtku9RDxI/s640/wireshark.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Reverse engineering by eye in Wireshark</td></tr>
</tbody></table>
</div>
<div>
<br /></div>
<div>
Eyeballing the data in Wireshark left me more hopeful. A great aspect of HCI snoop logging is that the data is captured before it is encrypted by the hardware Bluetooth chip on the phone. The plaintext data included some ASCII strings, and repeated application of step 7 led me to begin to understand some of the protocol format.</div>
<div>
<br /></div>
<div>
Wireshark does not lend itself well to bulk analysis, but it provides a rich set of export utilities to allow for post processing. It is a total hack, but I have had the best luck using "Export Packet Dissections" -> "As Plain Text". Before exporting, expand the "Attribute Protocol" dissection to show the data sent over the air. In the export window, ensure "Details" includes "As displayed". Finally a bit of gross Perl turns this into something I can work with.</div>
<div>
<br /></div>
<div>
At this point, I revisited gatttool. Using bluetoothctl I was able to scan for and pair with the card. It requires the use of Numeric PIN pairing mode in which a 6 digit number is displayed on FUZE's screen that must be entered in the client (a VM running BlueZ) to successfully pair. Once pairing is completed and encryption is established, the device happily responds to GATT messages over the Attribute Protocol.</div>
<div>
<br /></div>
<div>
First up was replaying some messages from the Wireshark dumps. I noticed one message was consistently occurring near the beginning of the conversation:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tx 02f50101000000000000000000000000000000f5 ....................</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">rx ddf50f02019000000602000169ffffff31320003 ............i...12..</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">rx ddf50e0202425041592d434d472d3031410003 .....BPAY-CMG-01A..</span></div>
<div>
<br /></div>
<div>
When sending the first line using gatttool, the second and third lines are reliably sent back. Parsing the data by eye a bit, version numbers become apparent for the hardware, microcontroller firmware, and BLE firmware.</div>
<div>
<br /></div>
<div>
That's interesting, but the very first message being sent is even more interesting:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">tx 02c40101300000000000000000000000000000f4 ....0...............</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">rx ddc404010190000003</span></div>
<div>
<br /></div>
<div>
As soon as this message is sent, the FUZE lock screen turns off and the main menu appears. This is implemented for user convenience, so the card is automatically unlocked when it is near a paired smart phone.</div>
<div>
<br /></div>
<div>
From here it is a matter of staring, thinking, a little experimentation, but mostly staring and thinking. This part should sound familiar to anyone who's ever reverse engineered anything.</div>
<div>
<br /></div>
<div>
Ultimately I was able to reverse engineer the majority of the protocol messages: including the message format and supported operations.</div>
<div>
<br /></div>
<div>
App-to-device messages have the following format:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> 02 XX YY ZZ .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. WW</span></div>
<div>
<ul>
<li><span style="font-family: "courier new" , "courier" , monospace;">XX</span> - opcode</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">YY</span> - total number of GATT write requests for the current operation</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">ZZ</span> - current write request number</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">..</span> - message body</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">WW</span> - checksum</li>
</ul>
</div>
<div>
I determined the following opcodes through a mix of interpreting messages I captured as well as light fuzzing:</div>
<div>
<ul>
<li><span style="font-family: "courier new" , "courier" , monospace;">b3</span> - upload a payment or membership card</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">b4</span> - delete a synced card</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">b5</span> - possibly change card information (discovered through fuzzing)</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">b6</span> - possibly reorder cards (discovered through fuzzing)</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">b9</span> - set card owner name (displayed on powered off screen)</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">ba</span> - unknown function (discovered through fuzzing)</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">bb</span> - set security level</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">bc</span> - get total number of cards</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">bd</span> - unknown function, related in some way to card index (discovered through fuzzing)</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">be</span> - fetch a payment or membership card</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">bf</span> - get card owner name</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">c4</span> - turn off passcode screen</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">c5</span> - set or disable passcode</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">c6</span> - factory reset</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">c7</span> - enable or disable data blind</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">d1</span> - enter firmware update mode</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">d2</span> - firmware update data</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">d3</span> - related to firmware update</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">d4</span> - related to firmware update</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">ea</span> - fetch battery level</li>
<li><span style="font-family: "courier new" , "courier" , monospace;">f5</span> - fetch hardware rev, Bluetooth firmware version, and MCU firmware version</li>
</ul>
</div>
<div>
The checksum is calculated by performing an exclusive-or (xor) of all message bytes except the initial 02. Props to <a href="https://github.com/jkbenaim">Jason Benaim</a> for identifying this highly secure Game Boy style checksum.</div>
<div>
<br /></div>
<div>
I looked briefly at the firmware update process, but I did not dive deeply. Since I only have one card, I knew I wasn't going to attempt any firmware flashing shenanigans. I was able to capture two MCU firmware samples by snooping the HTTP requests using Burp. The two samples are both high entropy, nearly the same size, and quite dissimilar in content. This suggests that they are encrypted. Without further analysis, it's not possible to say if they are signed or validated in any way during the firmware update process.</div>
<div>
<br /></div>
<div>
The BLE firmware update occurs over CSR's in-house OTA update protocol. I am not aware of any security analysis of this protocol. It would be interesting to study and understand, as I'm sure it is used by other devices with this or similar CSR BLE SoCs.</div>
</div>
<div>
<br /></div>
<div>
<a name="vuln"></a>
<br />
<h2>
Security vulnerability and exploit PoC</h2>
<div>
With an understanding of the Bluetooth protocol used by FUZE (see previous section), ICE9 discovered CVE-2018-9119: an attacker with physical access to a FUZE Card can perform the following actions:</div>
<div>
<ul>
<li>Bypass the lock screen</li>
<li>Read credit card numbers, with expiration date and CVV</li>
<li>Tamper with data on the card</li>
</ul>
</div>
<div>
At the time of this writing, the vulnerability has not been patched and remains exploitable on all production FUZE Cards.</div>
<div>
<br /></div>
<div>
This vulnerability affects MCU firmware 0.1.73 and BLE firmware 0.7.4, the most recently released versions of both.</div>
<div>
<br />
<span style="color: red; font-size: 120%; font-weight: bold;">Update 2018-04-07:</span> BrilliantTS plans to release an updated firmware on 2018-04-19. See the beginning of this article for full details.<br /><br />
</div>
<div>
The attacker must have physical access to the card because of how the card uses BLE link layer security. In addition to encrypting data, BLE link layer security acts as an authentication mechanism. If you aren't paired with the FUZE card, it will reject every message you send to it. Although <a href="https://blog.ice9.us/2014/01/ble-fun-with-ubertooth-sniffing.html">BLE link layer security has well known weaknesses</a> (also discovered by ICE9), it works reasonably well for FUZE's use case.</div>
<div>
<br /></div>
<div>
Where FUZE went right was using the Numeric PIN pairing mode. When you pair with FUZE, the card displays a 6 digit random number on its e-Paper screen. You must enter this on your phone (or Linux attack VM) in order for pairing to succeed. If you attempt to pair with a card that is not in your possession, you will have a one in a million chance of guessing the 6 digit pairing code correctly.</div>
<div>
<br /></div>
<div>
Rigorous testing indicated that it was not possible to bypass the pairing requirement, and also it was not possible to downgrade to a weaker pairing mechanism (Just Works) that does not require entering a passcode.<br />
<br />
Some may argue that the physical access requirement makes this vulnerability uninteresting. I would like to emphasize two points: the first is that handing a credit card to strangers is a normal part of making many types of purchases, so it is impossible to ensure that the card is not tampered with out of sight. Secondly, the card presents itself as more secure than a normal credit card with its use of a lock screen. As demonstrated by this weakness, that is a false sense of security.</div>
<div>
<br /></div>
<h3>
Proof-of-Concept Exploit</h3>
<div>
ICE9 developed a proof-of-concept exploit that can be run from a Linux system or VM. The exploit has been tested in Debian Stretch inside VMware using a BLE dongle via USB passthrough. This attack requires BlueZ to be installed.</div>
<div>
<br /></div>
<div>
First, scan for and pair with the device using bluetoothctl:</div>
<div>
<ol>
<li>Launch bluetoothctl: <span style="font-family: "courier new" , "courier" , monospace;">sudo bluetoothctl</span></li>
<li>Enable the agent (used for pairing): <span style="font-family: "courier new" , "courier" , monospace;">agent on</span></li>
<li>Scan for devices: <span style="font-family: "courier new" , "courier" , monospace;">scan on</span></li>
<li>Once a FUZE Card is found, disable scanning: <span style="font-family: "courier new" , "courier" , monospace;">scan off</span></li>
<li>Pair wih the FUZE Card: <span style="font-family: "courier new" , "courier" , monospace;">pair <bdaddr></span></li>
<li>Enter the Numeric PIN displayed on the device</li>
<li>Disconnect from the card: <span style="font-family: "courier new" , "courier" , monospace;">disconnect <bdaddr></span></li>
</ol>
<div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi3V6sl4IGnNqKsYTJXhVR_YTsGyNQixG0eYU-sCLjCOoceCMNZT9Z54tkx5r8HsvdzUtDdgArc5cQe3GPwvSdT8-mMd2PJPtrOHcx1Bo3RLu7vybN_a8SElMTHvhROjz4-H-3gLeAXFE/s1600/01_bluetoothctl.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="564" data-original-width="794" height="452" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi3V6sl4IGnNqKsYTJXhVR_YTsGyNQixG0eYU-sCLjCOoceCMNZT9Z54tkx5r8HsvdzUtDdgArc5cQe3GPwvSdT8-mMd2PJPtrOHcx1Bo3RLu7vybN_a8SElMTHvhROjz4-H-3gLeAXFE/s640/01_bluetoothctl.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pairing with the FUZE Card</td></tr>
</tbody></table>
</div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
From here, it is possible to send commands to the card using gatttool:</div>
<div>
<ol>
<li>Launch gatttool: <span style="font-family: "courier new" , "courier" , monospace;">sudo gatttool -I -b <bdaddr></span></li>
<li>Connect to the device: <span style="font-family: "courier new" , "courier" , monospace;">connect</span></li>
<li>Subscribe to notifications: <span style="font-family: "courier new" , "courier" , monospace;">char-write-req 1b 0100</span></li>
<li>Send commands: <span style="font-family: "courier new" , "courier" , monospace;">char-write-req 18 <command data></span></li>
</ol>
</div>
<div>
The following commands are of interest:</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> 02c40101300000000000000000000000000000f4</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> 02be01013030310000000000000000000000008f</span></div>
<div>
<br /></div>
<div>
The first will bypass the lock screen, and the second will read the first credit card number, expiration date, and CVV.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtWmRV9Sra5GgSUpafj69lbJmFjtK2aQSRoH0CwpGeFun_ckckZWd32qeUYAAK2sGaNNOSCmxOs55Nn9y5frGLbw40wvuFNiNxmIA_A9AX8Z_7ZJ9Vf7qp3e8W0wNYQzJQ-fClfrBDJ78/s1600/02_card.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="564" data-original-width="794" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtWmRV9Sra5GgSUpafj69lbJmFjtK2aQSRoH0CwpGeFun_ckckZWd32qeUYAAK2sGaNNOSCmxOs55Nn9y5frGLbw40wvuFNiNxmIA_A9AX8Z_7ZJ9Vf7qp3e8W0wNYQzJQ-fClfrBDJ78/s640/02_card.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Stealing credit card numbers via Bluetooth</td></tr>
</tbody></table>
</div>
<h3>
Disclosure to BrilliantTS</h3>
<div>
ICE9 disclosed the details of this vulnerability to BrilliantTS via email on the following timeline:</div>
<div>
<ul>
<li>2018-01-30 - Initial email to info@fuzecard.com and support@fuzecard.com</li>
<li>2018-01-31 - Follow-up email sent</li>
<li>2018-02-04 - Third follow-up sent</li>
<li>2018-02-05 - Response received from BrilliantTS (FUZE tech support individual)</li>
<li>2018-02-06 - Report sent to FUZE tech support individual</li>
<li>2018-02-09 - Follow-up sent to FUZE tech support individual</li>
<li>2018-02-13 - Final follow-up sent to FUZE tech support individual</li>
<li>2018-03-22 - Disclosure period expired</li>
</ul>
</div>
<div>
The report included a complete description of the vulnerability, proof-of-concept exploit code, and noted that ICE9's standard disclosure period is 45 days. BrilliantTS did not respond to any message after the report was delivered, and the 45 day disclosure period has since expired.</div>
<div>
<br /></div>
<div>
As of this writing, BrilliantTS has not released a firmware update for the FUZE Card.</div>
<div>
<br /></div>
<h3>
Cracking the Encryption</h3>
<div>
For completeness, I will note that the Numeric PIN pairing mode (along with other LE Legacy Pairing modes) is vulnerable to a brute force attack if an attacker is able to sniff the pairing conversation. I consider this an unlikely scenario with FUZE. It's likely that the user will pair in a secure location (such as their home), far from attackers. When they go to use the card, the phone and card use the previously established encryption key. During this phase of encryption, there are no known weaknesses.</div>
<div>
<br /></div>
<div>
Nonetheless, as a proof-of-concept, I was able to sniff a pairing conversation and crack it using crackle.</div>
</div>
<div>
<br /></div>
<div>
<a name="coin"></a>
<br />
<h2>
A few words about Coin</h2>
<div>
Some readers of this article probably remember that FUZE is not the first attempt at a Bluetooth credit card. Way back in the ancient days of 2013, Coin announced a similar product, and delivered it to users by 2015. Fitbit acquired coin in 2016 and killed the product and backend by 2017.</div>
<div>
<br /></div>
<div>
<a href="http://adammunich.com/">Adam Munich</a> snapped an X-ray of Coin:</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4H7HcFc-arjiWHF3ILsUqE2TqbBmiVUHw7x5WQdULLu7rCmOUqL0fqe4G2LSe6AD010mwYSsCPTw3cwsTn4U70oufwEd7LBHXPXChtAV0KSdHGkKq0HJqV48WcdGTsZ_Q3tWPNYDrKzw/s1600/coin-small.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="646" data-original-width="1024" height="401" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4H7HcFc-arjiWHF3ILsUqE2TqbBmiVUHw7x5WQdULLu7rCmOUqL0fqe4G2LSe6AD010mwYSsCPTw3cwsTn4U70oufwEd7LBHXPXChtAV0KSdHGkKq0HJqV48WcdGTsZ_Q3tWPNYDrKzw/s640/coin-small.png" width="640" /></a></div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<div>
<br /></div>
<div>
From the X-ray it is clear that Coin is a much simpler design than FUZE.</div>
<div>
<br /></div>
<div>
Like FUZE, Coin is the size and thickness of a regular credit card and communicates via Bluetooth. It has a simpler TN LCD segment-based screen and only a single button. Even still, it also has a passcode feature similar to FUZE. Unlike FUZE, the battery is not rechargeable, and users were expected to return their cards for replacement every two years.</div>
<div>
<br /></div>
<div>
One key way in which FUZE attempts to differentiate itself is by including NFC and EMV support. At the time of this writing, neither of those features is available, so it's a moot point.</div>
<div>
<br /></div>
<div>
I never owned a Coin device, so I can't say how its security compared to FUZE. To the best of my knowledge, nobody ever succeeded in extracting credit card numbers from Coin over Bluetooth. However, since the product is completely dead, it's again a moot point.</div>
<div>
<br /></div>
<a name="conclusion"></a>
<br />
<h2>
Conclusion</h2>
<div>
Some IoT ideas are unusually sticky. No matter how bad they sound, someone goes out and makes them. A Bluetooth credit card meets this definition for me. With Apple Pay, Google Pay, and other contactless payments shaking up the payments industry, I don't see a lot of value in a Bluetooth credit card. Even with those options available, I still see myself carrying around ordinary credit cards for the foreseeable future. At the end of the day, the risks of a Bluetooth card aren't worth the questionable convenience benefit.</div>
</div>
<div>
<br />
If you would like to hear more and you're in the Bay Area, I will be presenting my research on FUZE Card at the <a href="https://www.meetup.com/Mountain-View-Reverse-Engineering-Meetup/events/249206794/">Mountain View Reverse Engineering Meetup</a> (in Santa Clara) on Wednesday April 11, 2018 at 8 PM.<br />
<br />
ICE9 Consulting is an independent security firm specializing in Bluetooth and IoT. For more information, <a href="https://ice9.us/">visit our main site</a>.</div>
Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com6tag:blogger.com,1999:blog-4056437003022567927.post-88774109155888636902016-12-20T08:00:00.000-08:002016-12-20T09:42:27.364-08:00Building a Bluetooth Conference BadgeWho doesn’t love electronic con badges? They look fly as heck, blink LEDs, and… well… that’s all most of them do. Don’t get me wrong, there have been some neat game badges and even a few useful ones (hat tip to <a href="https://twitter.com/michaelossmann">Mike Ossmann</a> for <a href="http://ossmann.blogspot.com/2012/10/hackrf-jawbreaker.html">releasing a HackRF as a badge</a>(!)). But those are the exception. Most go straight into the <strike>ewaste</strike> old badge pile after the con.<br />
<br />
That’s why when I set out to create a conference badge, I wanted to make something I’d actually use for something other than bling. Enter the Slide Quacker!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhLBWwAFwOD6jTAv8xVx3Dy3XPCHo9kN0Ic_AMO0YLCszVYofVVKqRTP6qS_zwz3PUF12YROkgwpoE6vSq10Gn2tBa8KFV4R9i0iWPIeiBpnSv0WzJX9hdSscBxl49RB3Qnzr76uLKdQw/s1600/quacker.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhLBWwAFwOD6jTAv8xVx3Dy3XPCHo9kN0Ic_AMO0YLCszVYofVVKqRTP6qS_zwz3PUF12YROkgwpoE6vSq10Gn2tBa8KFV4R9i0iWPIeiBpnSv0WzJX9hdSscBxl49RB3Qnzr76uLKdQw/s320/quacker.jpg" width="320" /></a></div>
<br />
<br />
This summer ICE9 Consulting (that’s me!) sponsored <a href="https://wrongisland.org/">Wrong Island Con 2+ε</a>, a roaming conference put on by ducklord <a href="https://twitter.com/rich0h">richö butts</a> that took place on Catalina Island in Los Angeles, CA. Along with our pal <a href="mailto:wic@n.routed.net">nico</a>, we sunk a bunch of time, effort, and money into creating the best conference badge we could imagine.<br />
<br />
The Slide Quacker is a <a href="https://www.bluetooth.com/what-is-bluetooth-technology/how-it-works/low-energy">Bluetooth Smart</a> (BLE) slide clicker. You can pair it with your laptop and use it to change slides in a presentation. Neato. It is an open source, open hardware design, so if you like what you see you can even make one yourself.<br />
<br />
The firmware is based on <a href="https://mynewt.apache.org/">Apache Mynewt</a>, a project by <a href="http://runtime.io/">Runtime.io</a> that is incubating its way (hopefully) into the Apache Software Foundation. Mynewt provides a full embedded RTOS (real time operating system) as well as a fully open source BLE stack. I did run into a few rough edges at the time. It’s a little underdocumented, and I did find some bugs (it turns out when you report bugs in a Bluetooth stack the default assumption is “crackpot”, reasonably so). That being said, it’s come a tremendous way since then, and they just released milestone 1.0.0. If you’re in the market for a lightweight, featureful RTOS, give it a look.<br />
<br />
On top of Mynewt, we implemented a very basic HID over GATT implementation to emulate a HID keyboard. Our super sick keyboard only has two buttons: left and right arrow, although you can of course map any button to any function since the firmware is open.<br />
<br />
The hardware was lovingly handcrafted by nico. The design centers around a <a href="https://www.nordicsemi.com/Products/nRF51-Series-SoC">Nordic nRF51</a> SoC (System on Chip) with integrated BLE-compatible radio. Nordic does ship source code that you can use in designs, but it’s not an open-source compatible license. Thus our choice to use Mynewt. Other peripherals include an I2C accelerometer for pairing, a USB UART for firmware updating, and a whole bunch of LEDs because no conference badge would be complete without them. It even includes some easter eggs for setting your preferred orientation (though I did morally struggle with whether to include the UPRIGHT option).<br />
<br />
This was our first experience building a con badge, and holy moly was it a frosted buttload of work. But it was totally worth it in the end to see the badge ACTUALLY BEING USED by some of the speakers! Plus there were some fun shenanigans to be had at the con, making sure everyone knew that flat ducks ultimately reign supreme.<br />
<br />
If you’re interested in the hardware design and the firmware, check out the repo! As always, feel free to leave any questions and comments below.<br />
<br />
And before you ask… no I do not plan to make any more of these. But if you come to the next Wrong Island Con (hint: bug richö to run it again) maybe you’ll get your hands on our next creation.<br />
<div>
<br /></div>
Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com0tag:blogger.com,1999:blog-4056437003022567927.post-41494551667697656702015-09-01T21:47:00.000-07:002016-12-19T18:17:31.017-08:00Peeking Inside the BGM111 Bluetooth ModuleIn August Silicon Labs released the BGM111, a Bluetooth Smart (BLE) module that might be powering the next generation of IoT devices in customers' hands and on hackers' workbenches.<br />
<br />
I was curious about the module so I grabbed the datasheet. It's behind a registration wall on the Silicon Labs site, but strangely <a href="http://www.silabs.com/Support%20Documents/RegisteredDocs/BGM111_datasheet.pdf">a direct link</a> turns up on the first page of a Google search.<br />
<br />
The datasheet is fairly pedestrian. It appears to be running a custom Bluetooth stack on a Cortex-M4, the most powerful CPU core I've seen in a Bluetooth SoC to date. Developers have a few different options for running code. It is possible to use a custom API over a UART and run application code on an external MCU (similar to the BLE112 and Nordic nRF8001). It is also possible to upload code written in BGScript, a custom scripting language, and run it directly on the device (again like the BLE112).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/bgm111/stack.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blog.lacklustre.net/images/bgm111/stack.png" width="320" /></a></div>
<br />
Not much else really caught my eye in the datasheet. JTAG is exposed on the header, so it may be possible to dump the code running onboard and reverse engineer that. However once I reached regulatory section at the end of the datasheet, I noticed this odd statement:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/bgm111/chip_tbd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blog.lacklustre.net/images/bgm111/chip_tbd.png" /></a></div>
<br />
This piqued my interest. What strange chip could be inside? I know of no existing Bluetooth chips on the market with an M4 core. The product web site has a rendered image of the module without the RF cage blocking the chip, but I hadn't heard of Blue Gecko nor seen the logo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/bgm111/bluegecko-module.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="175" src="https://blog.lacklustre.net/images/bgm111/bluegecko-module.jpg" width="320" /></a></div>
<br />
A quick bit of googling indicated that this is <a href="http://news.silabs.com/press-release/product-news/silicon-labs-launches-blue-gecko-bluetooth-smart-solutions">a new line of chips produced by Silicon Labs</a> loaded with the EFM32 core. There is plenty of documentation about the CPU core, but no documentation about any wireless SoCs.<br />
<br />
Curiosity got the better of me and I picked one up from DigiKey (not cheap at $10/unit). The RF cage came up easily enough after cooking it in an IR oven for a few minutes, though a hot air gun would have also done the trick.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/bgm111/efr32.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="234" src="https://blog.lacklustre.net/images/bgm111/efr32.jpg" width="320" /></a></div>
<br />
Curiously the label EFR32 turned up very few results in a web search. A little snooping around the Silicon Labs site exposes the story.<br />
<br />
In 2013 Silicon Labs acquired Energy Micro, a fabless semiconductor company working on low power wireless chips. At the time Energy Micro was hard at work on their EFR4 Draco line, aimed at the super low power market.<br />
<br />
After the acquisition, it appears Silicon Labs renamed the EFR4 to EFR32. They have focused their entire marketing effort on the BGM111 module and have not even released the EFR32 to distributors. The sole reference I have found to the chip in official documentation is in the <a href="http://www.silabs.com/Support%20Documents/RegisteredDocs/UG122.pdf">Blue Gecko Bluetooth Smart Module Wireless Starter Kit User's Guide</a>.<br />
<br />
This is an interesting development, the first new Bluetooth silicon to enter the market in quite a while. I'm interested to see where this module ends up, and I'm even more interested in the stack running on the device. If you come across a BGM111 in any end-user products, let me know!Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com1tag:blogger.com,1999:blog-4056437003022567927.post-56411896050402036802015-08-13T08:48:00.000-07:002016-12-19T18:35:46.606-08:00Blackbox Reversing an Electric Skateboard Wireless ProtocolRecently at DEFCON 23 <a href="https://twitter.com/rich0h">Richö Butts</a> and I gave a talk about <a href="https://www.defcon.org/html/defcon-23/dc-23-speakers.html#Ryan">hacking electric skateboards</a>. One of the skateboards, the Yuneec E-GO, uses a custom wireless protocol between its handheld remote and the board. We touched on how we reverse engineered the protocol during the talk, but I wanted to go into more depth on our methodology.<br />
<br />
In short, this is the story of how we went from HackRF to skateboard jammer on Ubertooth. Read on for the gory details!<br />
<h4>
Finding the Signal</h4>
We theorized that the skateboard and remote used the 2.4 GHz band, which is well supported by HackRF One. Ordinarily one would use GNU Radio and a basic waterfall sink to look at spectrum, but GNU Radio can be a bit cumbersome.<br />
<br />
Luckily we had a <a href="https://sharebrained.myshopify.com/products/portapack-for-hackrf-one">PortaPack</a> to play with! The PortaPack sits on top of the HackRF and acts as a wideband spectrum analyzer (among other things). We tuned up to 2400 MHz and swept the spectrum in 20 MHz increments looking for our signal.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/TBSfu3JmeUk" width="560"></iframe><br />
<br />
By holding the remote near the antenna, we could easily see short bursts occuring regularly at four frequencies: 2408 MHz, 2418 MHz, 2423 MHz, and 2463 MHz. Conveniently enough, by tuning the HackRF to 2416 MHz we could see from 2406 MHz to 2426 MHz, allowing us to capture the lower three frequencies at the same time.<br />
<h4>
Recovering Modulation Parameters</h4>
<div>
We next turned to GNU Radio and Baudline for doing further signal analysis. Using a very simple flowgraph, we could capture samples of the remote transmitting, save them to disk, and load them up into Baudline. Once we had loaded the capture into baudline, we could zoom in on individual transmissions and inspect them visually.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_packet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blog.lacklustre.net/images/ego_packet.png" width="96" /></a></div>
<div>
<br /></div>
<div>
<div>
By looking at an individual transmission we could tell that the device uses a lower frequency to represent a 0 and a higher frequency a 1. This modulation mode is called frequency shift keying, or 2FSK. By measuring with Baudline, we could see that the lower frequency and upper frequency were around 300 kHz apart, giving a frequency offset of 150 kHz. In addition to discovering the modulation mode and frequency offset, we could also see that the transmissions included long sequences of 0's, meaning it was highly unlikely the device used encryption or data whitening.</div>
<div>
<br /></div>
<div>
Turning back to GNU Radio, we set out to create a flowgraph to demodulate 2FSK. This is somewhat complicated business, but thanks to Mike Ossmann's <a href="http://greatscottgadgets.com/sdr/9/">latest SDR tutorial video</a> and <a href="http://labs.inguardians.com/posts/20140516_GRC_Signal_Analysis.html">an excellent blog post</a> by Don C. Weber we were able to puzzle out some of the finer points of 2FSK demodulation. The workhorse is the Quadrature Demod block, which tracks changes in angle of a complex-valued signal. This somehow translates into changes in frequency, but this is the part where we admit that neither of us had any idea what we were doing with DSP (as evidenced by <a href="http://www.irongeek.com/i.php?page=videos/bsideslasvegas2015/atgp01-radbios-wireless-networking-with-audio-richo-healey">Richo's BSidesLV talk</a>).</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_flowgraph.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="90" src="https://blog.lacklustre.net/images/ego_flowgraph.png" width="320" /></a></div>
<div>
<br /></div>
<div>
At this point we had turned our complex RF signal into a real-valued signal. I doubt it is the best tool for the job, but Audacity did a fine job dealing with this data. After importing the raw data into Audacity, we finally had something that resembled actual data.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_bits.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="50" src="https://blog.lacklustre.net/images/ego_bits.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<div>
At the beginning of the packet is the preamble. The signal alternates between 0 and 1 so that the receiving radio can lock on and recover the symbol rate. Following that is the first meaningful data, the access code (also called a sync word). This is a fixed-length value, usually 16, 24, or 32 bits long, which the receiving radio can synchronize on to differentiate the signal from noise. Finally the rest of the packet is the payload.</div>
<div>
<br /></div>
<div>
Zooming in on the signal, the first order of business was recovering the data rate. The preamble makes this convenient as it always alternates between 0 and 1. This allowed us to count the number of samples from a peak to a valley, which gave us samples/symbol (symbols being bits, since this was 2FSK). Dividing the samples/second by the samples/symbol gives symbols/second, the actual data rate.</div>
<div>
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_samples_per_symbol.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="149" src="https://blog.lacklustre.net/images/ego_samples_per_symbol.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<div>
In our case, we measured around 80 samples/symbol. Dividing our sample rate of 20 million samples/second by 80 gave a data rate of 250,000. This suggests a data rate of 250 kbit which is very commonly supported by off-the-shelf 2.4 GHz radios.</div>
<div>
<br /></div>
<div>
The final piece of the puzzle was the access code. To recover this value, we began the tedious process of counting bits. We measured the length (in samples) of each stretch of 1's and 0's using Audacity. By dividing these lengths by our samples/symbol, we could recover the number of bits in each stretch. After recovering around 12 bits of the access code we turned back to GNU Radio.</div>
<div>
<br /></div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_flowchart_decode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="148" src="https://blog.lacklustre.net/images/ego_flowchart_decode.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<div>
The Correlate Access Code block takes as input an access code and tags the data stream with a value of 0x02 or 0x03 (the actual data is one byte of 0x00 or 0x01 for each bit). We took the output of this block and dumped it to a file. To analyze this file, once again Don C. Weber has us covered with <a href="https://github.com/cutaway/grc_bit_converter">grc_bit_converter</a>. This tool reads the tagged output, packs the bits into bytes, and dumps the data in ASCII hex. We we treated the first 32 bits of this output as a candidate access code.</div>
<h4>
Sniffing with Ubertooth</h4>
<div>
Armed with the frequencies the device transmitted on, modulation mode of 2FSK, frequency offset of 150 Hz, data rate of 250 kbit, and access code, we finally had enough information to use a narrowband transceiver to attempt to receive packets. Ubertooth makes an ideal platform to implement a sniffer, as its CC2400 is more than up to the task.</div>
<div>
<br /></div>
<div>
The details of tuning up the CC2400 are <a href="https://github.com/greatscottgadgets/ubertooth/blob/master/firmware/bluetooth_rxtx/ego.c">best left to code</a>, but it was fairly straightforward to rig it up to tune to one of the known channels and dump packets over USB. This gave us our first samples of packet data.</div>
</div>
<div>
<br /></div>
<div>
<pre><code>time=1084328910 delta_t=1012.321200 ms freq=2418
ff e1 92 13 01 d1 00 00 00 00 80 00 80 00 00 00 ff e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff bf
</code></pre>
</div>
<div>
<br /></div>
<div>
Of note is the <code>80 00 80 00</code> starting at the 11th byte of the data. By adjusting the speed control on the remote, these values varied linearly according to position of the speed control. It was thus clear at this point that the remote communicated in plaintext to the controller.<br />
<h4>
Hopping Along</h4>
The final order of business was figuring out the hop pattern and hop interval. As indicated in the above capture from the Ubertooth data, each packet was timestamped using Ubertooth's internal 100 ns clock. This gave us a high-resolution time source for measurements. Sitting on a single channel, we could calculate the delta between consecutive packets and plot these. The minimum value observed was 44 ms between packets, with all other values being multiples of 44 ms (accounting for false positives). The fact that we were seeing multiples of 44 ms indicates we were probably missing some packets, which is to be expected.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_3channels.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blog.lacklustre.net/images/ego_3channels.png" width="148" /></a></div>
<br />
Last up was the hop pattern. Looking at the three lower channels in Baudline, it is fairly evident that the device hops between at least the visible three channels in order before returning to the initial channel. We measured the delta between the start of one packet and the start of the next packet to be 11 ms. There was a gap between the third visible channel and the initial channel of 22 ms, so it wasn't much of a stretch to deduce the device hopped to the fourth channel and then back to the first channel in that window. Thus the simple hopping pattern was: channel 1 -> channel 2 -> channel 3 -> channel 4 -> back to channel 1, with a delay of 11 ms between each channel.<br />
<br />
Finally having figured out the hop interval and hop pattern, we had all the variables needed to completely follow the E-GO remote as it transmitted to the board. Implementing this in Ubertooth was again relatively straightforward, though the code was now somewhat complicated by a state machine.<br />
<h4>
Jamming</h4>
</div>
<div>
<div>
Since the goal of the research was to attack the skateboards, we set out to create a jammer. In order to jam a narrowband communication such as this, it is sufficient to generate random noise during transmission that confuses the receiving device. The CC2400 has a special mode that produces pseudorandom data, so we made use of this.</div>
<div>
<br /></div>
<div>
The jamming code co-opts the connection following code we introduced to sniff connections. When the CC2400 detects the access code, instead of receiving the packet data we turn the radio into transmit mode and configure it to send pseudorandom data for around 2 ms. Although there is a delay of around 200 us to switch the radio into TX mode, enough of the packet data is obscured by noise that the board stops responding to the remote after around half a second.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_jammin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blog.lacklustre.net/images/ego_jammin.png" width="148" /></a></div>
<div>
<br /></div>
<div>
<div>
For robustness, the jammer also includes a timeout. If no access code is detected after 11 ms plus a bit of slop, the Ubertooth begins transmitting anyway before hopping to the next channel and waiting for the access code again. Without this trick, the code would not reliably jam the connection.</div>
<div>
<br /></div>
<div>
Once the connection was jammed, the board immediately stopped driving the wheels and turned back into a regular skateboard. This is normally not an issue, as the rider would likely coast to a stop before anything bad happened. However, if the rider had been going downhill this attack would also disable the brakes, which could have obvious consequences.</div>
</div>
<h4>
Miscellany</h4>
<div>
One oddity that we noticed is that occasionally the board responds to packets with packets of its own. We haven't decoded the contents of these packets, but it is likely that they contain basic telemetry such as battery level. In the interest of open research, here is a link to a <a href="https://lacklustre.net/bluetooth/ego_sendandreply.wav">sample capture of the board and remote both transmitting on the same channel back-to-back</a>.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/images/ego_sendandreply.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blog.lacklustre.net/images/ego_sendandreply.png" width="143" /></a></div>
<div>
<br /></div>
<div>
<div>
Code for this has been pushed to <a href="https://github.com/greatscottgadgets/ubertooth">Ubertooth master</a> which you can grab from GitHub. Instructions for building and flashing firmware can be found <a href="https://github.com/greatscottgadgets/ubertooth/wiki/Firmware">in the wiki</a>.</div>
<div>
<br /></div>
<div>
If you have an E-GO skateboard and an Ubertooth, give it a try and let me know how it goes!</div>
<div>
<br /></div>
<div>
As always, this was not possible without the help of many people. We would like to thank <a href="https://twitter.com/sharebrained">Jared Boone</a> from <a href="http://www.sharebrained.com/">ShareBrained Technology</a> for his incredible patience assisting us with GNU Radio while he was in the midst of pushing out a product. We would also like to thank <a href="https://twitter.com/cutaway">Don C. Weber</a> for publishing an excellent walkthrough on decoding FSK with GNU Radio as well as <a href="https://twitter.com/michaelossmann">Michael Ossmann</a> for his incredibly awesome <a href="http://greatscottgadgets.com/sdr/">SDR tutorial video</a> series. Finally, thanks to <a href="https://twitter.com/safehex">@safehex</a> for winning the E-GO we used in this research at the <a href="https://www.bsideslv.org/auctions/">BSidesLV charity auction</a>.</div>
</div>
Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com0tag:blogger.com,1999:blog-4056437003022567927.post-88982841517881739322014-03-16T23:13:00.000-07:002016-12-19T20:18:50.408-08:00Remotely Crashing Bluetooth on AndroidAt CanSecWest last week I demonstrated a remote Bluetooth stack crash in Bluedroid, Android's Bluetooth stack since Android 4.3. This post briefly describes the bug.<br />
<br />
For the impatient, you can skip directly to the <a href="http://www.youtube.com/watch?v=MZPjQbaLp5E">video of the crash</a>.<br />
<br />
The vulnerability is in Bluedroid's BLE (Bluetooth Smart) packet parsing code. In order to exercise this vulnerability, an attacker must force a user to connect to a malicious BLE device. Upon connection, the malicious device will issue a malformed GATT notification packet that causes the stack to crash.<br />
<br />
It may sound a bit far-fetched that an attacker could force a user to connect to a device, but consider the fact that many BLE apps for Android opportunistically connect to any advertising device in order to determine if it is the device associated with that app. The app need only connect for this attack to succeed.<br />
<br />
This vulnerability is <i>not</i> exploitable: the crash is caused by a <code>FORTIFY_SOURCE</code> check failure. Additionally, the vulnerability has been fixed since Android 4.4.<br />
<h4>
Show me the code</h4>
The code in question can be found in stack/gatt/gatt_cl.c, in gatt_process_notification (line 614). This is code for parsing notification packets, which are messages that a BLE device can periodically send to a BLE master. On line 626 you see the following code:<br />
<br />
<pre><code>STREAM_TO_UINT16 (value.handle, p);
value.len = len - 2;
memcpy (value.value, p, value.len);
</code></pre>
<br />
<code>value.len</code> is <code>uint16_t</code>. Both <code>p</code> and <code>len</code> are controlled by the attacker, though in this case we're only interested in <code>len</code>. <code>p</code> is the content of the packet sent by the attacker and <code>len</code> is the number of bytes in the packet.<br />
<br />
The code expects a packet with a length of at least two bytes. If an attacker sends a malformed single byte packet, the calculation <code>value.len = len - 2</code> will underflow to 65534. The <code>memcpy</code> will attempt to copy nearly 64k of data from <code>p</code>.<br />
<h4>
Demonstration</h4>
I've made a demonstration video of the <a href="http://www.youtube.com/watch?v=MZPjQbaLp5E">remote Android Bluetooth stack crash</a>.<br />
<br />
I built an attack platform using a modified version of BlueZ, the Linux Bluetooth stack. BlueZ is configured to act as a BLE device running a GATT server. Whenever a BLE master connects to it, it automatically sends a malformed notification packet that is one byte long.<br />
<br />
In the video, I demonstrate the vulnerability using a BLE heart rate monitor app. For the purpose of demonstration, I manually connect the app to the evil BlueZ. The stack crashes when the music stops playing.<br />
<br />
The output of <code>adb logcat</code> contains lines similar to the following:<br />
<br />
<pre><code>
F/libc (19174): FORTIFY_SOURCE: memcpy buffer overflow. Calling abort().
F/libc (19174): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 19956 (BTU)
</code></pre>
<br />
Again I note that this attack is <i>not</i> exploitable due to <code>FORTIFY_SOURCE</code> runtime checks. The code is instrumented at compile time where the length of the target buffer is known. At runtime, the code checks to see if the memcpy length is larger than the target buffer length and if so calls <code>abort()</code>.<br />
<h4>
Timeline</h4>
This is the timeline following discovery of the bug:<br />
<br />
<ul>
<li>2013-09-30: Vulnerability disclosed to Google</li>
<li>2013-10-07: Fix committed</li>
<li>2013-10-30: Android 4.4 r0.9 tagged</li>
<li>2013-10-31: Android 4.4 released with fix</li>
</ul>
<br />
Google did not issue a fix for this on Android 4.3, the rationale being that all users should upgrade to 4.4.<br />
<h4>
More Info</h4>
If you're interested in learning more about BLE active attacks and BLE fuzzing, check out the video of my CanSecWest talk, <a href="http://www.youtube.com/watch?v=dYj6bpDzID0">Outsmarting Bluetooth Smart</a>.Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com1tag:blogger.com,1999:blog-4056437003022567927.post-89211949685369930192014-02-18T09:39:00.000-08:002016-12-19T19:00:11.415-08:00Bluetooth Recon With BlueZBluetooth devices are all around us and a surprising number of them are left discoverable. In this post I describe techniques for finding discoverable Bluetooth devices and listing the services running on them. I will also cover basic BLE (Bluetooth Smart) reconnaissance.<br />
<br />
This tutorial assumes you have a modern Linux system or VM running BlueZ. The commands below should work in BlueZ 4.101 and BlueZ 5.x.<br />
<h4>
Finding Bluetooth Devices</h4>
The most basic way to find local discoverable Bluetooth devices is to use <code>hcitool scan</code>. In the following example, there are two discoverable devices near my laptop: a Nexus 4 and a wireless speaker:<br />
<br />
<pre><code>$ hcitool scan
Scanning ...
98:D6:XX:XX:XX:XX Nexus 4
00:0D:XX:XX:XX:XX Bluetooth Speaker
</code></pre>
<br />
The left column is the device's BD ADDR (Bluetooth Device ADDRess). This address is unique to the device and is very similar to a WiFi or ethernet MAC address. The right column is the device's human-readable name, which the device sent us in response to our scan requests.<br />
<br />
To get a little more information about a device, we can use <code>hcitool inq</code>, another subcommand of <code>hcitool</code>:<br />
<br />
<pre><code>$ hcitool inq
Inquiring ...
98:D6:XX:XX:XX:XX clock offset: 0x0000 class: 0x5a020c
00:0D:XX:XX:XX:XX clock offset: 0x5a75 class: 0x240404
</code></pre>
<br />
This output again includes the BD ADDR, but this time it also includes the clock offset and class of device. Clock offset is a low-level value that can be ignored. Class of Device (CoD) tells us what type of device we're talking to.<br />
<br />
You can decode CoD using a tool I wrote called <a href="https://github.com/mikeryan/btclassify">btclassify</a>. Running it with the above classes tells us these devices identify as a phone and a wearable headset:<br />
<br />
<pre><code>$ ./btclassify.py 0x5a020c 0x240404
0x5a020c: Phone (Smartphone): Telephony, Object Transfer, Capturing, Networking
0x240404: Audio/Video (Wearable Headset Device): Audio, Rendering</code></pre>
<h4>
Diving Deeper: Services</h4>
Now that we know we have a phone and a headset (which is actually a speaker), we'd like to find out what services they run.<br />
<br />
In Bluetooth service information is available via the Service Discovery Protocol, or SDP. BlueZ ships with <code>sdptool</code> for querying SDP. The <code>browse</code> subcommand is typically the best tool for listing services. It has fairly verbose output, so it's useful to filter it using grep:<br />
<br />
<pre><code>$ sdptool browse 98:D6:XX:XX:XX:XX | grep Service\ Name
Service Name: Headset Gateway
Service Name: Handsfree Gateway
Service Name: AV Remote Control Target
Service Name: Advanced Audio
Service Name: Android Network Access Point
Service Name: Android Network User
Service Name: OBEX Phonebook Access Server
Service Name: OBEX Object Push
</code></pre>
<br />
Given the presence of "Android Network" services, we can conclude that this device is likely an Android smart phone. The other services are relatively typical for a phone. For instance, Headset and Handsfree are used with headsets and car audio systems, and the OBEX services are used for transferring contacts and sharing files.<br />
<br />
Unfortunately when we try to run <code>sdptool browse</code> against the speaker, we do not receive any records. Instead we can use the <code>records</code> subcommand to receive these records. This command runs for 20 seconds before terminating, so don't worry if it appears to have hung:<br />
<code></code><br />
<pre><code>$ sdptool records 00:0D:XX:XX:XX:XX
Service RecHandle: 0x10001
Service Class ID List:
"Audio Sink" (0x110b)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 25
"AVDTP" (0x0019)
uint16: 0x102
Profile Descriptor List:
"Advanced Audio" (0x110d)
Version: 0x0102
Service RecHandle: 0x10002
Service Class ID List:
"AV Remote Target" (0x110c)
Protocol Descriptor List:
"L2CAP" (0x0100)
PSM: 23
"AVCTP" (0x0017)
uint16: 0x103
Profile Descriptor List:
"AV Remote" (0x110e)
Version: 0x0103
Service Name: Hands-Free unit
Service RecHandle: 0x10004
Service Class ID List:
"Handsfree" (0x111e)
"Generic Audio" (0x1203)
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 1
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
Profile Descriptor List:
"Handsfree" (0x111e)
Version: 0x0105
</code></pre>
<br />
Pay attention to the values after "Service Class ID List". This tells us the device has "Audio Sink", "AV Remote Target", "Handsfree", and "Generic Audio" services. These services make sense given that we know this is a speaker.<br />
<br />
Both of these commands give a complete breakdown of all lower-level protocols used to implement the services. This information is not typically useful during general reconnaissance, but it can be useful when developing fuzzers.<br />
<br />
One final thing to note is that <code>sdptool</code> works even if a device is not discoverable. If you know a device's BD ADDR you can try to connect to it using <code>sdptool browse</code> or <code>records</code> to find out if it's nearby but undiscoverable.<br />
<h4>
Information Hidden by BlueZ</h4>
Certain devices return a bit more information that BlueZ does not display in <code>hcitool</code> output. You can get at this information using <code>hcidump</code> or BlueZ 5's <code>btmon</code>. Since <code>hcidump</code> works on all recent versions of BlueZ, I will demonstrate its use.<br />
<br />
In one terminal run <code>hcidump</code> and tell it to log to a file:<br />
<br />
<pre><code>$ sudo hcidump -w inquriy.cap
</code></pre>
<br />
In another terminal run <code>hcitool scan</code>:<br />
<br />
<pre><code>$ hcitool inq
Inquiring ...
00:26:XX:XX:XX:XX Richard Gill's MacBook Pro
</code></pre>
<br />
Yowza, we can already see the name of the owner of a nearby laptop. Could be useful for social engineering. This naming convention is fairly common among Mac laptops. Worse, on at least some versions of Mac OS X when you put Bluetooth into discoverable mode it will remain in that mode indefinitely.<br />
<br />
Kill <code>hcidump</code> and load the file it created in Wireshark. Filter the output to just inquiry responses using <code>bthci.evt_code == 0x2f</code>. If the device is friendly, you will see information similar to the following screenshot:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blog.lacklustre.net/inquiry_data_wireshark.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blog.lacklustre.net/inquiry_data_wireshark.png" width="320" /></a></div>
<br />
<br />
Under "Extended Inquiry Response Data" you can see a list of service UUIDs, which will be fairly similar to the output of <code>sdptool</code>. On the right I've highlighted a "manufacturer specific" field. This field helpfully tells us the specific model number of the laptop! This information is also highly useful for social engineering.<br />
<h3>
BLE Recon</h3>
All the of the above applies to classic Bluetooth devices, such as phones, headsets, speakers, and so forth. BLE devices are becoming increasingly common, and they require their own set of tools. Some examples of BLE devices are fitness wristbands, heart rate monitors, smart watches, proximity sensors, and so on.<br />
<h4>
Listing BLE Devices</h4>
The most basic tool to list local BLE devices is <code>hcitool</code>'s subcommand <code>lescan</code>:<br />
<br />
<pre><code>$ hcitool lescan
LE Scan ...
DC:A0:F2:B9:4F:9E (unknown)
DC:A0:F2:B9:4F:9E Flex
00:22:XX:00:XX:XX (unknown)
00:22:XX:00:XX:XX Polar H7 00XXXX
</code></pre>
<br />
I haven't censored the first device because it is using a random address that can vary over time, a BLE security feature that makes tracking devices more difficult.<br />
<br />
Given a bit of a-priori knowledge, we can assume the first device is a FitBit Flex. The second device is a Polar H7 heart rate monitor.<br />
<h4>
Listing BLE Services</h4>
Recent versions of BlueZ ship with <code>gatttool</code> for querying BLE services over GATT. The <code>--primary</code> command line switch connects to the device and asks it for a list of services:<br />
<br />
<pre><code>$ gatttool --primary -b 00:22:XX:00:XX:XX
attr handle = 0x0001, end grp handle = 0x000b uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle = 0x000c, end grp handle = 0x000e uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle = 0x000f, end grp handle = 0x0014 uuid: 0000180d-0000-1000-8000-00805f9b34fb
attr handle = 0x0015, end grp handle = 0x0023 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle = 0x0024, end grp handle = 0x0026 uuid: 0000180f-0000-1000-8000-00805f9b34fb
attr handle = 0x0027, end grp handle = 0xffff uuid: 6217ff49-ac7b-547e-eecf-016a06970ba9
</code></pre>
<br />
The service UUID defines the service. UUIDs of the form <code>000018xx-0000-1000-8000-00805f9b34fb</code> are generally 16-bit services that are assigned by the Bluetooth SIG. Information about these can be found on the <a href="https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx">GATT assigned numbers</a> page.<br />
<br />
Based on the UUIDs, we can see this device has "Generic Access", "Generic Attribute", "Heart Rate", "Device Information", and "Battery" services. The last UUID is a manufacturer-specific UUID. If you see another device with this service, it's likely a Polar H7.<br />
<br />
Given the presence of the "Heart Rate" service we can assume this device is probably a heart rate monitor. The "Device Information Service" is more interesting, and I'll describe some fun tricks with that in the next section.<br />
<br />
One thing to note: if you're trying to connect to a device using a random address, such as the FitBit Flex, you need to add the <code>-t random</code> command line flag. Let's list the services for that device:<br />
<br />
<pre><code>$ gatttool -t random --primary -b DC:A0:F2:B9:4F:9E
attr handle = 0x0001, end grp handle = 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle = 0x0008, end grp handle = 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle = 0x0009, end grp handle = 0x000e uuid: adabfb00-6e7d-4601-bda2-bffaa68956ba
attr handle = 0x000f, end grp handle = 0x0012 uuid: 558dfa00-4fa8-4105-9f02-4eaa93e62980
attr handle = 0x0013, end grp handle = 0x0018 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle = 0x0019, end grp handle = 0xffff uuid: 0000180f-0000-1000-8000-00805f9b34fb
</code></pre>
<br />
This device has many services in common with the heart rate monitor, but there are two additional manufacturer-specific services. Seeing these services on another device indicates you're probably looking at a FitBit Flex.<br />
<br />
Finally, to see a list of all characteristics you can use the <code>--characteristics</code> flag or <code>characteristics</code> command in interactive mode. I will omit its output, since it's generally very long. Once you've found a characteristic you're interested in, you can try reading it using <code>char-read-uuid</code> or <code>char-read-hnd</code>.<br />
<h4>
Sensitive Information in Device Information Service</h4>
The "Device Information Service" is very interesting. From the <a href="https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml">SIG's page</a> about it, we can see there is an optional field called "serial number". Clicking on the link brings us to the <a href="https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.serial_number_string.xml">serial number string characteristic</a>, which is assigned number 0x2a25. Let's use <code>gatttool</code>'s interactive mode to try to read it:<br />
<br />
<pre><code>
$ gatttool -I -b 00:22:XX:00:XX:XX
[ ][00:22:XX:00:XX:XX][LE]> connect
[CON][00:22:XX:00:XX:XX][LE]> char-read-uuid 2a25
[CON][00:22:XX:00:XX:XX][LE]>
handle: 0x001b value: 30 30 30 33 3X 3X 3X 3X 3X 3X 00
</code></pre>
<br />
This value is an ASCII representation of the serial number, which in this case is 0003XXXXXX. This value is likely unique and trackable.<br />
<br />
Let's try that on the FitBit:<br />
<br />
<pre><code> $ gatttool -t random -I -b DC:A0:F2:B9:4F:9E
[ ][DC:A0:F2:B9:4F:9E][LE]> connect
[CON][DC:A0:F2:B9:4F:9E][LE]> char-read-uuid 2a25
[CON][DC:A0:F2:B9:4F:9E][LE]> Read characteristics by UUID failed: No attribute found within the given range
</code></pre>
<br />
Too bad, it doesn't have it. One other interesting UUID to query is the <a href="https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml">manufacturer name</a>:<br />
<br />
<pre><code>[CON][DC:A0:F2:B9:4F:9E][LE]> char-read-uuid 2a29
handle: 0x0015 value: 46 69 74 62 69 74 00 00 00 00 00 00 00 00 00 00 00 00 00
</code></pre>
<br />
Converting this to ASCII gives us "FitBit", as expected.<br />
<h4>
One Last Thing</h4>
Using <code>gatttool</code> is nowhere near as reliable as the above makes it out to be. Connections will fail and drop all the time, even under controlled conditions. Just be patient and things generally work eventually.<br />
<br />
Have fun doing Bluetooth recon!Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com0tag:blogger.com,1999:blog-4056437003022567927.post-19661231856024573952014-01-27T06:15:00.000-08:002016-12-19T19:06:32.989-08:00BLE Fun With Ubertooth: Sniffing Bluetooth Smart and Cracking Its CryptoRecently Omri Iluz wrote about his experiences <a href="http://blog.cyberexplorer.me/2014/01/sniffing-and-decoding-nrf24l01-and.html">capturing BLE very cheaply</a> using an RTL-SDR and an MMDS downconverter. His work is very interesting and is a good way to get starting playing with BLE on the cheap.<br />
<br />
A software defined radio approach is very powerful, and if you're interested in sniffing Bluetooth with SDR you should definitely check out <a href="http://gr-bluetooth.sourceforge.net/">gr-bluetooth</a>. Another interesting approach is to use a narrowband radio as a sniffer, like the one on the <a href="http://ubertooth.sourceforge.net/">Ubertooth</a>.<br />
<br />
I've been researching BLE (also known as Bluetooth Low Energy and Bluetooth Smart) since 2012, and I wanted to share the BLE sniffer I built on the Ubertooth platform. My sniffer is highly robust and can capture data from connections on data channels. I also discovered weaknesses in BLE's security and wrote a tool to decrypt packets under some circumstances.<br />
<br />
The sniffer is turnkey and painless: if you have an Ubertooth you can begin sniffing packets right now by running a single command. Our tools capture to PCAP files that can be loaded into Wireshark for analysis using the BLE plugin that ships with recent development builds of Wireshark.<br />
<br />
My BLE sniffer and Ubertooth itself are 100% open source. The source for the Ubertooth firmware, host tools, and board design can be found on the <a href="https://github.com/greatscottgadgets/ubertooth">Ubertooth Github</a>.<br />
<h4>
Technical Details</h4>
Ubertooth is an open source platform for Bluetooth research. It has a powerful ARM microcontroller connected to a reconfigurable radio chip, the TI CC2400. Although it was originally built to monitor classic Basic Rate (BR) Bluetooth, it serves as an excellent platform for building a BLE sniffer.<br />
<br />
At the physical layer, our BLE sniffer works by configuring the CC2400's modulation parameters to match those of BLE. We also program the radio to search for a 32 bit value known as the Access Address that is at the beginning of every packet. When a nearby BLE device transmits, our radio sees the 32 bit Access Address and begins sending data to the ARM microcontroller.<br />
<br />
Before we can read the data, we have to dewhiten it. This is done by XOR'ing the data with the output of a 7 bit LFSR. Our implementation dewhitens 32 bits at a time thanks to an impressive algorithm by Dominic Spill and Michael Ossmann. After this we parse the header and validate the CRC. Valid packets are passed up to the PC via USB where they are displayed and logged to PCAP files.<br />
<h4>
Timing Is Everything</h4>
Almost everything above happens on the Ubertooth dongle itself, and the PC just acts as a logging platform. This was a deliberate design choice made to satisfy one key requirement: timing.<br />
<br />
In BLE, timing is everything. During connections devices hop to different channels relatively frequently, on the order of milliseconds. In this time we must receive the data, dewhiten it, parse the header, and make a decision about hopping very quickly. Sending the data to the PC and waiting for it to send a decision back would take too long for all but the slowest connections. USB latency alone is measured in milliseconds.<br />
<br />
Additionally, on advertising channels and during connections two devices will transmit very quickly in sequence. First one device will transmit, and then 150 microseconds later the other will transmit. If we're busy analyzing the data from the first transmission, we may miss the second one altogether! This type of latency would be impossible to achieve over USB.<br />
<h4>
Following Connections</h4>
Following connections is where everything comes together. Advertising packets are sent on three channels in no particular order and can be captured easily. Connections hop along a sequence of 37 data channels very quickly, spending between 7.5 ms and 4 seconds on a given channel. If we wish to capture data from a BLE connection, we must hop along with the master and slave and listen for their packets on each data channel.<br />
<br />
First we must sniff a CONNECT_REQ packet, which is transmitted by a BLE master device on an advertising channel. This packet initiates a connection between two devices and contains all the connection-specific details, such as Access Address, how frequently to hop, and in what order to visit data channels.<br />
<br />
Once we have the details from the CONNECT_REQ packet, we have everything we need to follow along with the master and slave as they hop among the data channels. We hop to data channel 0 and wait for the first transmission. First the master transmits and then 150 microseconds later the slave transmits. We minimally process these packets and send them along to the PC. Then we hop to the next channel in the sequence and wait for the next packets. This continues until the master or slave closes the connection.<br />
<br />
BLE conections are actually quite simple, significantly moreso than the hop pattern of BR Bluetooth. The only difficulty is meeting timing requirements, which we can do easily since all our processing occurs on the ARM microcontroller.<br />
<h4>
Promiscuous Capture</h4>
Our Ubertooth BLE sniffer also includes support for capturing data from connections that are already active at the time of sniffing. This feature, called promiscuous mode, is not supported by any other inexpensive commercial or open source sniffer. The only other tool I know of with support for this costs over US$ 20,000.<br />
<br />
Due to the nature of BLE, without observing a CONNECT_REQ packet it is extremely difficult to recover all the parameters needed to successfully follow connections as they hop among the data channels. Hop timing, channel ordering, and even CRC calculation elude us.<br />
<br />
I developed a few clever tricks to recover these key parameters using Ubertooth. Once we've recovered them, we feed them back into the normal connection following code and can actually begin following these active connections. For more details on how we recover the parameters, refer to my <a href="https://lacklustre.net/bluetooth/Ryan_Bluetooth_Low_Energy_USENIX_WOOT.pdf">USENIX WOOT whitepaper</a>.<br />
<br />
Disclaimer: This mode is a little touchy: recovering the parameters can be tricky and we don't filter false positives well. However, once the parameters have been recovered, connection following is just as robust as if the CONNECT_REQ packet had been observed.<br />
<h4>
Cracking Encryption</h4>
In early 2013 I discovered that BLE's encryption has a fatal flaw. I wrote a tool called <a href="https://github.com/mikeryan/crackle/">crackle</a> to automatically exploit this flaw and decrypt encrypted BLE data.<br />
<br />
An attacker present during pairing can recover the encryption keys used to protect data during connections. Furthermore, since these encryption keys are reused, this attacker can decrypt every future conversation between the master and slave devices.<br />
<br />
This attack is completely passive. The attacker simply has to capture the packets sent by the pairing devices using a tool such as Ubertooth. No packets are ever transmitted by the attacker, and the victims will have no knowledge that they are being eavesdropped on.<br />
<br />
If you give crackle a PCAP file that contains the pairing data, it will automatically crack the encryption key and decrypt any further data sent during the connection. If you give it a key and a PCAP file filled with encrypted data, it will decrypt the data.<br />
<br />
Obviously this is a huge weakness in BLE and severely weakens the security of the system. I was surprised that, although this weakness has been public for a while, the latest version of the Bluetooth Core Specification (version 4.1, published in December 2013) does not address it.<br />
<h4>
More Info</h4>
I've intentionally left out a lot of details since this blog post is already long-winded enough as-is. If you're interested in more depth, you can do any of the following:<br />
<br />
<ul>
<li>Check out my <a href="https://www.usenix.org/conference/woot13/workshop-program/presentation/ryan">USENIX talk</a> and <a href="https://lacklustre.net/bluetooth/Ryan_Bluetooth_Low_Energy_USENIX_WOOT.pdf">white paper</a></li>
<li>Watch my earlier, <a href="https://lacklustre.net/bluetooth/">related talks</a></li>
<li>Send me an email: mike at ice9.us</li>
<li>Tweet me <a href="https://twitter.com/mpeg4codec">@mpeg4codec</a></li>
<li>Drop into #ubertooth on freenode and say hello!</li>
</ul>
<br />
Ubertooth can be purchased from several places, the full list is available on the <a href="http://greatscottgadgets.com/ubertoothone/">Great Scott Gadgets web site</a>, though I always get mine from <a href="http://hackerwarehouse.com/product/ubertooth-one/">Hacker Warehouse</a>.<br />
<br />
Finally I would like to express thanks to the many people who helped make this work possible, but in particular:<br />
<br />
<ul>
<li>Michael Ossmann (<a href="https://twitter.com/michaelossmann">@michaelossmann</a>) for creating the Ubertooth</li>
<li>Dominic Spill (<a href="https://twitter.com/dominicgs">@dominicgs</a>), the current Ubertooth maintainer</li>
<li>Michal Labedzki, for getting my BLE Wireshark plugin into Wireshark</li>
</ul>
Mike Ryanhttp://www.blogger.com/profile/04674329136748832217noreply@blogger.com1