The Xplora children's watch in my lab finally got the promised update! You know what that means...
Let's see what we can find in a casual reversing afternoon ✨
1/x
The Xplora children's watch in my lab finally got the promised update! You know what that means...
Let's see what we can find in a casual reversing afternoon ✨
1/x
with adb enabled, we can pull firmware just like we did before and throw the results into JADX. we know that all the authentication stuff is implemented in the XPCommonService app, so let's look there first. first impressions:
- static secrets are gone! great!
- promising strings: ECDSA, AES-GCM, AndroidKeyStore
- new crypto library import with cute dragon mascot
3/x
the watch is still paired using a QR code, but it looks a little different and no longer contains the device IMEI but what looks like a 6-byte random value (good!)
previously, just scanning the code was enough, but now users have to enter a 6-digit code on the watch to confirm the pairing. i'm not sure if that additional interaction actually adds security (scanning a code containing unpredictable (!) data should already be enough to establish physical presence), but it certainly doesn't hurt.
with that, attackers can no longer activate arbitrary watches from a distance. small wins! yay ✨
6/x
...okay, i *think* this is still in the realms where i can just post about it, so strap in 🧚🏻
(disclaimer: this is all at a glance, i may well be wrong about something)
high-level, the process to get credentials from the server looks like this:
1. send our encrypted* S/N to the server to get a QR code with a random identifier (as seen in #6)
2. user scans code, gets 6-digit pin from server, enters it on the watch
3. we build a request containing a random string, our encrypted* S/N and IMEI, the 6-digit pin, a timestamp, our ECDSA public key, and a matching ECDSA signature*
4. the server validates this request somehow, and sends us INIT_SECRET and INIT_KEY values in response
7/x
now, when i say 'encrypted', i'm referring to this new function here (code simplified by me).
it does AES-GCM, and it's the best cryptographic code i've seen from Xplora so far! sure, it calls the key a nonce for some reason, but it does authenticated encryption, hashes the key string before use (doesn't even use md5!), and uses a securely random IV every single time! 🤯
however...
8/x