Last month Rob and I found a vulnerability in the Pebble app ecosystem which enabled us to access a target application’s sandbox. Essentially the flaw enables a malicious application to read the flash storage and access the JavaScript instance of the target app once the malicious app is opened.

The Vulnerability

The application exploits a vulnerability in the way that the UUID of an application is stored. When a PBW container is built, the app’s info (including the UUID) is stored in the file appinfo.json located in the root of the PBW. However, some of the app’s info is also written as headers into the individual app binaries (each in the aplite, basalt, chalk binaries). By modifying the value of the UUID written to the header of the binaries in the malicious app to match the target app’s UUID we are able to trick the watch into thinking the target app is being loaded when in reality the malicious app is being loaded.

Building a POC

Building the proof of concept for this vulnerability was pretty straightforward. To start we built a simple application which would read a numeric value saved in flash storage and print it out as text on the screen. The application would also use the javascript instance to log a phrase which is unique to the target application. Finally this target application would be built & installed on the watch, with the UUID of the application being recorded.

The next part was to initialize a new pebble app project. Doing so would generate a package.json with a different UUID compared to our target app. The UUID in the malicious app’s package.json would be saved elsewhere then replaced with our target app’s UUID this way during build time our malicious app will be built with the exact same UUID as our target app. Finally the sample malicious application would access the same flash storage key that the target app reads from, only this time when the middle button is pressed the value will be incremented.

The next step is to build the malicious app. Since the malicious app is being built with the same UUID as our target app, that is the UUID that will be built into the headers of the aplite, basalt and chalk binary files. The final step is to extract the appinfo.json from the malicious app, modify the UUID to be the UUID which was generated when the malicious project was created, and then repack the pbw container.

Video Demo

Potential Impact / Interesting Ideas

What made this vulnerability have a higher impact was the fact that the malicious application could be uploaded to the app store. When uploading a pbw to the app store the validator used to only check the appinfo.json to see if another app with that value already existed. The appstore never validated that the binary headers actually matched the appinfo.json values. Thus a malicious application could be uploaded to the appstore with the intent to cause harm, for example an application could be created to spoof the Uber app and request an Uber without the user’s knowledge.

There are actually some practical uses to this too, although the bad does outweigh the good in this case. Rob had the idea that you could create a watchface which reads values from flash storage for color preferences etc… Then you could create a watch app which would spoof the face’s UUID and be able to update those preference values. This way a watchface’s setting could be changed without needing to have access to the phone.

The issue is now resolved and the appstore does more rigorous checking when uploading an application, to ensure that the UUID is not being spoofed.

Reward

For finding this vulnerability Pebble awarded us with a $500 bounty along with our names being put on their whitehat hall of fame page.

Timeline