So my journey with these earbuds started after I saw them on this Mrwhosetheboss video about pointless tech. This device seems to be also popular on TikTok. My suspicions were confirmed, this runs android. So of course i went ahead and bought them.
245 euros later... and they finally arrived!
Before we dive further into this, unlike with rabbit, this issue has been properly reported and patched. This is also my first real blog post/disclosure so feedback is appreciated.
Small overview
I like how they strapped a USB-c cable to the outside of the box while there is also a smaller one inside the box. They ran out of box space it seems...
I also wonder if they are legally allowed to use this OpenAI logo (probably not lol)
Anyways, we aren't here for fancy boxes, lets get to the main point. The device itself boots up to a screen with the time and ChatGPT front and center.
There are some other AI features available too like translations. But this isn't a review of the device, you can watch other YouTube videos about that. The ChatGPT animation looks way too similar to the actual app and OpenAI could probably get them in legal trouble for stealing their brand identity. I will also mention that the audio quality is absolute shit if you use their EQ profiles but can be upped to a usable level by tweaking the EQ curves yourself.
There are also some apps available in the IKKO store, the reason that there is no google play store available is because these apps are modified specifically for the screen on the ActiveBuds, at least, that is what the CEO says about them. We will check that out in a bit. These apps include some music apps like Spotify, but also some gaming apps like, oh god, SUBWAY SURFERS BAYBEEEEE
Of course all of them unbearable to navigate due to the small screen. However we can now confirm that it most definitely runs android.
Time for some hacking
There is sadly no browser available to directly download other apps. And while you can open the native android settings app, clicking the build number 7 times does not enable developer mode. So i couldn't enable adb it seems. Is it locked that well? heh nope.
Let's just plug it into a pc and see what happens....
What the fuck, they left ADB enabled. Well, this makes it a lot easier.
After sideloading the obligatory DOOM, i began checking out how the ChatGPT integration works on the backend. I first started HTTP inspecting the device, however since i couldn't enable the proper system certificates without rooting the device, i couldn't see exactly to what URL it communicated. Fortunately that wasn't really needed.
Holy shit, holy shit, holy shit, it communicates DIRECTLY TO OPENAI. This means that a ChatGPT key must be present on the device!
I know that this device can be rooted to get the proper certificates installed because a tool exists on all Spreadtrum/Unisoc devices which can be used to unlock the bootloader as long as companies use the default signing keys. This was indeed the case here too. However, i couldn't get past the confirmation screen as the device does not have a volume up key to confirm the unlock. I think you are able to sign your own partitions to make it flash them without an unlocked bootloader but that's a bit too advanced for my own liking.
So, i went back to the drawing board and just dumped all of the apps from it with an APK extractor tool. After popping the launcher app into JADX, things immediately became concerning.
The device can communicate to either of these domains.
- api.openai.com
Obvious, the OpenAI API - chat1.chat.iamjoy.cn
Seems to be the API for the entire device, including features not related to ChatGPT like the app store. Loading it up in a browser gives a login page. - chat2.chat.iamjoy.cn
Same thing as chat1, possibly a backup server? - openspeech.bytedance.com
No idea, might be a speech recogniser backup instead of whisper, haven't seen communication to this from the device. - www.airdimple.cn
Seems like an OpenAI API mirror or proxy?
Knowing this i went hunting for api endpoints and keys. I found a file called SecurityStringsAPI which contained encrypted endpoints and authentication keys.
You might think, hey that's just base64 idiot, the most basic encoding known to mankind. And well, yeah, it is.
However, there is a second stage which is handled by a native library which is obfuscated to hell. I am not going to even try to read that. Fortunately i didn't have to. I just sideloaded the app on a different device which was rooted, and well, just like the rabbit apk, it just works!
Inspecting this device:
Yup, that's an OpenAI key.
Now, while having this access, we can also expose their (pretty funny) system prompt.
The device also has another few modes, which are Angry Dan and In-Love Dan. For the angry one you need to confirm you are 18+ because it actually swears a lot.
The system prompts for these are a bit more boring.
I also noticed that it logs the chat to another endpoint on the chat1 domain. This is probably just to keep a log of messages since the ChatGPT API does not allow that. Possibly for some Chinese espionage? Well, possibly but not entirely, we will get to that.
The headers for this request include the message, model, response and the device IMEI as the device id.
I also sideloaded the store app and found out that the apps seem to be mostly ripped straight from apkpure.com
After discovering this information, i sent an email to the security department of IKKObuds.
While waiting for their response i started to investigate their companion app. Wait i forgot to tell you about that? Yeah, these earbuds have a companion app with which you can also directly interface with ChatGPT and see your previous chats from the device. So that's what the logging endpoint is used for! You bind the app by scanning a QR code from the device in the "Membership" menu.
So, let's HTTP inspect this app and check out where it gets this information from.
Alright so it queries this API with your account token and your device id and returns all the chats you have ever had with the device. However, after removing the account token, the request still worked? So this api has no authentication apart from the device id. I feared the worst.
I found a frame in the tutorial video in which the device id wasn't properly blurred and plugged that into the api.
YUP, i now had their entire demo device chat history. And as the IMEI has a certain range, you would be able to figure out the chat history of all customers, which may include sensitive details.
I also added this new discovery to the email chain.
While that email was waiting for a reply i checked if i could fabricate a linking QR code from a known IMEI to bind the device. (The QR code is not the IMEI itself but something encrypted) I found the API endpoint by looking at the same SecurityStringsAPI, which was less secure than i initially thought because the variable names literally expose the encrypted api endpoints (lol)
Plugging in the getBindDevQrCode api in postman, i could fabricate a base64 image of the QR code with any IMEI.
However, using this QR code to try and bind the device to my app resulted in an error, saying that the device has already been bound to someone else. So that has been the only good security implementation up until now.
However, i lied, this is still a security/privacy issue. Why, you may ask? This exposes the username you set when creating the account for the app. However, there is no username field when creating your account. Only first and last name.
I created an account with the first name as "Cheese2" and the second name as "Delight2". Turns out that the username is equal to First name + Last name. When trying to bind that device to an app after it has already been bound to another app, the response includes the name "Cheese2Delight2". Great. Doxed.
So what we can do now is guess IMEI -> generate QR code -> Bind the device if not bound already, or get your full name when the device is already bound. -> Get all your chat history either way if the device is bound or not.
Doxed + Ratio + wait....
There is an unbind_dev endpoint????
Unfortunately that one actually checks account token and does not allow to unbind a random device IMEI. Phew.
Hey, do you remember that logging endpoint that actually sent your chats you made with ChatGPT to their servers? This one?
Yeah, that also only used the device id as authentication, so we can send arbitrary text to the companion app of anyone....
I tried to send some HTML and JS through it to try and exploit the companion app, fortunately they use vue for their app and that has default HTML and JS injection security built in. But we can still send scams or something to any user.
Oh hey a reply to my email!
First of all, from a gmail address? Come on, actually try to have at least some professionalism. Second, OK they are actually doing something about it.
(The YouTube channel mentioned is because i said that i will be making a video about this. I have all the footage for it but i hate my voice with a passion so here we are on this blog post :))
Shortly after this email, they locked down the app and put out an announcement stating that the app will be in maintenance for a week.
They also wanted to become a sponsor of my empty YouTube channel? What?
I don't think that they understood that i would be talking about their horrible security. Anyways.
The API was now non functional and displayed a maintenance message. After the service period they put out both an app update and a device update.
What changed? The endpoint to get the chat history now needs a "signature" header. Which is composed of your account token, your device id, language and the current time encoded with a public/private key + a password.
(oops exposed that)
Anyways, it is now impossible to fetch the chats without having a valid account token. Still doesn't fix the fact that i can generate a QR code with the guessable IMEI and bind the device to an app if it hasn't been bound already. That circumvents this all.
The device update broke the ChatGPT functionality from functioning on a device which is not the IkkoBuds itself. The keys remain on device and have not been rotated. So if anyone is able to figure out the broken app on another device or the key encryption system, you can still get your very own free OpenAI API key.
However i just gave up at this moment, also because they never replied with anything after my last email criticizing them for leaving the keys on device. This is now a month and a half ago.
So, that is it. You can still inject messages into apps of others, link devices that are not already bound to another companion app, thus leaking chat history. And leak first and last names of devices which are bound.
I am giving up, but if anyone else wants this company to fix this, be my guest.
Also if you liked this deep dive, consider supporting me so i will be able to convince myself that buying more strange android devices is worth it lol
https://ko-fi.com/mgdproductions