Let’s talk about Oculus VR, known best for their 2012 kickstarter funded Oculus Rift, a popular virtual reality headset. Earlier this year, Facebook acquired the company for $2 billion, making it an interesting new target in Facebook’s bug bounty program.
I was late to the party. Their inclusion in Facebook’s bug bounty was already announced for a few weeks, and I was pretty sure the low-hanging fruits were already gone. I nevertheless started my quest for valuable bugs and did eventually find where I was looking for.
In this blogpost, I will address each issue individually. I’m going to start off with the account takeover vulnerability, without a doubt one of the most interesting bugs I encountered in Oculus land.
1. From joining any group to complete admin account takeover
aka the administrator list: where security researchers meet
Creating an account at the Oculus developer center, you can either sign up as an individual or as part of a company.
Once you have your e-mail address verified, you can automatically choose any company related to your verified e-mail domain. If you’d for example manage to verify an @facebook-inc.com e-mail address, you would we able to join either Facebook, Instagram, Oculus, Parse or Moves. My goal was to join the Oculus company without having to verify an @oculusvr.com e-mail address.
I could either
- Find a way to bypass the verification process
- Look for a privillege escalation to change my company
It did not work. So I clicked next and proceeded to the last registration step. Once I had chosen a company associated to my verified e-mail domain, I could choose to work an existing project – or choose a new one.
Here the things got quite interesting: I noticed the CSRF token we saw in the choose-a-company form was not present this time. This cross-site request forgery issue would allow us to make someone from the same company change its project… to another project of the same company. Not that exciting, huh?
I tested once again. This time, I choose a project with an id that was not associated to my company. I was shocked to see I indeed was able to join another company’s project, in fact, I even did join the company. Cool! I could join the Oculus Team and view some confidential details such as e-mail addresses ect. At first, I did not realize this privillege escalation and CSRF would actually allow me to take over accounts.
As a company administrator, were are able to edit all the details of the company’s linked employee accounts. Even the password and the e-mail address.
So here was the deal: all I would need to do is use the CSRF to make someone join one of my company’s project and change his password. Bazing! We are able to hack Oculus accounts. But things got a little crazier. Just a little.
After reporting this bug to Facebook, I tried to reproduce the issue again. This time, I would use my company’s administrator account to join the Oculus team. I could not believe my eyes: I was still a company administrator. From the Oculus Team, this time. Long story short: I could hack any Oculus account without user interaction. I’d simply join their company – as a company administrator – and change their password.
Fun fact: it was nice to see my colleague Stephen Sclaphani in the company admin list using another vulnerability. Well done, Stephen!
Long story short: things escalated quickly. From a lame CSRF, to an interesting privillege escalation CSRF, to an account takeover CSRF, to a complete account takeover without user interaction.
September 5th, 2014 02:39AM – Reported to vendor
September 5th, 2014 02:40AM – Vulnerability confirmed by vendor (! Check the response time !)
September 8th, 2014 02:50AM – Vendor asks for fiw confirmation
September 8th, 2014 02:52PM – Fix confirmed
October 15th, 2014 09:46PM – Bounty awarded
I did get a nice reward for this bug, but it did not even get close to Bitquark’s 5k for a similar account takeover. This is due to the fact that Facebooktook additional steps to mitigate the risk of account takeovers and decreased the payouts accordingly. I am nevertheless very happy with the award and want to thank the Facebook security team for their fast and friendly responses.
During my quest for Facebook bugs, I found some other valuable bugs I’m about to describe below. Enjoy!
2. Privillege escalation leading to cross site scripting
A company may have multiple e-mail domains linked to it. This can be done in the “Access Control” pannel only the company administrator can use. These domains are included in various forms as a joined array, as well as in the “update project” form:
Facebook rewarded me for both bugs with a nice and generous award. I would like to thank them for this! It’s always a pleasure working with them.
August 26th, 2014 11:00PM – Reported to vendor
August 27th, 2014 09:41PM – Vulnerability confirmed by vendor (got a “PS: Nice work, Inti!” – reply as well. Awesome!)
September 8th, 2014 02:48AM – Vendor asks for fix confirmation
September 8th, 2014 02:26PM – Fix confirmed
September 9th, 2014 08:51PM – Bounty awarded
– Privillege escalation
August 26th, 2014 11:08PM – Reported to vendor
August 27th, 2014 09:31PM – Vulnerability confirmed by vendor
September 8th, 2014 07:12PM – Vendor asks for fix confirmation
September 8th, 2014 07:41PM – Fix not confirmed, still some nasty side-effects present
September 16th, 2014 11:05PM – Vendor asks again for fix confirmation
September 17th, 2014 12:09AM – Fix confirmed
September 17th, 2014 12:53AM – Bounty awarded
3. Another privillege escalation leading to cross site scripting
If you liked the previous bug combo, you will definitely like this one. It’s a bit more complex and therefore one of my favorite’s.
Remember the “update project” form I told you about earlier? It includes a CSRF token. That’s good, right? Yes, but it is a bad practice not to change your tokens for every form you generate. This bug will explain you why.
Upon registration, when a user is asked to join a company linked to his or hers company domain, he is also able to create a new one. To create a new company, the user is prompted to give some more details on the company in question, such as phone number, street address and website. The user needs to make sure the information provided is valid because – and this is important – these details cannot be changed later on.
Of course I tried to inject all kinds of XSS payloads into these parameters: tests that haven’t really got me far. I did notice that the company registration was processed by the same script used to update profiles. In fact, there were quite a lot of similarities. Even the form token was the same. Only CompanyTypeId was different: COMPANY instead of PROJECT. Interesting!
So this wild idea began to haunt my brains: what if I could use the “update” action command to change my company details? I could perfectly use the form token provided in the update project form: it would be the same. So I made myself a new form with some elements of both forms combined, “the best of both worlds”: the company detail parameters from the “create company” form, and the CSRF token and update action from the “update project” form.
It felt a bit like making Frankenstein and hoping it would come to live when it gets hit by a lightning. “This is never going to work”. Until I executed the script and head back to my company details: it worked.
So wow, another privillege escalation allowing any company user to change the companies details. But then I thought of my previous bug: would this bypass the XSS filter once again? Turns out I got it right. Boom!
September 5th, 2014 05:17PM – Reported to vendor
September 6th, 2014 02:29PM – Vulnerability confirmed by vendor
September 25th, 2014 12:20AM – Vendor asks for fix confirmation
September 25th, 2014 03:50PM – Fix confirmed
October 14th , 2014 01:58AM – Bounty awarded
4. Reflected XSS
Whoosh. That was heavy! Time to light things up a bit, with this low-profile, yet funny, reflected XSS!
If you want do download a particular game at the Oculus Share center, you first need to accept some terms and conditions. Then it takes you to your download link.
Déja vu. If I had learned something from the bugs described above, it must be that things will never work out from the first try.
September 9th, 2014 03:00PM – Reported to vendor
September 9th, 2014 11:57PM – Vulnerability confirmed by vendor
September 26th, 2014 09:02PM – Vendor asks for fix confirmation
September 26th, 2014 09:12PM – Fix confirmed
October 14th , 2014 02:20AM – Bounty awarded
5. The dupes
For being quite late to the party, the dupe ratio of 2/8 bugs was quite ok. Just a bit of a bummer both of those bugs were some sort of account takeover vulnerabilities. That’s why I decided to honor them as well in this write-up.
The first one was a password reset CSRF. If a company administrator adds a user to his company, the employee gets a temporary password and an activation link. After clicking the activation link, the user would be prompted to choose a new password. Interestingly, this form was not protected by any CSRF token, which made it possible to make someone reset his password without he or she even knowing. Here was my video PoC:
The 2nd account takeover I found was a bit less interesting, but nevertheless interesting. The developer center is closely linked with the discussion board: if you register an account to the developer center, a forum account will be created as well. When you delete your developer account, the forum account did not get deleted. I tried to create a new user with the same name as our orphan forum account – and guess what? I could regain access to it. In short: when one’s developer account was pruned, the forum account that was left behind could be claimed by anyone registering under the same name.
That was all for today. If you are interested in reading more about Facebook’s bug bounty program, this would be the place to be.
If you are interesed in more detailled write-ups, make sure you follow me on twitter!