As I have been looking into blue tooth low energy and iBeacons for a customer I decided to reverse the application and see if I could "find" all the beacons from the comfort of my seat :)
So what is an iBeacon?
The Apple web site describes them as….
"iBeacon is a new technology that extends Location Services in iOS. Your iOS device can alert apps when you approach or leave a location with an iBeacon. In addition to monitoring location, an app can estimate your proximity to an iBeacon (for example, a display or checkout counter in a retail store). Instead of using latitude and longitude to define the location, iBeacon uses a Bluetooth low energy signal, which iOS devices detect. To learn more about Bluetooth technology, see the official Bluetooth website."
Basically an iBeacon is a BTLE chip that is emitting a UUID, a major location, and a minor location. You end up having something like:
This is broadcast and the iOS application is scanning for the UUID, you can also include the major if this is not likely to change. When they are found by the application it does something, e.g. calculate proximity let the user know they are close by or have just left the area. A better technical write up is available here. Also the Apple developer documentation is available here.
There is a lot of hype starting to surround them and that seems to have gained since CES2014, I guess many of the journalists at the event saw the scavenger hunt. (See links below).
I installed the CES application on my jailbroken iPhone and had a nose around. I used libimobiledevice to start pulling back the syslog to my laptop, you can also do this using the iPhone configuration utility too. I prefer idevicesyslog in libimobiledevice a it doesn’t jump around so much on the terminal when you are looking at the console/log.
When I fired the application up and started the scavenger hunt I noticed what looked like the UUID and some minor numbers:
Now I had these all I needed to find was the Major and I could spoof beacons.
I ssh’d onto the device and located the application, dumped it and decrypted it using clutch. Clutch is a favourite of crackers but also very handy for hackers / pen testers to dump and application to be read in IDApro, hopper, class-dump-z or whatever. I ran strings on the binary, which showed up a few references to beacon and UUID but nothing to concrete. No major found here.
I continued to look around the sub directories of the application and found a few SQLite databases which looked promising, the names of the tables sounded like they would hold the details of iBeacons that were found. I looked inside each of the tables but again, nothing.
I then found a plist that looked like a default preferences file which had some interesting stuff in it and some reference to sh_targets. I assumed this was scavenger hunt targets. The data inside the key sh_target_list was all hex:
I grabbed it and chucked it into a hex 2 ASCII converter available on the internets... Hmm looked a lot like a binary plist.
xxd -r -p ces.hex ces.plist
I could now convert this into xml using plutil
plutil -convert xml1 ces.plist
Now I had a plist I could look at in Xcode or any other text editor. Once opened, it was easy to see the dev had embedded the details of a found beacon inside the plist and also the minor id’s, which matched up with what I had found in the log.
This left me with two options, I keep looking for the major and spoof each beacon or I see if I can set the individual beacons to found = YES in the plist.
After hunting around a little bit longer for the major I decided the quickest route to success would be by trying to set the found key to = YES.
To get everything back into the right order I would need to do the following:
- Edit the plist with the keys ‘found' and ‘i_beacon_minor' in and set the found key to YES
- Use plutil to convert the plist back to binary
- Grab a hex dump of the modified plist and copy hex back into the default preferences plist.
- Convert the default preferences plist back to binary and then copy over to my device and replace the old file.
Set key value to true:
plutil -convert binary ces.plist
I then used hexfiend to dump the hex, I guess I could of used hex dump or xxd but hexfeind forted the hex nicely and didn’t grab the offset when doing cut and paste:
Once pasted into the default preferences post I now had all I needed to win.
I’m not sure what would have happened if I had tried to claim the prize remotely? I’m guessing that they may have had some metrics that could have identified how quickly I found each beacon, making it physically impossible to have visited each beacon individually. However with some further digging I‘m sure I could have found the major ID and spoofed each beacon with a raspberry Pi or another iOS device. Setting some reasonable times between each it could have been believable.... A free 4K UHD curved TV would have been good =D
If you are planning to use iBeacons for prizes or some kind of promotion code then I would suggest you use a web server backend with reasonable protection to stop this kind of hack, it wasn’t that hard and could be done pretty quickly.
If you believe the hype iBeacons have a big future, it will be interesting to see the implementations and how people secure them properly.