(tl;dr - If you are using a cheap smart watch, probably don’t. If you want to skip to the juicy bit jump to “Authentication”)

As with most complicated things in my life, it started with a simple question.

Do you know how to get the data off this watch?

Surely there’s an export feature in the app to a common file format like GPX, TCX or FIT. That’s pretty standard. Yet we couldn’t find a way. The only share and export functionality just provided an image with some stats on it.

Also given Android’s lockdown on the file system (to the point that you can no longer backup your phone!) there was no way to access the DB to obtain data (without root anyway).

Investigating the Ryze Android app I quickly discovered that this is a white label of an IDO smart watch.

Screenshot of the IDO and Ryze website showing practically the same watch

Screenshot of the IDO and Ryze website showing the same smart band

It got me thinking - could I pick up one of these watches for a lot cheaper to play with. Eventually I landed on searching Amazon. The hardest part was working out if it was actually an IDO based device. I discovered what worked well was looking for watches that use the “VeryFit” app which is the IDOs stock app. There’s actually a bunch of watches that use this app. I found one for a low price of $39 (AUD) and free next day shipping.

Telegram message : So why did you buy a knockoff apple watch from amazon?
My partner however was a little confused. The watch came in some shiny packaging without mentioning its brand. To be honest I’m pretty impressed with what you can get for $39 these days.

Box with shiny logo that says Smart Watch on my desk

The watch on my wrist

Hilariously I paired my IDO watch with the Ryze app and it just worked fine. I wasn’t actually expecting that to work but it seemed ok with it.

Would I buy one? yes - as a Bluetooth Low Energy reverse engineering example device otherwise no. Onwards to reverse engineering!

To the cloud

The first thing I looked at was syncing data from the cloud. This was pretty easy and basically just required following the same request flow as the phone. It however has some drawbacks, you still need to use the app, and you need to have an account. I didn’t really progress any further with this - but it is a viable way forward with those limitations.

Getting data off watch directly

I’m going to skip past dealing with authentication for the moment as that gets a little spicy and we don’t want to ruin the standard story telling plot framework.

Once connected and authenticated the device presents a bluetooth service at 0AF0 which provides several characteristics. The import ones to us are a subscription to 0AF7 - this is where data from the watch to the phone is sent while 0AF6 allows us to send commands.

adb logcat and BlueSee.app were lifesavers here. The app logs a lot of information about what its doing and how its working. You can pretty much work out everything from using the app with adb logcat running then emulating that flow with BlueSee.app. Also what helps is that the developers seemed to have a scattering of their documentation and source code on GitHub and some of the other vendors shipping these have done the same. Not all the source code is available which would have made reverse engineering just a little bit easier but its a good start.

So we send commands by writing to 0AF6. The easiest first set is 0x0201 which provides some basic device info. The device will write back to 0AF7 with the returned data. For these 0x02.... commands the return data will be structured like:

02 - Header
01 - CMD (get basic info)
.. - Reply data structure (device)
.. -                      (firmware version )
..
..

Data is little endian.

V3 protocol

Getting activity data we need to use the “v3” protocol. These commands have the first byte a 0x33 or “3” in ASCII.

The v3 protocol can have data be split over multiple transmissions - a requirement of using this style BLE. So that the watch and phone can know that a new command has started rather than a continuation there’s a preamble DAADDAAD. This is just an utterly weird design choice given all the other features in BLE that could have been used. There’s then a service selectorish thing, length, command, sequence fields, followed by data and eventually a CRC.

To send a request to get the last activity I use the following command:

0x33 - '3' version protocol
0xDA - this is preamble to detect new command midway through
0xAD - preamble
0xDA - preamble
0xAD - preamble
0x01 - health?
0x10 - length (without '3' and checksum (last two bytes) - aka minus 3 on single packets)
0x00 - length
0x04 - cmd
0x00
0x0B - sequence - can just pick anything
0x01 - sequence
0x00 - start / stop
0x04 - cmd
0x00
0x00
0x00 - checksum
0x00 - checksum

Checksum calculation

I think its just some sort of CRC16 however I’m not sure which because the device I have never checked it so I never bothered working it out.

V3 return data

The return contains much of the same header. You can use the sequence numbers to line things up with you have to handle queueing of data and multiple requests.

Activity data is nearly always split over multiple packets so just read in the subscription until the data received matches the provided length in the header or until you see another preamble.

Then its a matter of unpacking the data. Noting that you’ll have arrays of varying lengths.

You might be thinking that this protocol will be stripped down to save transfer speed, however the protocol sends stuff like pace in several different units.

Online activity downloader

I built a really rough and dirty website for talking to my device and getting the health data off it. You can play around with it at https://sprocketfox.io/ido/. It’s happy path’d for my $39 crappy watch so probably won’t work for most people. It generates a TCX file that can be used on Strava or Garmin.

Screenshot showing an activity being downloaded from the watch

Authentication

When I originally paired the device I scanned a QR code on the watch. Turns out this probably just had the mac address on it or something because after several hours of getting device info and pulling activity data I realised that I had never performed any authentication step. Resetting the app and repairing also revealed that there's no pairing code. Nothing. The device isn't locked or secured once connected. Anyone can connect to the device at any time and start issuing commands.

You can pull activity data, sleep data, heart rate data, menstrual data. You can perform firmware updates. I don’t have GPS in my version of the watch but I bet you can access that as well. Whatever you want you can get it - there’s no protection. I can only test with my watch, but I suspect this applies to most devices that have been white labeled.

The watch I bought off Amazon has 5000+ ratings and the VeryFit app has over 5 million downloads. There’s 10k Ryze Connect app downloads according to Google Play. From what I can tell Cove, BoAT and bfit Move are also using the same app/protocol - I imagine there is a lot more as well. These are sold in retail stores like JB Hifi and Harvey Norman. There’s even kids versions of these watches which adds to a creepyness factor.

I pondered about how to disclose this and decided to go with the “fuck it” approach. The reasoning is that it’s going to be hard to find all the different vendors to let them know and I suspect they won’t care. I just don’t have the time go talk to AI chat bots, lodge support forms, have support people not understand my concern, have multiple generic replies saying “it’s not an issue our vendor said its secure” ect…. Is “JJMJKJ” (yes thats who sells it on Amazon) going to do anything - no. Not a chance. So rather than go through that entire process, get burnt out, and still be left with no actual device security I’m taking the approach of letting people know as soon as possible.

If you’re in Australia you can request a refund as the device isn’t fit for purpose or of acceptable quality.

Git

Details about this can be found at https://github.com/xssfox/idowatch

Unexplored security fun