Multiple Critical Vulnerabilities Identified in an Indian Carpool Service Provider!

Soham Bakore
7 min readFeb 21, 2020

Hi everyone, hope you are doing well. Today I will share few of my recent critical findings regarding one of the famous and rapidly growing carpool service providers in India. Some of these vulnerabilities include withdrawing money from any user’s account without their interaction, cancelling other user’s posted rides, OTP bypass etc.

Hope this helps other security researchers/penetration testers as well, that being said let’s get started.

Let’s get started

Introduction

For privacy reasons let’s name the application in consideration “Carpool”.

You should always understand the functionalities before testing any application be it web app, mobile app or any kind of assessment you are doing. As I was already using the application, I knew enough about the functionalities of the application.

The application was having SSL pinning enabled. You can know more about SSL pinning here. There are multiple ways to bypass SSL pinning, the one which I used was using frida utilities. You can learn about SSL pinning bypassing techniques here.

Vulnerabilities

1. Withdrawing money from any users account without any user interaction at all!

Well this was the most critical vulnerability I have found in this application because the impact is huge and there is loss of business also.

As the name suggests this vulnerability allowed me to withdraw money/credit balance from any user’s wallet. This vulnerability is actually a chaining of multiple IDOR vulnerabilities affecting different API endpoints of the application.

To chain this vulnerability for maximum impact reconnaissance really helped

Just to brief the vulnerability here is the workflow

[1] In the application, Attacker will post the normal ride request as a DRIVER from one location to another

The API endpoint for creating a ride request is as shown below. Observe carefully that the travellerId of attacker is “CkyBXNNZdk”.

/api/create-ride

{“droppingCity”:”Pune”,”isCacheRequired”:true,”bookingsLeft”:1,”travellerId”:”CkyBXNNZdk”,”boardingCity”:”Pune”,”tarvellerType”:”DRIVER”,”origin”:”new_single”,”bookings”:1,”originLocation”:[73.78046069999999,18.5167],”originAddress”:”XXXX”,”destinationLocation”:[73.889547,18.5518451],”isFavorite”:true,”travelDistanceInMeter”:15453,”destinationAddress”:”XXXX”,”travelDate”:”2019–11–12T19:00:03Z”,”viaAddress”:”XXXX”,”travelName”:”Nov 13, 12:30 AM”,”travelStatus”:”OPEN”}

[2] By using the above API request the attacker will create a ride request on behalf of victim user as a RIDER

This is possible because of a vulnerability known as IDOR (Insecure Direct Object Reference).

The POST request for the same is as shown below. We have changed the travellerId and travellerType value in below request

{“droppingCity”:”Pune”,”isCacheRequired”:true,”bookingsLeft”:1,”travellerId”:”ZDGTG9nd1V”,”boardingCity”:”Pune”,”tarvellerType”:”RIDER”,”origin”:”new_single”,”bookings”:1,”originLocation”:[73.78046069999999,18.5167],”originAddress”:”XXXX”,”destinationLocation”:[73.889547,18.5518451],”isFavorite”:true,”travelDistanceInMeter”:15453,”destinationAddress”:”XXXX”,”travelDate”:”2019–11–12T19:00:03Z”,”viaAddress”:”XXXX”,”travelName”:”Nov 13, 12:30 AM”,”travelStatus”:”OPEN”}

So, now the attacker will see the request from the victim user as a RIDER

[3] The attacker will offer the ride request to victim user

After completion of point number (1) and (2) above, the victim’s ride request will start showing up on the attacker’s app. The attacker will now offer the ride request to the victim user using his app. While doing this, he captures the request and response parameters using burp suite (Proxy tool)

The API endpoint for the same is as shown below:

/api/request/ride

This is a POST request containing the following parameters which gets auto generated when the attacker offers ride request to victim using the app.

