

Back in June last yearโat WWDCโApple quietly announced iBeacon. It didn’t even get a mention in the keynote, appearing in just a single slide aboutย “โฆsome other features in the SDK.”ย But for hardware people it was actually one of the most prominent features of Apple’s latest OS release, and my Twitter feed exploded. People are always looking for new levers to enable them to do new things.
I’m not really going to talk here about theโinteresting and somewhat tellingโsplit between Google, which initially relied on NFC technology and only recently have grudginglyย added Bluetooth LE supportย to Android, and Apple, which avoided NFC and concentrated on finding alternatives utilizing both Wi-Fi and Bluetooth LEโfor instance by rolling outย AirDropย as an alternative to Google’s now shuttered Bump file-sharing service. While I think the choice of those competing technologies actually tells us a lot about the two companiesโthat’s another post entirely.
In what could easily be a commodity marketโafter all iBeacon isn’t their technologyโEstimote is viewed as the market leader, and isย being promotedย fairly heavily as one of the handful of partner companiesย on the Nordic booth at CESย next week.
What is iBeacon?
iBeacon is a technology that allows you to add real world context to smart phone applications. Based around Bluetooth LE, part of the new Bluetooth 4.0 standard, it’s a way to provide basic indoor navigation andย iBeacon has been integrated into iOS 7 both inside theย Core Locationย and theย Passkitย frameworks to enable indoor micro-location and geofencing.
However iBeacon isn’t about location, it’s about proximity.ย Your iPhoneโor now even yourย Android phoneโcan now alert applications when you are approaching or leaving a location with an iBeacon. It can also report an estimate of your proximity to the iBeacon, but you should be aware that the closer you are to the beacon, the more accurate the estimate of proximity becomes. The two factors here are signal strength and radio interference. Whilst signal strength is fairly dependable, interference is notโand can change radically with timeโso while you can generally depend on the beacon to alert your app that you’re in its general proximity, I’d be wary of relying on the ranging to much.
Building your own iBeacon
It’s fairly simple to build your own iBeaconโeither using a Raspberry Piย or using a Bluetooth LE board like the Red Bear Labs BLE Mini boardโand there are some people taking advantage of that to turn a quick profit.
For instance Radius Networks is selling a “iBeacon Development Kit” which consists of a Raspberry Pi, a Bluetooth USB dongle, and an 8GB SD Card. Costing around $45 when bought separately at full retail price, they’re selling it bundled together for $100. That’s quite a markup, especially since they won’t be buying the components at retail, with very little added value over buying the parts separately and following fairly simple instructions to build your own.
To be fair, I think Radius is just selling the kit as a sideline to promote their software offering, and they’ve published their work on reverse engineering the iBeacon Bluetooth profile, and maximising iBeacon responsivenessย amongst other things.
The Estimote
The way I’ve heard it, Estimote struck it lucky. There they were, playing around with Bluetooth LE “beacons” that could be used by smart phones for indoor location fixes, without people showing that much interest, and then there was Appleโand the iBeacon, and they ended up with a couple of months head start on the competition. Of course this could be the urban legend editionโor at least a revisionist versionโof their company history, told in bars, conference lobbies, and other places where developer gather. But it does have a certain ring of authenticity to it.
Despite thatโand whatever the true storyโwhen the iBeacon is discussed, most times you’ll hear the phrase “โฆlike the Estimote.” It’s a bit unfair on their competition, and there are competitorsย Roximity,ย TwoCanoes, Sonic Notify,ย Radius Networks, and few others, but I guess those are the breaks.
It’s actually still fairly hard to get your hands on an Estimoteย developer preview kitโas it’s still shipping in limited numbersโbut I managed to get one of the early developer kits back in November last year and, predictably, I took one of the beacons apart.
The first thing you notice is that there is no on/off button, the device is broadcasting all the time, even before getting out of its packaging. It’s shipped live, which could get interesting.
The case is made of soft silicon with a rubberized feel and it is entirely closed so that it’s waterproof.ย I more-or-less had to destroy the enclosure to extract the PCB from it, which also means that changing the batteriesโat least on the models in the preview kitโisn’t going to be possible.ย However it does mean that you can install it outdoors, which is a big plus point for some use cases.
The Estimote is built around the Nordic Semiconductor nRF51822, which explains their presence on the Nordic booth at CES. It’s a nice chip, basically aย 32-bit ARM Cortex M0 CPU with 256KB of flash and 16KB of RAM with a built-inย 2.4GHz radio supporting both Bluetooth LE as well as 2.4GHz operationโwhere the 2.4GHz mode is on air compatible with the nRF24L series products from Nordic.
The beacons are marketed as including both a temperature sensor and an accelerometerโalthough as we’ll see later on neither of these are advertised as part of the GATT, and aren’t accessible data packets, at least at the moment.
I’m assumingโfor nowโthat the temperature sensor they’re talking about is the one built-in to the Nordic ARM itself, and that the accelerometer is the smaller chip (on the left of the picture) labelledย “8237 C3H DEA3H” although I’m going to have to admit I haven’t tracked down the data sheet for this chip so I don’t know for certain.
Estimote are advertising a range of around 230 feet (about 70 meters) for their beacons.ย Howeverย testingย puts the range much less, at somewhere around 130 feet (about 40 meters) out of the box,ย ย with highly variable precision. As far as I can tell you also shouldn’t rely on the proximity measurements at all as, atย least from my own testing, these proximity measurements vary rapidlyโpresumably due to radio interference.
They’re also predicting a battery life ofย up to 2 years. However our beacon arrived at 55 percent charge, and it is now at 33 percent after just a month, so that seems somewhat of an optimistic predictionโand makes that sealed enclosure more of a liability than an asset.
Interestingly all of the Estimote beacons in all of their developer preview kits are shipping with identical UUIDsโthe UUID ย for every beacon is fixedโand they’reย not planning to add the ability to change the UUID any time soon. That means you can’t use them in a production environment the way Apple intended, or at least, not without some modification.
You’re also effectively locked into using their closed source iOS SDKย if you’re using their hardware, as other iBeacon hardware won’t work with their SDK, and if you use the lowest common denominatorโApple’s own Core Location and Passkit frameworksโto talk to a heterogeneous collection of iBeacon hardware, you’re stuck in read-only mode with the Estimote beacons themselves. That could be a real problem in the future, both for end users, and Estimote themselves.
Estimote have now also shipping a closed sourceย Android SDK. However, there doesn’t seem to me to be much advantage in locking yourself into theirย proprietary SDK on Android asโunlike their iOS SDKโthe beacons can’t be configured using it, so you’re stuck with read-only mode in any case. You may as well use one of the generic libraries built for iBeacons on Android,ย and be able to talk to everyone’s hardware, not just Estimote’s.
The beacons themselves then must be configured by a closed source iOS SDK,ย and at least at the moment the Bluetooth LE GATT services and characteristics of the beacons remainโat least officiallyโundocumented.
To be fair to Estimote, Apple haven’tโat least officiallyโpublicly documented the iBeacon specification yet either, although unofficial documentation based around Apple’s own example code has started to appear.ย As well as the hardware then, we should take a closer look at the developer preview beacon’s software and see if we can figure out how they work.
What does the Estimote Beacon advertise?
Using Sandeep‘s noble package for node.js we can look atย what’s advertised by one of the beacons, using the advertisement discovery script included with the package.
An Estimote beaconโpicked at random from our developer preview kitโwith a Bluetooth Address of E7:44:89:31:ED:4E advertises a local name of “Estimote”,ย along with some service and manufacturer data. However it doesn’t seem to be advertise any service UUIDs.
Taking a closer look at the manufacture data then, the data advertised by the beacon was,
4C00 02 15 B9407F30F5F8466EAFF925556B57FE6D ED4E 8931 B6
Breaking this down,
- First two bytes are the Apple Company Identifier (Little Endian) 0x0042.
- The third byteโat least most likelyโspecifies the data type, which is 2.
- The fourth byte specifies the remaining data length, 21 bytes.
- Estimote Beacons have a fixed iBeacon UUID of B9407F30-F5F8-466E-AFF9-25556B57FE6D.
- The next two bytes after the iBeacon UUID are the iBeacon Major (Big Endian), i.e. 0xED4E, 60750.
- The next two bytes after the iBeacon Major are the iBeacon Minor (Big Endian), i.e. 0x8931, 35121.
- The final byte is the measured RSSI at 1 meter away, i.e. 0xB6, -74.
Effectively the Estimote isn’t doing anything special here, this is just standard iBeacon data. Three of the properties create the beacon’s identity. These are:
- UUIDย โ This is a property which is unique to each company, n most use cases the same UUID would be given to all beacons deployed by a company (or group). Estimote is unusual in that they’ve fixed the UUID for allย “their” beacons to be the same.
- Major โ The property that you use to specify a related set of beacons, e.g. all the beacons in one store would share the same Major value.
- Minor โ The property that you useto specify a particular beacon in a location.
We need to look at the service data advertised by the beacon,
0A18 4EED318944E7 B6 4EED 3189
to see anything Estimote specific,
- The first two bytes specify this service data is for a service with UUID 0x180A.
- The next 6 bytes are the Bluetooth Address but in reverse order, E7:44:89:31:ED:4E.
- The next byte, 0xB6 matches the measured RSSI at 1 m away.
- The next 2 bytes, match the iBeacon Major but this time itโs Little Endian.
- The final 2 bytes, match the iBeacon Minor again in Little Endian format.
According to the Bluetooth core specification service data must be prefixed with the 16-bit UUID of the service the data is forโand here for the Estimoteโthe service data is for for a service with UUID ofย 0x180a, which is interesting because as we’ll see later when we look at the GATT, that service doesn’t exist on the device.
GATT services and characteristics
In contrast with “classic”ย Bluetoothโwhere there are a whole range of protocolsโwith Bluetooth LE there is only one protocol at the top and it is GATT (Generic Attribute).ย The actual functionality of a Bluetooth LE device is implemented by means of attributes which can be read, written, or ย enabled for notification/indication, depending on the attribute type.
We can use the Linux gatttool command line programโpart of the BlueZ packageโto manipulate these attributes. Connecting to the beacon with gatttool we get a list of both the services and characteristics.
Putting theย outputย from gatttool into tabular formโwhere readable characteristics were read using the โchar-read-hnd <handle>โ gatttool commandโwe can compare the values we got from the gatttool to what’s shown the Estimote iOS application,
and we’re a lot further forward. Interestingly if, at this point, you try using gatttool‘s “char-write-req <handle> <new value>” command to write to any of the Estimote’s characteristicsโUUID, Minor, Major, Power Level and Advertising Intervalโthe writes return as successful. However subsequentlyย the iBeacon’s broadcasted data does not update accordingly.
Despite this the Estimote SDK lets you update the iBeacon Minor and Majorโalthough not as previously mentioned the UUID of the beaconโsomething is going on here that we need to understand more fully. The SDK is obviously doing something devious under the hood thatย gatttoolย isn’t.
Using the SDK
Yoann Giniย has built a simple tool using the Estimote SDK allowing you to read and edit the Minor and Major numbers for the beacon, called EstimoteEditor.
We’ve forked the projectโand made some changes we’ll talk about laterโso if you go ahead and clone the repo,
git clone https://github.com/sandeepmistry/EstimoteEditor.git cd EstimoteEditor git submodule init git submodule update
and initialize and update the submodules, then open the project in Xcode, you can build and deploy to an Bluetooth LE enabled iPhoneโunfortunately it’s not going to work in the iOS Simulator, it needs to be run on a device.
After you select the discovered beacon the Power Level, Major, Minor and Advertising Interval are all configurableโand the edited values stick, unlike the changes we made from gatttool. So, what’s the SDK doing differently?
Method Swizzling CoreBluetooth
Since Objective-C is aย runtime language it is possible to inspect methods, properties, and variables of classes and objects at runtime, even though they are private and hidden by the SDK, even if you don’t have the source code and only have access to a binary blob.
To do this we use something called method swizzlingโitย allows you to replace the existing implementation of a method with your own at runtime. Predictably ifย used properly, can be a powerful tool. However, used incorrectly, it can cause devastation on a biblical scale.
Sandeep used this technique to see how CoreBluetooth works under the hood on OS X, and then used the results to communicate with the bluedโthe Bluetooth daemon on OS Xโwithout usingย CoreBluetooth in noble, his node.jsย BLE library. Perhaps more scarily Alasdair has used it in production code to intercept various network calls and introduce analytics to collect network performance dataย “in the wild” on the iPhone.
Letโs use a similar technique on iOS to intercept the communication between the Estimote SDK and CoreBluetooth.ย After taking a look at the iOS runtime headersย for CoreBluetooth, the CBXpcConnection class stands out. Here an XPC connection is used by CoreBluetooth to communicate with the Bluetooth daemon.
Letโs swizzle the following methods,
- (void)handleMsg:(int)arg1 args:(id)arg2; - (void)sendMsg:(int)arg1 args:(id)arg2;
which will allow us to see how the Estimote SDK is using CoreBluetoothโwith some interpretation, we see that there isn’t anything special going on here,
- start scanning for devices
- devices discovered
- stop scanning
- connect to the device
- discover devices services and characteristics
- read/write some of the devices characteristics
Things look similar to what we were doing with gatttool, except for the read/writes to the characteristics at handles 45 and 47. We should probably go back to Xcodeย and set breakpoints during characteristic writes and see what the call stacks shows,
This gives us two more methods to swizzle, this time inside the ESTBeacon class,
- (void)pairSensorFirstPart; - (void)pairSensorSecondPart;
Looking at the output it definitely looks like there is a special pairing process going on, so setting break points in the new swizzled methodsโletting us set into the original methodsโdoesn’t help all that much. What’s next?
Running class-dump on the build provides some interesting output. The ETBluetoothMath classย looks especially interesting.
@interface ETBluetoothMath : NSObject { } + (id)stringFromHexString:(id)arg1; + (id)hexStringToBytes:(id)arg1; + (int)giveSignToUnsigned:(unsigned int)arg1; + (unsigned long)Secunit_ModExpWithBase:(unsigned long)arg1 Exp:(unsigned long)arg2 andMod:(unsigned long)arg3; + (unsigned long)randomUInt32; + (unsigned short)randomUInt16; + (id)randomDataWithBytes:(unsigned int)arg1; + (const char *)CBUUIDToString:(id)arg1; + (int)compareCBUUID:(id)arg1 UUID2:(id)arg2; + (id)IntToCBUUID:(unsigned short)arg1; + (unsigned short)CBUUIDToInt:(id)arg1; + (unsigned short)swap:(unsigned short)arg1; + (const char *)UUIDToString:(struct __CFUUID *)arg1; @end
Let’s swizzle the Secunit_ModExpWithBase:Exp:andMod: method and add some logging on the inputs and return values. That will tell us how the characteristic handle 45 is used,
- Generate a random 32-bit unsigned integer.
- Write the following to characteristic at handle 45: 5^(random 32) mod 0xfffffffb (little endian)
- Read characteristic at handle 45 (little endian): (characteristic 45 value)^(random 32) mod 0xfffffffb
Letโs put a breakpoint in swizzledย pairSensorSecondPart method in ESTBeacon, and step into the original. After stepping over a few instructions we see something interesting.
Is that TIโas in Texas Instruments? Going to Google we find not only that it is, but the source codeย for TI_aes.cย is available online. We can grab it, and add it to our project. That’ll let us try adding breakpoints to aes_encrypt and aes_decrypt inside TI_aes.c.ย Surprisingly, these breakpoints actually get hit, which means that we can inspect the data passed into both the encryption and decryption methods.
The AES-128 encryption key is alwaysย 0xff8af261013625c2d810097f20d3050f. Whilst the encryption state is based on the Bluetooth Addressย (E7:44:89:31:ED:4E) and is 0x4eed318944e731ed4ee74489443189ed.
The AES-128 decryption key is based on the last secunit calculated (0x8e450d08) and is 0x080d458e8e450d08088e0d458e08450d. Whilst the decryption state is the result of the encrypt, 0x419a05a457dcceebeed5129e88a81c4e.
The result of the decrypt is written to the characteristic at handle 47, wrapping up the pairing process.
Putting things together
Now we’ve figure out the pairing sequence and aย rough specification of the characteristics. We can create a node.js script that uses noble to discover and connect to the Estimote Beacon. Then we can tryโagainโafter pairing to write to the Major and Minor characteristics. This time with success.
Interesting. The SDK doesn’t allow us to update the UUID, can we do it using this method? It turns out we can. Writing the same value to both the UUID characteristics works, and the iBeacon UUID is updated. We can set the iBeacon UUID to something the Estimote does not expose.
Conclusion
Theย Estimote iOS SDKย is closed source, but by usingย method swizzlingย and theย class-dumpย utility on it and the CoreBluetooth framework we were able to find out how it interacts with the beacon.
The information contained in the SDK is probably more revealing than the authors expected it to be, and unfortunately for them, there’s very little they can do about that.
Whilst the Estimote developer preview kit and SDK are still in their early stages if Estimote sticks with their currently security modelโalthoughย there are signs that they might notย do thatโanyone who creates an application using their SDK will be able to reconfigure any Estimote Beacon in the wild.
The implications of that are fairly far reaching. If someone maliciously changes the iBeacon Major or Minor characteristic of a beacon, any consumer application configured to use that particular beacon will stop workingโthe beacons must be configured with a pre-defined identity to trigger the correct behaviour inside the consumer’s own application when their smart phone comes into proximity of the beacon.
Beyond that you could configure aย “fake” beacon to act as an impostor of another beacon belonging to a retail chain, potentially gaining access to promotions, gift cards and other location dependant goodies tied to the beacon you’re impersonating.
Other manufacturers use differentโand possibly more secureโmethods to set the UUID, Minor, and Major values of the beacon. Personally, I’d want to take a serious look at those alternatives before deploying this technology in production environments. Especially if there was real money involved.
Whilst it’s not trivial to reverse engineer the software and hardware used in devices like the Estimote, it’s entirely doable andโafter understanding how the beacons workโwe were able to easily modify the beacon configuration.
Update:ย We talked about both of the ability to configureย “fake”ย beacons, and the ability to disable beacons in the field,ย however we didn’t think we’d see something like this quite this soon. This yearโsย Consumer Electronics Showย (CES) featured a promotional scavenger hunt based around Appleโs iBeacon technologyโand it turned out that you could win the hunt, without ever having to go to CES.
ADVERTISEMENT