Edit: I published this page in January 2017 after contacting the Facebook white hat program

Default Facebook's privacy settings allow enumerating user's mobile phone numbers

Introduction

Facebook often asks users to input their mobile phone numbers. Users are asked to input their mobile phone numbers for easier password recovery or for easier contacts discovery on messanger app. Even if the mobile phone number is kept private and it is not public, the default facebook's privacy settings allows lookup of users through their mobile phone number, allowing malicious parties, such as spammers, to enumerate all those inattentive users.

With few lines of codes, and few facebook's account, it is possible to enumerate all the Facebook's users that didn't manually deactivated lookup by phone numbers. In few hours it is possible to populate a large database of users with respectively their name, surname, avatar photos and mobile phone numbers, along with all the public informations they input on Facebook. This database can then be used for unlegitimate purpose, such as advertising or spamming. In this brief report, i am going to show how I built a script for achieving this easily, and i put the result of my experiment.

Anatomy of the search

The Facebook's privacy policy that allows users to be looked up through their mobile phone number allows malicious party to make two different kind of search for ambigous purposes:

In both cases, the attack vectors consist in brute forcing all the possible numbers and input them in the facebook search. Whenever a match is found, Facebook's search returns one and just one result, giving to the searcher the certainity that the searched phone numbers belong to that user.

We will discuss later about the facebook protections (such as request's rate limits) and how to avert them.

Brute forcing all possible phone numbers in a restricted set.

My experiment consisted in trying to enumerate italian facebook's users and retrieving their phone numbers. Mobile phone numbers are always composed by 10 digist, of which the first three depends on the carriers, so are usually easily predictable. Coding a script for generating all the possible phone numbers is trivial: with 32 common carrier's prefix, all the possibile italian phone numbers are 107*32.

After populating locally this database, it is enough to perform a search on facebook using a browser, inspecting network's traffic and exporting the HAR (http archive). Then it is trivial to parse the request's archive and replay requests programmatically changing search's input.

During my experiment, using cookies from my personal facebook's account, 
I sent over 400 requests to Facebook in a total range of time of about 8 minutes, and matched 50 users: 50 strangers of which i got name, surname, photo and phone number, intended to be private, (and all the public info). I did not receive any limitation from Facebook.
 The success rate was about 10%, so that each 10 requests searching for a random phone number a match was found.

Below a screenshot of the script executing on my shell:

ex

Averting rate limits

Firstly saying there is not public knowledge about Facebook protections, a possible threat came to my mind: More or less Facebook receives a request from an account to ‘search.php’ every time an user digits a character in the search input. A user searching a phone number using web user interface inputs 10 characters, so that about 10 requests are sent to Facebook’s server. An user performing some searches on Facebook's website sends an huge amount of requests. This could suggest that Facebook expects many request by the same account for searches, allowing malicious searcher to perform more requests without limitations.

Putting a random timeout between requests helps preventing being marked by facebook as an automated tool (prohibited by facebook's policy).

Making the attack more effective

Using such a trivial tool it is possible to populate a large database of mobile phone's contacts. Parallelizing the searches with many accounts it is possible to slolwly query the facebook's database and retrieve all the contacts' information. The attack can be easily distribuited.

In order not to sent useless request to facebook's servers (searching of not existing phone numbers, for example), it is possibile to use free services such as Twilio's apis that allows to lookup phone numbers to check their existency. For a small amount of money (half cent of dollar), it is even possible to lookup the mobile carrier of a given phone number.

Targeting a single user

Targeting a single user to retrieve its phone number is also possible. In fact, it is enough to retreive its facebook's username (which is public), and input it in reset password form. Facebook will show the last two digits of its mobile phone number, restricting the searched space. In fact, assuming the nationality of user's mobile phone carriers, possibile permutations are: n_carriers_prefix*105. In case of italians phone numbers, possibile phone numers are 32M.
Making so many queries to Facebook's server is surely not trivial, but parallelizing the attack makes it possible. Moreover, in the meantime we find a match, we can enumerate all the users that helds the tried phone numbers.

Conclusions

Even if Facebook's privacy policy expects such behavior, protections adopted to prevent misues seems not to be effective. Malicious users can easily populate large databases and using it for unlegitimate purposes (such as spam). Facebook, as other social networks, offers highly customizable privacy settings, but these settings have a default beahvior that in most cases could be dangerous for users' privacy. Thought most of the users are inattentive to privacy's issues, these default settings should have the most possibile privacy-preventing configurations.