There are various Facebook products like Ads Manager, Business Manager, Messenger Payments, etc. which requires an user to add some payment method to their Facebook account which can be credit card, debit card, paypal, etc.
eg. If I want to run Facebook Ads then I need to add a credit card or any other relevant payment method so as to use it. Same is with other products.

Facebook assigns a unique 15 digit random number to any card added to user's Facebook account and this id is known as credential id. This credential id is then used by Facebook to query about credit card details.

This credential id was querable via GraphQL and it allowed an attacker to use it(credential id) to get credit card details. But it exposed last 4 digits, address, expiry date, etc.

How one can get credential id?

1] I had reported a bug last year where Ad Analyst was able to escalate privileges and was able to access funding sources of the Ad account. This leaked the credential id of the payment method. Unfortunately this bug went duplicate but I was still able to use it to demonstrate the flaw.

2] Brute Force / Dictionary attacks :
We need to form 15 digit numbers so calculations are as follows...

This covers all the 15 digit numbers. We need ONLY 900000 billion numbers. This seems to be practically possible as it may take few weeks to do so.

But even if we consider it impossible, one can generate numbers in range like generating number from 931000000000000 to 999999999999999. This will be a lot quicker than previous one. Also, if we reduce the range and only brute force last 6-8 digits still we can generate a lot of valid 15 digit numbers.

So, now we assume that we can generate a large amount of valid unique 15 digit number.

*Note : I avoided running the real brute force/dictionary attack as it would get me access to real credential ids of real users which voids Facebook's terms. Instead, to prove my point I provided POC of my test accounts where I was able to show that brute force attack may work to get access to credit card details.

3] Other methods:
Ad account Admin removed from the Ad account having noted these ids can still use it now and get access credit card details.

Similarly, it applies to Business Manager as it has a separate payment management. A user having access to Business Manager but now removed from it can still have credential ids.

Proof Of Concept

1] Get an access_token which can access graphql. This token can be obtained by observing requests/responses of your Android/IOS Facebook app or other Facebook owned apps.

2] Now, get yourself a credential id via any of the methods listed above.

3] Encode the credential id in order to form a string as base64encode(p2p_credential_id).
eg. base64encode(p2p_999999999999999) --> cDJwXzk5OTk5OTk5OTk5OTk5OQ==

NOTE : Please note that credential id is never deleted from Facebook. So, anyone can access the details even if card is removed or account is deactivated.

How one can exploit it?

Try to form a valid credit card :
According to my research, it is possible to validate a credit card number using Luhn algorithm (https://en.wikipedia.org/wiki/Luhn_algorithm). One can generate a large set of credit card details then filter out the credit cards based on last 4 digits and pincode and expiry date. This will return a very small set of valid credit cards. Later, cvv number can be brute force or any alternative attack can be done if we have valid credit cards.
This attack is sophisticated and will require a lot of time but it is not practically impossible.

One can even think of innovative ways to use these stolen credit card details.

Impact

Once attacker knows the credential id then attacker can access credit card details which exposed the following:
1. last 4 digits
2. expiry date
3. address
4. country and other relevant details

Facebook determined that brute force attack may take a long time but considering other methods they patched the bug by placing permission checks on the endpoint. Now, users can only access their own credit cards.

Special Thanks

Thanks to Facebook for patching the vulnerability and all my friends who are supporting me for my work.

How can you learn GraphQL?

Timeline

January 1, 2017 at 11:35pm - Report Sent
January 13, 2017 at 6:22pm - Initial Response by Facebook
January 16, 2017 at 6:59am - Sent more information
January 18, 2017 at 1:55pm - Bug Confirmed by Facebook
January 24, 2017 at 3:44pm - Bug fixed and response by Facebook
January 27, 2017 at 7:40am - Confirmation of fix by me
February 1, 2017 at 4:31pm - Bounty awarded

I came across a note New: Videos in Comments! written by Bob Baldwin who works at Facebook. This note was about Facebook launching it's new feature of commenting using videos.
eg. Now, users were allowed to upload a video in comments.

When I saw this note , at that time this video comment feature was already out 8 hrs ago. So, I started playing around and testing this feature to find out how it works. After, 2 hrs I was able to figure out some pretty interesting low impact flaws. Using these low impact flaws, I was able to form a bug to DELETE ANY VIDEO !

At that time, I was like ...

Seriously, I am able to DELETE ANY VIDEO of my choice from FACEBOOK.

The Bug

This bug is proof of flaw in logic rather than daily technical flaws which we see like RCE, SSRF, etc.

Developers logic

When we upload a video as a comment, then this video gets uploaded onto user/page 's timeline and then it gets attached to the post as a video comment using it's video-id.
eg. When any user comments using a video on any random post, then video will first get uploaded to the user's timeline and then video-id will be returned. This video-id gets attached to the post as a video comment.

My attack Logic

I love API. So, I got to this via GraphAPI. Below is simple attack logic.

Create a comment via api.

Edit the comment and attach video of your choice using video_id via api.

Delete the comment via api.

This was removing the attached video using it's video-id.

Here, there are two simple flaws ...
1. I am able to attach anyone's video to my comment using it's video-id.
2. When I delete my comment, then attached video gets deleted. As it uses ONLY video-id and there are no permission checks placed to verify if the user owns the video. Assumptions are made that user will ONLY upload/attach his/her own videos.

This vulnerability was temporarily fixed by Facebook team in 23 minutes after confirmation of flaw.

Permanent fix was live in 10-12 hrs after that.

Kudos to Facebook. :)

