🧙🖳✨

318 Followers
35 Following
32 Posts
trying this whole academia thing | they/them

alright, wrapping this up: what have we learned?

- the pairing has improved and enforces physical presence now!
- we have dynamic keys!
- cryptography remains very difficult 🙃
- maybe the ECDSA keys will do something in a future update?
- talking to vendors helps! getting publicity helps!

also, what i'm seeing here looks a little similar to what i described in a somewhat exasperated mail to Xplora in November, although with a certain came-back-wrong vibe to it

10/10, thanks for joining ✨

... this shiny new function is apparently only ever used to encrypt the S/N and IMEI values from above, using the random string from step 3 as a key. which then, of course, is sent in the same request as the encrypted value?? they're essentially sending key || AES-GCM(SHA256(key), data), which is a cool way to spend ~76 bytes doing a cryptographic NOP

a similar thing applies to the ECDSA signatures: yes, they're proving ownership of the public key by including a signature over some values, but from what i can tell, this key is never used again?

we're generating expensive elliptic curve points, enrolling them into the AndroidKeyStore, serializing the public key into base64, generating a signature to prove to the server that we control the private key — and then we just pour it all down the drain?

to be clear: i don't think this is exploitable, which is why i'm talking about it here. simplifying these NOPs still yields a secure-ish looking protocol. but still 😳
9/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

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

aha! the INIT_SECRET and INIT_KEY values come from the Config class, where they are set by a RegisterManager during, presumably, device registration.
let's actually see what that looks like to the user before we dig through more code
5/x
the bread-and-butter authentication logic seems to be unchanged! they're still using the same encryptIMEI and encryptSignature functions to generate auth headers. with the static keys gone, key material has to come from somewhere though..
4/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 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

Do you know where your child is?
Are you sure?

Come join me explore the security of children's smartwatches (including evil witches, clothespins, and the secret to teleportation)
Tomorrow / Monday at #39c3 and online, 13:50 Hall Zero.

seemoo.de/s/c3-xplora

So someone anonymously sent me an Apple Watch. Guess I have a reputation 🙃

#39c3