Here at Integrity we love to be challenged, so whenever there is some free time, there is encouragement to do research or to break some things (https://labs.integrity.pt/advisories/) in addition to play foosball.
We (@r0t1v, @fjreis, @fabiopirespt) decided to use this time to jump into some bug bounties.
What is a bug bounty?
As stated in wikipedia:
A bug bounty program is a deal offered by many websites and software developers by which individuals can receive recognition and compensation for reporting bugs, especially those pertaining to exploits and vulnerabilities. These programs allow the developers to discover and resolve bugs before the general public is aware of them, preventing incidents of widespread abuse.
For our luck, Uber decided to open their bug bounty program to the public, and in Portugal, Uber was almost a daily issue in the news because of the taxi drivers, so we dove right into this program.
After a couple of hours, we found out two open redirects that we reported right away. This could be the start of something good (we thought), but both issues were already reported by other researchers.
At first it was a bit disappointing, but not giving up we doubled back and decided to implement some processes/methodologies.
The process / Methodology
In order to implement some kind of methodology, we went back to the Uber bug bounty program to check again their scope, which is far extensive as it can be seen below:
- https://*.uberinternal.com/ (added later into the program)
- iPhone Rider Application
- iPhone Partner Application
- Android Rider Application
- Android Partner Application
To gather more information about Uber subdomains we started with a dns brute-force.
Example of subdomains retrieved with sublist3r
With all subdomains enumerated, all that was left to do was to use nmap and check for banners, page titles, page redirects as well as exploit-db and some blogs for known vulnerabilities.
For the mobile apps, jd-gui was used to read the java classes in order to map the mobile endpoints, later we also turned to MobSF.
API endpoints gathered with jd-gui
Now, judging from the information that we gathered, we felt that it was more than enough to start searching for some vulnerabilities.
0×01 – Possibility to brute force promo codes in riders.uber.com
Uber has a feature that allows the usage of promotion codes. This codes can be given by other users or companies. The application riders.uber.com had this feature in the payment page, so after adding a new promotion code we grabbed the request and realised that the application didn’t had any kind of protection against brute-force attacks, which helped us to find many different promotion codes.
Promotions page form – without any promotion code applied
The image below illustrates our brute force attack. As stated before different codes were found and can be distinguished by their response.
- 1951 – Valid code
- 1931 – Not valid
- 1921 – Code Expired
Example of brute-force attack
Uber also gives an option to customize promotion codes, and since all the default codes began with the word “uber”, it was possible to drop the time of the brute force considerably allowing us to find more than 1000 valid codes.
Initially this issue was not considered valid because the promotions codes are supposed to be public and be given by anyone. This was true until finding an $100 ERH (Emergency Ride Home) code which they (uber-sec team) had no knowledge about. This ERH codes work differently from all others since even if a promotion code is already applied this ones can still be added.
Vulnerable form with ERH code applied
March 23, 2016 – Bug reported to Uber
March 23, 2016 – Uber’s team changed status to Informative
March 24, 2016 – We provided new information
March 24, 2016 – Uber’s team changed status to Triaged
April 19, 2016 – Uber’s team changed status to Resolved
May 2, 2016 – Uber rewarded us with a bounty.
0×02 – Possibility to get private email using UUID
As you can see in the picture below, inside Uber riders mobile application there is a “Help” section that allow users to send questions directly to support. Let’s be honest, many of us almost never use the “Help” or even know that it exists, but as pentesters we can’t say no to another form. (later we found that the Partners application had the same forms).
After submitting a question, the server would reply with the message: “We’ve received your request and will be in touch as soon as possible via <my-email-address>”. Looking at this message we thought that maybe we could enumerate some user emails.
Request sending uuid instead of token
By looking at the request there are two places (the x-uber-uuid header and the uuid parameter) that might allow us to get emails from other users if we change them for another valid UUID. We tried to change both, but unfortunately the server returned our email again. Although there is a token parameter also, our first approach was to fuzz a bit into this parameter but in the end we end up by changing it to another user UUID and something magic happened, the webserver returned the email address for that user.
Server replied with email associated to uuid
It’s a bit hard to say why a UUID has been interpreted as a valid token, but it is indeed.
Since the application wasn’t throttling our requests in this endpoint, we grabbed a small amount of UUIDs and with them we were able to get all the emails corresponding to those UUIDs. Now you’re probably asking: “how can you know UUIDs from other users?”, that’s what we will explain later.
March 31, 2016 – Bug reported to Uber
March 31, 2016 – Uber’s team changed status to Triaged
April 11, 2016 – Uber’s team changed status to Resolved
April 13, 2016 – Uber rewarded us with a bounty.
0×03 – Enumerating UserIDs with phone numbers (duplicated)
When looking for vulnerabilities we always try to find all of the application/webapp features, especially those that aren’t easily found or used. With this in mind, we decided to get our phones, computers and called for a Uber and so we did. During our trip we intercepted all the requests and one of those requests caught our attention.
Request inviting to split the fare
This request happens when an user tries to split his fare with others. To invite someone to split the fare, the user needs to add a phone number from his contact list.
The problem here is that the response is leaking too much information such as driver UUID, invitees UUIDs and the invitees picture, even before they accepting the fare split.
You can see the app leaking the information in the pictures below:
Response leaking information about invited user [1/2]Response leaking information about invited user [2/2]
Remember before when we told you that we would explain how we got a list of UUIDs? This is how!
Now, joining this vulnerability with the previous one we could get anyones email address that was associated to the phone number.
Unfortunately, after reporting this issue, it was marked as duplicated.
April 6, 2016 – Bug reported to Uber
April 7, 2016 – Uber’s team changed status to Needs more info
April 7, 2016 – We provided new information
April 7, 2016 – Uber’s team changed status to Duplicate
0×04 – Use Partner/Driver App Without Being Activated (duplicated)
Every user is able to create a driver account but it remains not activated until Uber verify all your driver documents.
After started to test the Partner/Driver app, we realized that you can only enter in the mobile app after the activation process.
“Driver account not activated” response
Looking on the request of the response above, you can see a parameter called allowNotActivated and his value was false.
Request with new value on “allowNotActivated” parameter
By manipulating the login request and changing the parameter allowNotActivated to true, it was possible to obtain a valid session token. So at least, it means that the server create a valid token even when the account was not activated.
New token created
As you can see on the response, there is a field called isActivated setted to false. Changing this to true allowed us to get into the app.
Interface of Partners mobile application
Now we got a couple of new features to test.
March 31, 2016 – Bug reported to Uber
March 31, 2016 – Uber’s team changed status to Needs more info.
March 31, 2016 – We provided new information
April 7, 2016 – Uber’s team changed status to Duplicated
0×05 – Possible to View Driver Waybill via Driver UUID
Using the previous vulnerability we were able to test a new functionality called waybill. By crafting the request that the app sends, we notice that it has a broken access control vulnerability that allowed us to see the last trip from every driver, by only knowing his uuid.
Request for waybill of other driver
To get a driver UUID you can, for example, request a random car, let the driver accept the trip and after this you cancel it. In the meanwhile you are able to capture the driver UUID.
In the response of this request, we were able to get the driver name, license plate, last tripUUID, last passenger name, number of passengers, the origin and destination of the trip.
Detailed response of driver’s waybill
Notice the TRIP # in this response? To get the full path of the trip, we ended up discovering a new functionality that returns the full path of the trip, the driver name, client name, license plate and even the car model.
This functionatility could not be detailed in this moment, but as soon as we are authorized, we will talk about it.
Full path of the trip
March 31, 2016 – Bug reported to Uber
April 1, 2016 – Uber’s team changed status to Triaged
April 13, 2016 – Uber’s team changed status to Resolved
April 18, 2016 – Uber rewarded us with a bounty.
0×06 – Information regarding trips from other users
Remember the vulnerability 0×03 where we found out that by changing the token by a UUID we could impersonate another user?
Requesting trips associated to uuid (in the token)
The request above allow an user to view the trips made by himself. Notice that in the request there is any session headers or session cookies. All the **session** details are sent via GET parameters.
By changing the highlighted uuid and maintaining the original token, the server return a 403 unauthorized access. If we change the UUID and the token for the UUID of the user that you want to see the trips, we get a bunch of new information
This was the response when asking for trips by sending the same value in UUID and TOKEN fields.
List of trips associated to the UUID
As it can be seen we were able to get the date of the trip, driver name and picture, the id and cost of the trip and the map of where he have been.
The response above only demonstrate one single trip, but the full response gives us all the trips made by the user.