How I got this hit ?

I have been following some youtube channels, some great books and some other material which I mentioned in this note on my page to improve my life. The book "The Power Of Subconscious Mind " mentioned in my note is really life changing and have some really cool techniques to take you to whole new level. I recommend everyone to read this book who wants to acheive great things in their life.

Also, it's worth mentioning that it took me more than 1.5 years to find this high-impact bug.

Follow this :

Special Thanks

I would like to thank all my friends, well-wishers and everyone around me who plays an important role of motivating me. Also, Facebook Security Team to patch this bug before it goes into wrong hands.

Timeline

June 10, 2016 at 3:53pm - Report Sent
June 10, 2016 at 8:36pm - Initial Response by Facebook
June 10, 2016 at 8:51pm - My Response to Facebook
June 10, 2016 at 10:11pm - Bug Confirmed by Facebook
June 10, 2016 at 10:31pm - My Response to Facebook
June 10, 2016 at 10:34pm - Temporary fixed applied by Facebook
June 10, 2016 at 10:44pm - My Response to Facebook
June 11, 2016 at 9:05am - Bug fixed and response by Facebook
June 11, 2016 at 9:55am - Confirmation of fix by me
June 11, 2016 at 10:28am - Confirmation of fix by Facebook
June 11, 2016 at 10:35am - Messages exchanged
June 15, 2016 at 1:20am - Messages exchanged
June 20, 2016 at 9:03pm - Asked about bounty decision
June 23, 2016 at 1:13am - 5 digits bounty awarded

I was able to fool Facebook's Graph Search and bypass privacy restrictions and extract sensitive information about user's applications and pages. I was able to get applications used by any user, regardless of privacy settings set to Only Me and also I was able to get Pages liked by user, regardless of privacy settings set to Only Me

For example, I was able to see applications used by Mark Zuckerberg despite of privacy settings set.

What is Facebook Graph Search and How it works?

Facebook Graph Search is SMART search tool developed by Facebook and Google developers who joined Facebook. It was an innovation as it allowed people to see what their Friends are doing. And these things aren't possible using traditional Google search.

Graph Search Internal Working

Graph Search simply works on Set Theory. So, it is possible to fire queries which adhere to Set Theory and are successfully executed and make the search engine return result set back.

For eg,
A = {1,2,3}
B = {2,3,7}

Then,
Intersection = {2,3}
Union = {1,2,3,7}

This works same in Graph Search.

