Facebook Email/phone disclosure using Binary search

Rikesh Baniya
PenTester Nepal
Published in
3 min readJul 9, 2021

--

So in December I decided to hunt on Facebook, and chose to go with the Facebook Android App

I was analyzing the Facebook app’s password recovery flow.

I noticed that the following endpoint was being used.

When a user enters his email/phone number his email is supplied in the following manner using parameter `q`

The endpoint contained manyyyyy parameters, more than it required.

So I was eager to test what those parameters did.

I quickly noticed that although the user’s email is being carried by `q` parameter, it also contains a `qs` parameter.

Now, incase you don't know;
In Facebook the character `s` behind a parameter means plural.

Example:
invite_id, Plural= invite_ids
user_id, Plural=user_ids

I knew that in plural parameters you can supply array of data
like:
user_ids=[“UserID1”,”UserID2"]

so I supplied data in following manner:

qs=[“vicitmemail1@gmail.com”,”victimemail2@gmail.com”]

But it gave an error stating the array key are invalid.

So this wasn't a normal array, it had its own keys.

So after some fuzzing I finally figured out that the parameter `qs` takes the value in json wrapped format along with the keys “phone” and “email” and the values of email/phone are the ones that will be supplied as an array

Example:
q=victim@gmail.com
qs={“email”:[“
victim@gmail.com”],”phone”:[“981234567890”]}

Now,
When you supply an email in the forget password endpoint, the data belonging to you is given in the response in encrypted format.

The response will contain:
your encrypted userID ,contact points etc

Along with the data there was a value `summary` and it was set to `1`.

Initially I thought it to be a Boolean.
But turns out:

When we supply one email in `qs`
qs={“email”:[“user1@gmail.com”]}
Data of one user is obtained in response.
hence: summary=1

When we supply two emails in `qs`
qs={“email”:[“user1@gmail.com”,”user2@gmail.com”]}
Data of two users is obtained in response.
Hence: summary=2

But here comes the final part:

Lets say I supply:
qs={“email”:[“victim1@gmail.com”,”victim2@gmail.com]}
Data of only 1 user is obtained.

What does that mean?
Both the emails belong to the same user and both emails pointed to same user resulting in the response “summary”:1

Now, basically it was bruteforce attack scenario.

I supply victim's username along with a email and if the email belonged to victim the response is “summary:1”

qs={“email”:[“victimUserName”,”Email”]}

//Yup, We can supply username in email parameter

BinarySearch to the rescue

Bruteforce attacks are noisyyy.
But using binary search, this attack became much easier.

Refer to this video to learn about BinarySearch:

Since, the endpoint was accepting an array of data:
I wasn’t forced to only submit
1 username+1 email

I could supply
1username+ 100s of email.

Example;

qs={“email”:[“victimUserName”,”email1@gmail.com”,”email2@gmail.com”,”email3@gmail.com”]}

Now if any of the email from the request belonged to vicitmUserName:

Summary=3
//Response of email1+email2+email3

Else summary=4
//Response of vicitmUsername+email1+email2+email3

This made it easier to bruteforce and effectively identify any user’s private email.

Diagram demonstrating the binarySearch

I also received this sweeeet response from the Facebook team,
felt good ;)

Timeline
Submitted : January 3
Triaged: February 13
Bounty $XXXX Awarded :March 22

--

--