We haven’t written about smart adult toys in a long time, but the Qiui Cellmate chastity cage was simply too interesting to pass by. We were tipped off about the adult chastity device, designed to lock-up the wearer’s appendage.
There are other male chastity devices available but this is a Bluetooth (BLE) enabled lock and clamp type mechanism with a companion mobile app. The idea is that the wearer can give control of the lock to someone else.
We are not in the business of kink shaming. People should be able to use these devices safely and securely without the risk of sensitive personal data being leaked.
The security of the teledildonics field is interesting in its own right. It’s worth noting that sales of smart adult toys has risen significantly during the recent lockdown.
We discovered that remote attackers could prevent the Bluetooth lock from being opened, permanently locking the user in the device. There is no physical unlock. The tube is locked onto a ring worn around the base of the genitals, making things inaccessible. An angle grinder or other suitable heavy tool would be required to cut the wearer free.
Location, plaintext password and other personal data was also leaked, without need for authentication, by the API.
We had particular problems during the disclosure process, as we would usually ask the vendor to take down a leaky API whilst remediation was being implemented. However, anyone currently using the device when the API was taken offline would also be permanently locked in!
As you will see in the disclosure timeline at the bottom of this post, some issues were remediated but others were not, and the vendor simply stopped replying to us, journalists, and retailers. Given the trivial nature of finding some of these issues, and that the company is working on another device that poses even greater potential physical harm (an “internal” chastity device), we have felt compelled to publish these findings at this point.
We have redacted significant details here.
We found a serious privacy vulnerability very quickly with the mobile app: all API endpoints were unauthenticated using only a long-ish “memberCode” to make requests. The memberCode itself is somewhat deterministic and is based on the date a user signed up for the service, however we found an even easier way using a shorter “friend code”.
A request with this six digit “friend” code returned a huge amount of information about that user, including very sensitive information such as their name, phone number, birthday, the exact co-ordinates where the app was opened, their longer “memberCode” value, and the user’s plaintext password (not that we need it).
It wouldn’t take an attacker more than a couple of days to exfiltrate the entire user database and use it for blackmail or phishing.
We were able to sample a few IDs at random, showing user locations at the time of app registrations. Bear in mind this is just a small subset of users from the available data. We threw away any personal information immediately.
Now we have the longer memberCode we can fetch all the devices associated with that person:
GET /list?memberCode=20200409xxxxxxxx HTTP/1.1 Host: qiuitoy.com Connection: close "deviceId": 0, "deviceCode": "201909xxxxxxxxxx", "deviceName": "Cellmatexxxx", "deviceNick": "Cellmatexxxx", "deviceNumber": "QIUIxxxxxxxxx", "deviceType": 2, "deviceBlue": null, "deviceBlueAddr": "F9:34:02:XX:XX:XX", "isEncrypt": 1,
And once we have that, we can work out what permissions that person has over that lock (so can they unlock it themselves or have to ask someone else):
GET /wear?memberCode=20200409xxxxxxx&deviceCode=20191204xxxxxx HTTP/1.1 Host: qiuitoy.com
And if they can, we can flip that so they’re now locked out of the device:
POST /binding HTTP/1.1 Host: qiuitoy.com Connection: close memberName=Pwned&memberCode=20200409xxxxxx&deviceCode=20191204xxxxxx
And we can do that to everyone, very quickly, locking everyone in, or out. There is no emergency override function either, so if you’re locked in there’s no way out. This may or may not be considered a feature!
The BLE implementation itself requires an API request to generate an unlock command based on a token previously written to the lock. It’s possible we could analyse the requests and responses to generate the right key, or reverse engineer the lock hardware itself…
The above is taken from the decompiled Android app and by hooking it with Frida we can see the notifies (36f6) and writes (36f5) associated with checking the battery level first and then the unlock (the third write):
[+] BluetoothGattCallback constructor called from com.apicloud.uzble.AndroidBle$2 [BLE Write =>] UUID: 000036f5-0000-1000-8000-00805f9b34fb data: 0x56f3430769ddd6e1603xxx [BLE Notify <=] UUID: 000036f6-0000-1000-8000-00805f9b34fb data: 0xe01012b3074d111c98bxxx [BLE Write =>] UUID: 000036f5-0000-1000-8000-00805f9b34fb data: 0x25f8a92325fd9cfc7ea79xxx [BLE Notify <=] UUID: 000036f6-0000-1000-8000-00805f9b34fb data: 0x2717dd996ab4a017a6ceexxx [BLE Write =>] UUID: 000036f5-0000-1000-8000-00805f9b34fb data: 0x9ee90373a2d3f156b3557xxx [BLE Notify <=] UUID: 000036f6-0000-1000-8000-00805f9b34fb data: 0xbcdaea06fa1cb94f3f1c2596xxx [BLE Write =>] UUID: 000036f5-0000-1000-8000-00805f9b34fb data: 0x9ee90373a2d3f156b3557d52xxxx [BLE Notify <=] UUID: 000036f6-0000-1000-8000-00805f9b34fb data: 0xc04dab04c54c818d808a78c79adef839
But wait, that hex from the Android app, and the BLE characteristics look awfully familiar. It’s exactly the same implementation as the Nokelock we looked at, except the advertised device name is “OKGSS101”.
The per lock AES encryption key is returned in the API call listing the devices we made earlier. Mass unlocking over BLE anyone?
If you find yourself locked in, you’re probably wondering how you can get out without heavy tools or a visit to the emergency room…
The design of the locking pin uses a motor to withdraw it and is unfortunately not ferrous, so no easy use of magnets, nor is “bumping” it open (as you’ll be wearing it). I had a little success with a shim made from a cut-up can, but the idea of sharp pointy metal near anything important isn’t ideal.
The “better” alternative is to prise open the circuit board area where the front button and light is:
It’s glued-in but came out without much effort or damage. 3 volts (two AA batteries) applied to the white and yellow wires is enough to drive the unlock motor directly (white = negative, yellow = positive), a technique known as “spiking”.
Your local emergency department will probably have the right tools to cut though the metal safely though and would be your better first port of call!
For a realistic threat, the risk of personal data leakage seems more likely to be exploited and give reward to an attacker.
A number of countries have oppressive laws that may expose users of these types of devices to unwarranted interest from law enforcement and bigots.
Further, users are likely to want to keep their private lives private. They should expect privacy by default and security by design. If one wants to share very private information, then that should be by explicit intent of the user.
Many adult toy vendors have shown almost complete disregard for privacy and security over recent years. Fortunately, projects such as the Internet of Dongs have helped guide many towards improved security. Clearly Qiui hadn’t got the message.
Disclosure wasn’t as seamless as we might have initially hoped:
April 20th 2020: we messaged them asking who to report the issue to. They replied very quickly. Cool!
No problem, so we tried again without PGP:
So we sent them the details. Silence reigned.
May 26th 2020: we pushed a little harder, they responded, stating that they would fix by 6th June.
11/06/2020: an updated version was deployed to the App & Play Stores. This mostly resolved issues with requests now being forced to authenticate. Older API endpoints were left up though, and new APIs still returned exact user locations.
June 17th 2020: we sent a message detailing the residual problems, with no response.
June 25th 2020: we reached out again, via a journalist, Qiui said they didn’t want to fix (or couldn’t) as they “only” had $50,000.
June 30th 2020: we sent a follow up email (and twitter DM) with potential fixes to the remaining problems (and had it translated into Chinese just in case), with no response.
July 10th 2020: we contacted two UK retailers of the device to make them aware of the issues. One withdrew it from sale, and made contact with the EU-based wholesalers. Qiui responded back to the retailers that the remaining issues would be fixed “in August”.
September 11th 2020: RenderMan from @InternetOfDongs got in touch with us too: he had helped another researcher through the disclosure process with Qiui. @MikeTsenatek had found a password reset issue independently and was also struggling to get heard by the vendor. By chance he noticed a tweet of mine some time ago, figured that we might be looking at this device and reached out.
We had a great call together where we exchanged remarkably similar experiences of interactions with Qiui! His write-up is available here.
This reinforced our decision to publish: clearly others were likely to find these issues independent of us, so the public interest case was made in our minds.
RenderMan definitely deserves kudos for his continued efforts to broker conversations between researchers and vendors in the adult toy arena. Some vendors have made significant improvements to their product security and privacy as a result of his hard work.
October 4th 2020: We were contacted by a third researcher with similar concerns.
October 6th 2020: We published in coordination with the other parties.