Carvis and Reverse Engineering Uber pt. 2
Carvis and the story of reverse engineering Uber Pt. 2
Not having any insider information when it comes to why Uber does what it does, all I can do is speculate and make assumptions, so bear that in mind when reading my descriptions of the challenges faced during this portion of the process. It is just part of the process when Black Box testing. The request and response bodies used by Uber are fascinating and a real life example of the type of massive data flow an application like this feeds off of. Below I have detailed some of the basic flow.
This was the thinnest request and response of the entire process and pretty straight forward. I have decided to redact the important bit of info you get when logging in for Ubers sake. If you wanna know. Do the work.
Among the myriad of POST request this one stood out to me from the very beginning. After doing some quick comparisons I realized it was a process that only happens once a session. I didn't spend the time to figure out exactly what determined a session and when or why the app needed to ‘bootstrap’ the user, other then every time you logged out and back in. With this call, the treasure trove of information you send to Uber is paled in comparison to what is sent back in return. Over 3000 lines of information is sent back via ‘bootstrap rider’.
This was the meat of the process. I think it goes without saying that the endpoint named /me/pickup was going to be what I was looking for. This was where I needed to dig in and do most of my work.
Again, I am not going to give out the nitty gritty details of exactly how I got this to work or what flaws I may or may not have found. All I will say is that I was able to replicate the functionality via Postman and then again via a quick button I wired up to our front end splash page. It took plenty of trial and error and suffice to say Uber did not make it easy.
So here we were with a fully functional version of our app that exactly mimicked both Uber and Lyfts functionality by utilizing their own private endpoints. Life was great and everything was easy…(There is that word again...easy) You should be on high alert at this point. I was constantly checking and re-checking the functionality via recording sessions on Charles and spoofing ride requests via postman. At this point I believe I had over 50 canceled rides! (Bye-bye 5 star review)
Over the next couple weeks as we built out the actual application, both web client and Amazon Alexa Skill, things were working just fine. Having been the culprits of private api manipulation, we as a group decided to go out of our way to architect the app in such a way as to greatly decrease the possibility of someone being able to do the same thing to us. The tl/dr is that we separated out our secret sauce into a private api which was only ever touched by our forward facing api via private methods that lived in a separate private repo. 3 degrees of separation at all times. We also encrypted EVERYTHING. Even though this was just a research/educational app, we wanted to treat it as if it was going to market. We understood the ramifications of being responsible for users passwords, emails, secret keys etc. Nothing of importance was ever transferred unencrypted and all of the important or sensitive data was to be partitioned away from the rest of the application.
Less then a week from demo day, 3 days to be exact, I ran into another MAJOR issue. Uber had made a pivot in the applications functionality and user flow. Before, a user never had to enter a destination address, you could if you wanted, but it was solely a feature to help drivers out. They also had Surge Pricing, which a user had to accept any time prices were higher than the normal rate. After the pivot, everything changed. Users were required to enter a destination address and prices were now considered ‘up-front’, meaning you got a real time estimate of the total cost of the trip. This of course completely broke the system I had in place.
I scrambled to make the necessary changes. I fired up Charles and got to snooping and what I found was at the time very disheartening. They had completely changed their ride-order flow. Again, I won't get into details but what I will say is that functionality I had been able to mimic with one POST request now took two and there was a lot of hail marry hard coding involved. I got lucky. I was able to recreate the functionality and figure out exactly what I needed to mimic to get the Uber servers to believe I was legit. Honestly moving forward I have serious doubts about how long this functionality will actually work in practice. I am assuming some of the hard coded bits of mine will soon start being validated server side on Uber's end and I'll be out of luck, but for the time being it worked.
That my friends is pretty much it. That's my story of reverse engineering Uber's private api endpoint and hacking their functionality. It was an extremely fun and educational endeavor. They are one of the industry giants and it shows the minute you start digging into their systems. Of course they are not perfect, or else I would have never been able to pull this off, but still, everything can be hacked.