{“travellerTravelId”:”wELKkGo337",”travelIds”:{“vTrYlcRXGe”:{“requestType”:”PERFECT”,”displayNumber”:1}},”requestType”:”PERFECT”,”travellerId”:”ZDGTG9nd1V”}

Note the victim’s travellerId is in bold above,it is the same travellerId to which ride request was offered by the attacker in previous steps.

Below is the response to the above request captured via burp. Attacker notes down the requestId as highlighted in bold below.

{“status”:1,”result”:{“requisitions”:[{“requisitionId”:”ZJQRUQ8TDm”,”travellerTravelId”:”wELKkGo337",”matchedTravellerId”:”kaQ7XiY5bC”,”RStatus”:”REQUESTED”}]}}

[4] Attacker will accept the ride request on behalf of victim user

This is possible because of a vulnerability known as IDOR (Insecure Direct Object Reference).

The POST request for the same is as shown below containing following parameters

/api/ride/edit/request

{“origin”:”Home Page”,”travelRequisitionId”:”ZJQRUQ8TDm”,”travellerId”:”ZDGTG9nd1V”,”RStatus”:”APPROVED”}

Using the victim’s travellerId (already available with attacker) and trip’s request id obtained in step (3) above, attacker modifies the above request as highlighted

Attacker then executes the above request using repeater module of burp. Below is the response of the above request.

{“status”:1,”result”:{“requisitionId”:”ZJQRUQ8TDm”,”RStatus”:”APPROVED”,”travellerTravelId”:”wELKkGo337",”matchedTravellerTravelId”:”kaQ7XiY5bC”,”travellerId”:”CkyBXNNZdk”,”matchedTravellerId”:”ZDGTG9nd1V”,”travellerType”:”DRIVER”,”matchedTravellerType”:”RIDER”,””originAddress”:”XXXX”,”destinationAddress”:”XXXX”,”feeMode”:”walletCreditBalance”},”executionTimeInMS”:45}}

As can be seen in the above response, the status is set as APPROVED, So the ride request that was sent by the attacker to victim using the app has now been approved by the attacker himself on behalf of victim user.

[5] Attacker will start the ride

Generally, what happens is when the DRIVER and RIDER have approved each other’s ride request then only DRIVER can start the ride.

But here attacker is able to start the ride without victim user even realizing that he is on a ride! :P

It can be done using following API endpoint:

/api/start-travel

This is a POST request containing following parameters

{“travellerId”:”CkyBXNNZdk”,”travelId”:”wELKkGo337”}

The travelId can be found in the response of step (3) the attacker made in the application

After some time, attacker will stop the ride using below API endpoint:

/api/travel/complete

This is a POST request containing following parameters

{“travellerId”:”CkyBXNNZdk”,”travelId”:”wELKkGo337”}

On receiving a successful response for complete-ride API, money will automatically get deposited to attacker’s wallet and that’s it!!

Victim may be HALF ASLEEP when all the money in his wallet balance may be WIPED OUT by the attacker!! Such is the risk posed by this vulnerability.

Yes! It’s Critical..

Note: This vulnerability has been fixed now.

2. OTP Bypass

OTP is a form of two-factor authentication which is being used more often in every application nowadays. The OTP was SMS-based, so it was sent to the registered mobile number in the application. The API endpoint for sending the OTP request is shown below

/generate/otp

This is a POST request containing following parameters

{“deviceType:androd”,”appVersion”:5.X.X”,”contactNumber”:”XXXXXXXXXX”,”regionCode”:”+91"}

The API endpoint which was being used to verify the OTP is shown below

/authenticate/otp

This is a POST request containing following parameters, I have just shown some of the parameters just for simplicity

{“deviceType”:”android”,”appVersion”:”5.X.X",”contactNumber”:”XXXXXXXXXX ",”OTP”:”1253",”regionCode”:”+91"}

If the OTP is incorrect the response we get from the server is

{“status”:0,”error”:{“errorCode”:9006,”message”:”Invalid OTP”}}

By replacing this response with the correct OTP response we can bypass OTP verification. Even if we put the incorrect OTP we can login to the application bypassing the OTP verification successfully.

The response for the correct OTP is as shown below. I have shown limited length response for understanding purpose

{“status”:1,”result”:{“Verification Token”:”JWT token”,”traveller”:{“contactNumber”:”+91xxxxxxxxxx",”membership”:”SILVER”,”isActiveUser”:true,”segments”:{“PaymentPriority”:”High”},”externalClientId”:”XXXXXXXXXXX”,”deviceType”:”android”,”appVersionCode”:291,”active”:”2019–10–01T06:33:22.000Z”,”isBikePoolEnable”:true,”appVersion”:”5.X>X",”isTrackingEnable”:true,”profileUpdated”:true,”promoCode”:”XXXXXXX",”gender”:”MALE”,”lastName”:”B”,”email”:”x@y.com”,”firstName”:”xxxx”,”mediaSource”:”referral”,”,”travellerId”:”CkyBXNNZdk”,”dialingCode”:”+91",”isPassEnable”:false}}}

By replacing the response I was able to login to the application effectively bypassing the OTP verification phase (Response Tampering)

And it’s bypassed..

3. Fetch other user’s chat messages/history

The application has a feature to message the user with whom you are riding or have requested to share the ride. The API endpoint for the same is given below

/api/fetch/chat/message

This was a POST request containing following parameters

{“fromDate”:”1970–01–01T00:00:00Z”,”toTravellerId”:”CkyBXNNZdk",”fromTravellerId”:”ZDGTG9nd1V",”toDate”:”2020–01–10T18:21:51Z”,”limit”:30}

This vulnerability was possible due to unauthenticated IDOR. The vulnerable parameters were “toTravellerId” and “fromTravellerId”.

By changing the above id’s to any other valid traveller id’s we can get chat messages of those two users :P

Reconnaissance always helps and it surely did in this case to get the travellerIds.

For the simplicity purpose I will show few of these methods

[1] GET request to the API endpoint below

/api/traveller/friends

This gives user’s friendsIdList in the response. We can take travellerIds from this response

[2] POST request to API endpoint below

This is just a request to see matched requests when you have posted a trip request on the application. For simplicity,have not shown the POST body paramters

/api/pairing/list

That being said, simply by changing the toTravellerId and fromTravellerId I was able to fetch chat message histories of different users :P

Simple but critical… :P

4. View completed rides of other users

This vulnerability allowed me to view completed rides of other users along with few other details which were used in further recon process.

In the application there was one section where you can see your completed rides as well as the upcoming rides.

The API endpoint for checking the completed rides is shown below:

/api/completed/rides

This was a POST request containing the following parameters. In this case, the parameter traveller_id was vulnerable to IDOR

{“limit”:10,”traveller_id”:”CkyBXNNZdk”}

By changing the traveller_id to any other valid traveller id’s I was able to see completed rides of other users along with the generated wallet balance of those rides.

5. Fetching wallet transactions of other users

In the application, we can see all the previous transactions done through the API endpoint below

/api/payment/list?skip=0&limit=20

This is a POST request containing following parameters

{“appVersion”:”5.X.X",”skip”:0,”travellerId”:”CkyBXNNZdk",”limit”:20}

As you could have guessed it, by changing the travellerId to any other valid traveller id’s I was able to fetch wallet transactions of any other user.

The parameter travellerId was vulnerable to IDOR

6. Editing / Canceling other user’s upcoming rides

We can see all the rides Completed or Upcoming in my rides section of the application.

The API endpoint for the same is

/api/my-travels/

This is a POST request containing following parameters

{“deviceType”:”android”,”appVersion”:”5.X.X”,”traveller_id”:”CkyBXNNZdk”

By changing the traveller_id to any other user’s travellerid, I was able to see that user’s all rides.This also contained the travelId’s of all the trips of that user including the upcoming rides.

By using the below endpoint attacker can cancel that user’s upcoming rides

/api/cancel-ride

This is a POST request containing following parameters

{“travelId”:”wELKkGo337",”travellerId”:”CkyBXNNZdk”}

By replacing the travelId and travellerId to other user’s trip details, I was able to cancel his/her upcoming rides.

Timeline:

4/10/2019: Reported vulnerabilities to the company

5/10/2019: Got response from the company requesting more details

5/10/2019: Provided all the details for reproduction of vulnerabilities

15/10/2019: Requested for status on reported vulnerabilities

20/10/2019: Got token of appreciation from the company

21/02/2020: Confirmation on fixing the vulnerabilities

That’s it folks. Hope you liked it. Please share it if you do. Keep learning! Keep hacking! Peace.

Thanks for your time!

--

--