Skip to content

Main Navigation

Cyber Security Services – London
  • About Us
  • Services
  • Testimonials
  • Blog
  • Contact

Categories

  • crest
  • Research

Mass Account Takeover in the Yunmai smart scale API

Posted on 30 May 2022 (26 June 2022) by Bogdan Tiron
Mass account takeover in the Yunmai smart scale mobile app

INTRO

Recently, during an internal IoT research project, we did a pentest of the Android and iOS Yunmai smart scale apps.
Below are the 5 vulnerabilities that we discovered, and we chained 3 of these (#2,#3 and #4) to achieve mass account takeover. All vulnerabilities have been responsibly disclosed to Yunmai.

  1. Bypass limit of 16 family members per primary account
  2. UserID Enumeration
  3. Ineffective authorization checks
  4. Information Leak
  5. Account takeover through ‘password reset’ functionality

First, a short description about the Yunmai mobile apps.
The Android one has 500.000+ installs. However, the iOS AppStore does not show the number of downloads as the Google Playstore.
The mobile application allows you to see your weight, a graph with your progress over time, along with 12 other indices such as BMI, body fat percentage, visceral fat, etc. In addition, you can add and delete family members to your account, and each user can add information such as sex, name, age, height, relationship, profile photo.

TLDR: We achieved Mass Account Takeover by chaining 3 vulnerabilities. First we brute-forced userIds, in order to leak puId (primary uid) account values. Then we used the leaked puId values in a Privilege Escalation attack to add ‘family member’ accounts to other registered accounts; in response, we obtained an Information Leak containing the corresponding ‘accessToken’ and ‘refreshToken’ of the newly created ‘family member’ accounts. Thus, we can now use these tokens to impersonate the ‘family member’ accounts, switch between the accounts of the family members and query all their data.

Account types and account structure

There are two types of accounts: parent/primary accounts and family member/child accounts. The primary accounts are all the accounts created through the registration process. On the other hand, the child accounts are all the accounts created by the primary account once logged in. The purpose of the ‘child’ accounts is to have the data of each family member separate if more than 1 person uses the same smart scale.

When a user registers in the app, each user account will contain information such as:
– a userId key having a unique 9 digit value for each user. (ex: ‘userId’: xxxxxx252, as seen below)
– a puId (or primary userId) key having a value of 0. If the puId is 0 it means the userId is also a puId in this case.

Register account response containing account data in the Yunmai smart scale app
Fig 01: Each created account receives a unique 9 digit number as userId

Once logged in in the app with the above registered account you can create ‘child’ accounts for those friends or relatives that will use the scale with you. This will help to keep your measurements data separate. Thus, when you create the ‘child’ accounts, each ‘child’ account, just like the primary account, gets a puId value and a unique 9 digit userId (ex: ‘userId’: xxxxxx253, as seen below). But, the puId value will be equal to the userId of the user who created the ‘child’ account (ex: ‘puId’: xxxxxx252)

Register 'family member' account response containing account data in the Yunmai smart scale app
Fig. 02: Child account created with puId ending in 252 and userId ending in 253

Now let’s take a look at the vulnerabilities one by one.

1. Bypass the limit of 16 family members per primary account

Description:
A primary account can have up to 16 ‘family member’ accounts registered to use the same smart scale. However, this limit is enforced only client-side and not server-side.
If you try to create the 17th family member account from the app, you will receive the below message.

Bypass limit of 16 family members per primary account in the Yunmai smart scale app - photo1
Fig 10: Message shown once you reached the 16 user limit using client-side validation.

However, you can use a previous request to create such an account. Just update the ‘realName’ value of the new account and send it to the server once you reached the 16 accounts limit. Thus, you bypass the client-side validation and the server will happily fulfill the request, as seen below.

Bypass limit of 16 family members per primary account in the Yunmai smart scale app - photo2
Figure 11: Standard create ‘child’ account request used to bypass client-side validation

2. UserID Enumeration

Description:
When you are adding users under your account, the maximum number of members you can add is 16.

At one point, when you reached the limit of 16 registered family members, a request will be issued on Android only. As seen below, this request will contain your 16 userIds values.

UserID Enumeration on the Yunmai Android app- photo1
Fig 20: Vulnerable endpoint used for brute-forcing the ‘ids’ parameter for ‘userIds’ values

Let’s keep from the above request only 1 userId instead of all the 16 userId values. We will brute-force the last 5 digits of the userIds (from the “ids” parameter). Moreover, we will extract from the responses the usernames, as seen below.

UserID Enumeration on the Yunmai Android app - photo2
Fig 21: Brute-forcing last 5 digits of the userId
UserID Enumeration on the Yunmai Android app - photo3
Fig 22: Extracting the realName parameter from the response for each brute-forced userId

This is a great way to extract from the enumerated users:

  • userIDs
  • their names
  • birthday
  • profile photos
  • their sex
  • puIds values

The above request is the 1st one to be used in our chain to achieve Mass Account Takeover.

To recap:
userIds – represents a unique 9 digit value corresponding to each account.
puIds – is the userId of the primary ‘family member’ account. All the userIDs of the family members of one account sit under one puId (primary userId).

3. Ineffective Authorization Checks

Description: The Android and iOS API were discovered to not implement any authorization checks while adding or deleting ‘family member’ accounts to/from other accounts.
Impact: You can add and delete family members to/from other people’s accounts.

Vulnerable instances:

  1. Deleting family members from other people’s accounts
    1. https://intaccount.iyunmai.com/api/android//user/del-user.d
    2. http://intaccount.iyunmai.com/api/ios/user/del-user.d
  2. Adding family members to other people’s accounts
    1. http://intaccount.iyunmai.com/api/ios/user/register-child.d
    2. https://intaccount.iyunmai.com/api/android//user/register-child.d

Instance1: Deleting family members from other people’s accounts

The account supports adding multiple family members in order to switch between them and keep their data, such as weight, BMI, body fat %, etc, separate.

Now that you have the userIds that you want from the previous finding ‘Username enumeration’, you can target one userId belonging to a different account and delete it. All you have to do is update the ‘delUserId‘ parameter with the userId that you want to delete, in the below request. As a result, that userId will be deleted because of the lack of ‘Authorization Checks’ of the API on the ‘delUserId’ parameter. These ‘Authorization checks’ should verify if this to-be-deleted userId is one of my ‘family member’ accounts using my Yunmai smart scale, or not.

Vertical privilege escalation on the Yunmai Android app - photo1
Fig 30: On Android, deleting a userId belonging to a different account by modifying the delUserId parameter with the victim’s userId

Below is the request on the iOS app with the modified delUserId and its successful response:

Vertical privilege escalation on the Yunmai iOS app - photo2
Fig 31: On iOS, deleting a userId belonging to a different account by modifying the delUserId parameter with the victim’s userId

Instance2: Adding family members to other people’s account

All we need to perform this attacks is a victim’s puId value, that we can take from the above ‘Username enumeration’ vulnerability. Once we have that, we can add family members to that account, as seen below. We only need to update the puId value with the victim’s puId.

The below request is the 2nd and last one to be used in the chain to achieve Mass Account Takeover.

Vertical privilege escalation on the Yunmai Android app - photo3
Fig 32: In the Android app, creating a ‘family member’ account called ‘TestAccount’ under victim’s puId (primary id account) by modifying puId with victim’s puId
Vertical privilege escalation on the Yunmai iOS app - photo4
Fig 33: On iOS, the victim’s account with the newly created ‘TestAccount’ family member created in Fig. 32

Adding family members in the iOS application under victim’s puId:

Vertical privilege escalation on the Yunmai iOS app - photo5
Figure 34: On iOS, creating a ‘family member’ account under victim’s puId (primary id account) by modifying puId with victim’s puId

From the above response, we must take notice of 2 important parameters useful for the next finding: ‘accessToken’ and ‘refreshToken’.

4. Information Leak leading to Mass Account Takeover

The mass account takeover chain

As seen in the above screenshot (‘Figure 34’), when we create a ‘family member’ account to other people’s accounts, the server leaks the ‘accessToken’, and the ‘refreshToken’ of the newly created account. As a result, we can impersonate the newly created ‘family member’ account. Then, we can move upwards to impersonate and hijack the primary account. Doing this process in an automated way for every primary account enumerated through chaining this Information leak with the previous 2 findings (UserId Enumeration and Ineffective Authorization Checks), we can achieve Mass Account Takeover.

The impersonation

Now that we have a leaked ‘accessToken’ and ‘refreshToken’ from Fig. 34, we can impersonate the newly created account. Below is an example where we exchanged the leaked ‘refreshToken’ for a new ‘accessToken’. Regarding the ‘userId’ request parameter, there is no need to update it to our ‘MaliciousAccount’ one.

Mass Account Takeover through Information Leak on the Yunmai iOS app - photo1
Fig 40: Using the leaked ‘refreshToken’ to get an ‘accessToken’ for the newly created ‘family member’ account, account which shares the Yunmai scale with our targeted account.

Now we can use the newly ‘accessToken’ from the above response to do authenticated requests, as seen below. Here we query the newly created ‘MaliciousAccount’ account. This account was set up using the default values such as: ‘basisWeight’: 0 ; ‘birthday’: 19970524;

Mass Account Takeover through Information Leak on the Yunmai Android app - photo2
Fig 41: Using the generated ‘accessToken’ to do authenticated requests and query the newly created userId

From the above request, we move ‘laterally’ inside the family account to query the primary account and all its family members. Therefore, we need the above ‘puId’:602619692 value. Below we can see there are 16 userIds (family members) in total under this puId account.

Mass Account Takeover through Information Leak on the Yunmai Android app - photo3
Fig 42: We use the /swatchLogin.json endpoint to switch the accounts from our newly created ‘family member’ userId to our victim’s puId (as ‘targetUserId’ request parameter) and leak victim’s ‘accessToken’

We take note of the above ‘accessToken’ belonging to the primary account and now we query the puId user for extra details.

Mass Account Takeover through Information Leak on the Yunmai Android app - photo4
Fig 43: Query the victim for data

Finally, get all the recordings with information about this victim user. In the below response are a ‘total’ of 2 recordings meaning the victim weighed 2 times.

Mass Account Takeover through Information Leak on the Yunmai Android app - photo5
Fig 44: Getting all the recordings with info about our victim

5 Account takeover through ‘forgot password’ functionality

Description:
The iOS functionality to change your password is not working at all. However, the Android application implements a weak ‘forgot password’ functionality.

The application does NOT invalidate the previously generated ‘forgot password’ tokens, once a user requests a new ‘forgot password’ token. As a result, an attacker can request multiple tokens to be sent to the victim’s email. This will increase attacker’s chances of guessing that code and changing the victim’s password. So the impact of this finding is that someone can take over over any Yunmai’s user account. 

Endpoint: https://intapi.iyunmai.com/api/android/verify/code.d – for generating ‘forgot password’ tokens that are emailed to the victim 

Steps to Reproduce:

  1. Go to the login page in the Android app and select ‘Forgot your password?’.
  2. Write the email of the targeted victim and click ‘Send verification code’. Afterwards, the victim will get an email with a unique 6 digit code that allows to reset the password.


  3. Intercept the above request and send it multiple time, in order to increase your chances of guessing the code. We have retrieved the following list of codes: 172067, 167686, 167921, 164708, 171353, 171316, 163569, 169577,163965, 168449, etc, as seen below.
Account Takeover in the Yunmai smart scale app - photo1
Fig 51: Victim receiving multiple ‘reset password’ codes
  1. Analyzing the codes, we realized we can do a brute force them, as seen below. This is to reset the password of the victim to the one we want. Therefore we chose a brute-force range from 166000 to 169999. The first and only successful code was 166309.
Account Takeover in the Yunmai smart scale app  - photo2
Fig 52: Brute-forcing the verification code, setting the new password to ‘123qwer’ and sorting by Length to find a successful response
  1. And the response to the above request:
Account Takeover in the Yunmai smart scale app - photo3
Fig 53: The successful response to our brute-forced request to reset victim’s password

Responsible Disclosure Timeline:

Sept-Oct 2021: We responsibly disclosed all vulnerabilities to the support team. So the Support team thanked us for our help and forwarded our emails to the dev team. However, we received no response back from the dev. team.

We did multiple retests.

Regarding the finding #5, a silent fix has been made after we reported it. Now all the previously generated ‘forgot password’ tokens are invalidated. Consequently, we did a retest for this finding, however, the codes are in the same range 165k-175k. Thus, you can easily bypass this partial protection and achieve account takeover through forgot password functionality’ by brute-forcing the reset password token.

The finding #2 is still open. Thus, the request on Android to the endpoint /device-users.d used for ‘UserId enumeration’ is still triggered when/after it reaches the 16 users limit.

The finding #3 is still open. So you can still add/delete family members to/from other accounts.

5th of May 2022: we emailed again to the support and dev. teams. We got no response back.

30th of May 2022, 7months after the first emails to Yunmai to report the findings: Blog post published.

References

Privilege Escalation Attack in Concrete CMS
Account Takeover through Password Reset Poisoning vulnerability in Drupal CMS
Account Takeover through Password Reset Poisoning vulnerability and a Stored XSS for Full Compromise in Joomla

About Post Author

Bogdan Tiron

Cloud Application Security Consultant/ Pentester

See author's posts

Posted in ResearchTagged account-takeover, api-pentesting, iot-hacking, mobile-pentesting, smartscale-hacking

Post navigation

 Multiple vulnerabilities in Concrete CMS – part2 (PrivEsc/SSRF/etc)

Would you like to be updated every time we post something cool on our website?
Please subscribe to our newsletter.

FORTBRIDGE footer map

CONTACT US

contact@fortbridge.co.uk

ADDRESS

Brick Kiln Two,
Station Road, London,
SE13 5FR

LINKS

Terms of Use
Privacy Policy
Acceptable use policy
Cookie policy

COMPANY

About us
Services
Testimonials
Contact

RESOURCE CENTER

Blog
RSS

SOCIAL MEDIA

Copyright FORTBRIDGE 2020

Branding and Web development secured by INOVEO

Go to mobile version