A similar bug found by "Philippe Harewood" ---> "Abusing Facebook Graph Search using GraphQL". This bug gave me initial idea. He has exploited Graph Search directly using GraphQL whereas, I tried to abuse it directly on website.

Proof Of Concept

Getting applications of any random user.

Intersection of two sets was handled properly and didn't show any private information using privacy Only Me or other.

This returned me few applications which were used by me or Mark Zuckerberg. I demonstrated this vulnerability on my test accounts.

Getting Pages liked by user.

On user profile, a user is allowed to like pages which are of categories Apps and games, Movies, Tv shows, Music, Books, Sports, etc. Now, these pages are sorted according to categories and are addressed as individual elements. Books, Music, Sports are different entities and each entity has an option of privacy; an user can select any privacy for any entity.
eg. I visited this page (https://www.facebook.com/pranavhivarekar.hacker/games?pnref=lhc) and it showed me all sections and I was able to set different privacy to different sections and individual elements.

So, here I was able to extract any user's personal information. It included Books he/she read, Movies he/she watched, etc. All the personal information was available via Graph Search, regardless of privacy settings.

To check whether a Tv show was liked by me. I used my another test account and fired the following query. My privacy settings for that page were set to Only Me.

Both the Api's have different permission models i.e different and distinct scope permissions are available for both the apis.

I was testing the Core Api and I found pretty bad authorization bypass. Let me explain what was it ?
Also, I would like to add that this bug was open for almost 2 years from the initial launch of the api.

A dedicated folder named after your app is created within the Apps folder of a user's Dropbox. Your app gets read and write access to this folder only and users can provide content to your app by moving files into this folder.
In simple words, an app can access only the folder which is created by itself. It won't have any access to other folders or root folder. So, an app can post/delete files ONLY in it's folder.
eg. If Pranav's app has created Pranav's app folder then app can access ONLY that folder and nothing else.

But I was able to circumvent this permission model and I was able to post files in any folder of my choice of dropbox.

Proof Of Concept

This is completely logical attack ...
Two steps were required to completely post files in other folders.

Vulnerable parameter is root=dropbox. Here, auto means it will directly point to the App Folder but dropbox means it starts pointing from root.

If file is already present with the name then it gave verbose errors. This allowed me to enumerate all files present in the dropbox.
eg. If test.png is already present in the root directory and we try to post file with same name then it will give verbose errors and Status 403 Forbidden which is a clear indication that file exists.

I successfully submitted this bug to Dropbox's Flex which was hosted on Bugcrowd and won first prize.

The endpoint /me/links is undocumented. We cannot find documentation about how to deal with this endpoint. But combining few api calls we can create unpublished posts.

More information about creating unpublished posts can be found here.
It states that, "It is possible to add some content to the Graph without publishing a news feed or profile story indicating that it has been created. This is useful in a few situations, such as Page posts which are scheduled to go live at a particular time, or when a photo is to be used in a photo comment."

This is very useful for page owners as UNPUBLISHED content will not be shown on page until published. Page admins or people having roles on pages can also schedule the posts to be published later.

After recursive testing, I observed that this edge(/{page-id}/links) is not obeying the rules of an unpublished content. When we create an UNPUBLISHED link via /me/links edge. Then it will be unpublished i.e it won't be visible in feed and a profile story indicating that it has been created will not be shown. So, it is working good on the front end.

But any app or anyone can access the page. So, anyone with their access_token with public_profile permission can access the UNPUBLISHED links.
This can be done via /{page-id}/links edge.

Proof Of Concept

The link is published as unpublished. So, link is public at the moment but it is not shown or linked directly to the page. But there was flaw that allowed anyone with any access_token to view the unpublished links via /me/links endpoint. Now, it is patched and the unpublished links are only accessible to admins/editor or people having roles on pages and not to public.

Thanks to Facebook's team for patching this vulnerability that allowed exposing of unpublished links via API.

The endpoint /{videolist_id}/videos is undocumented. So, we cannot find any real documentation
about this on developer's site. But still using analogy between other endpoints and this endpoint we can guess the working.

Facebook recently released new features for pages. This was the one. Now, we can upload videos on a page and then create a video playlist and arrange relevant videos for our audience. So, it gave really cool looks to our loved facebook pages.

Before folks were allowed to only upload videos to a page but creating video playlists was not offered. So, it was difficult for audience to navigate through video content. Also, it troubled page managers.

Now, using graph api, using an user access_token with public_profile permissions, it was allowed to add/remove videos from video playlists.

I researched and found an analogy between other endpoints. And in the end, I came to the conclusion that for dealing with pages or creating/editing contents on pages, it demands manage_pages permissions. And if we need to modify/edit the object then we must possess publish_pages permissions. So, this bug was good to go.

Proof Of Concept

Post a video on a page.

Go to page and create a new Video Playlist.

Now, add the video to the Video Playlist you created.

Now any app having user access_token with public_profile permissions, can REMOVE the video from playlist.

A user access token with publish_actions permission is required to remove a user's photos.

A page access token or a user access token with manage_pages, publish_pages permissions is required to remove a Page's photos.

A photo can only be removed by the same app that published it.

eg.
1. We can delete a photo from a user's timeline using an user access token with publish_actions permissions, provided the photo was published by same app.
2. We can delete a photo from a page using a page access token with publish_pages permissions, provided the photo was published by the same app.
3. We can delete a photo from a page using an user access token with manage_pages and publish_pages permissions collectively, provided the photo was published by the same app.

Here, it allowed an app to delete a photo published on a page by the same app using an user access token with permissions publish_pages. A simple permission check was missing. So, this contradicted the documentation.

Basically, to co-ordinate with the page, basic requirement is to get an access token with permissions manage_pages. But it allowed me to do deal with pages without satisfying the basic requirement.

Twitter is using many third party OAuth integrations like Gmail, AOL, Outlook, Yahoo, etc. These third party integrations are used so that they can provide an easy way for their users to Import Contacts from these sites.
eg. If an user is having many email contacts but user is new to twitter so directly importing contacts from the email service will find all his/her friends on twitter.

The Story Of The Hack

Outlook's OAuth used on twitter was deprecated. You can read about OAuth 2.0 here.

Note the redirect_uri parameter. It is set to https%3A%2F%2Ftwitter.com%2Finvitations%2Foauth_landing.
Now, we can change redirect_uri to any twitter's url.
eg. any *.twitter.com was accepted as it was using a deprecated version.

Also, make note of response_type=code. It states that twitter has implemented a Server-side OAuth flow. After getting code twitter makes a request to server and collects access_token. Using this access_token twitter imports contacts from Outlook.

So, my job was to steal code. Attack vector to steal code is via referrer header. This was the most hardest job ever. As twitter uses a link shim t.co.
eg. When user posts any link on twitter then it gets converted to some link like http://t.co/anything.

When user visits the http://t.co/anything then it redirects to the site but wait ...
It removes off referrer header from the request. So, we cannot use it to leak code via referrer.

I was like

Then I noticed that any *.twitter.com is allowed. So, it was my turn to flip the game over twitter. So, I found a page in OAuth implementation which can be used to leak code via referrer.

Game starts now ...!

I created an app. Now, I implemented a Login via twitter on my own site. So, when user clicks Login via twitter then OAuth token gets created. Simply, it looks like

When user presses Cancel then it goes to this page. And we can use this end point to leak code.

Now, I researched more and found that once oauth_token has been cancelled, it can still be used to leak code (Just sending it to another user.)
eg.https://api.twitter.com/oauth/authorize?oauth_token=1BXYoJbg57y8iPjuOn1MHI8HTFdXubvc

Open Redirect vulnerability allows attacker of an web application to redirect users to any external sites. Here, there is no validation of the passed input by attacker. This is basically used in phishing attacks.

Final Exploit

This exploit should work against any random victim (user) of HackerOne. So, using my mind, I got an idea of combining 'Open Redirector' and 'Redirect Filter Bypass' to create an exploit to damage other users.