Messing About With Facebook Places
InfosecDepending on who you speak to, Facebook Places is either a fantastic little feature which enables to you see if any allies are nearby, or an annoying tool designed to invade your privacy. If you ask me, I’m somewhere in the middle, it’s neither a problem since the privacy settings are very strict, but it is a little creepy.
For those not in the know - Facebook Places allows you to “check in” to your physical location via Facebook. Designed for Facebook mobile applications, it can detect your rough location, and offer to check you in at places nearby, ranging from shops, stations, attractions and anything else you choose to find in the area. You can then see who else within your social group has checked in, saving the unnecessary and sometimes complicated process of pre-arranging meetings, yeah…
I was curious about how this process worked, and was surprised to find out that it was actually much simpler and low tech then I expected. Armed with a web server, I went about attempting to ‘fool’ Facebook Places into checking me into locations I wasn’t physically at, and thought I’d share my findings with you, the ever beautiful Serpent reader.
This guide only lets you muck about with your own Facebook Places location by doing some quick basic networking redirection tricks, but unless your friends have changed their privacy settings, you can also tag them at random locations too ;)
Facebook Places in a Nutshell
Let’s have a quick and dirty look at how the Facebook Places works. It varies slightly when using specific applications, such as the iPhone Facebook app, and the Android application, but the general process is the same. The simplest way to discover the secrets of Facebook Places is to use the generic URL http://touch.facebook.com to check you in. This website was designed to be accessed by any mobile device with a browser, so should work nicely for our needs.
Go ahead and try it out, load the above URL on your phone and log in to Facebook, click the ‘Places’ tab and Facebook will attempt to find your location, and offer you places nearby that you can check into.
The first thing you might notice is that the longitude and latitude of your location are contained within the URL string. It would be far too simple to simply edit these and get new locations, but that’s exactly what happens. For example, changing these values to a longitude of -112.1390 and latitude of 36.0544 will place you squarely in the Grand Canyon. Facebook then displays the locations nearby.
There’s just one problem. It also detects your nowhere near this place (unless you physically are!), and will not allow you to check in, in short, denied.
So how do we trick Facebook into thinking we are at the Grand Canyon? We spoof the Google Geo-Location service.
Google to the Rescue
When you click the Places tab, Facebook needs to find out where you are. Facebook itself can’t do this, so they rely on someone who’s spent many months mapping out the entire globe - Google.
Facebook simply utilizes the Google Geo-Location service, by instructing your browser to ask Google to find you. It does this with a simple HTTP request, containing a payload filled with local information, gathered from your browser. This information contains key components to help Google identify you, the key components being:
- Any and all mobile base stations found nearby the device
- Wireless networks discovered nearby
- Your internet facing IP address
These three pieces of information are enough for Google to give a rough idea of your whereabouts. The base station information is quite obvious, anyone can discover these… but how did they learn about the wireless networks?
Simple. They recorded the SSID’s of discovered networks when creating Google Street View. Pretty sneaky, huh?
If you were expecting some clever GPS or cell triangulation, sorry to disappoint, your location is for the most part - looked up in a huge database.
Here’s how it works…
Using Google’s Geo Location Service
Facebook are just a customer of Google’s service, it can be utilized by anyone. The two main ways to access the service are via the depreciated Google Gears platform, or by crafting the correct HTTP request yourself.
Note
Google Gears API is hoped to be replaced by HTML5. Google hope that the Geo-location API will become standard within this specification, which means they must be maintaining this massive database of wifi SSID's, base stations and IP's.To try Google’s Geo-location you need to either send an HTTP request containing the information required by the API, in the form of a POST request, or you can involve the Google Gears API which is built into Chrome. The latter option is the easier, and the following code will demonstrate:
<?php
$code = <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Geolocation</title>
</head>
<body>
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
var geo = google.gears.factory.create('beta.geolocation');
function updatePosition(position) {
document.write('Current lat/lon is: ' + position.latitude + ',' + position.longitude);
}
function handleError(positionError) {
alert('Attempt to get location failed: ' + positionError.message);
}
geo.getCurrentPosition(updatePosition, handleError);
</script>
</body>
</html>
EOF;
echo outputCode($code, "html");
?>
This code is specific to Google Chrome, and other browsers that have the Gears API installed (which isn’t many). It will gather the required information for you, but that’s not much fun. This script results in the following call being made to the URL http://www.google.com/loc/json.
POST /loc/json HTTP/1.1
Host: www.google.com
{"version":"1.1.0","request_address":true,"access_token":"4:OfCj4VEHHX2tMsyw:-Rz9WPFGqrq7gIzL","wifi_towers":[]}
Non essential headers have been removed to make things easier to grasp, but the basics are there. The payload within the POST request is the API at work, but interestingly, this request doesn’t give away any clues about where we are.
This request was generated from a PC, so no cell towers could be found. Wireless was disabled, so no wifi was detected; the access token is simply a unique identifier to maintain persistent sessions, so Google tracked the location solely on my public IP address. It’s not the most accurate method, but does get results.
However to play with Facebook Places - we need to manipulate the response, not the request. The process is quite straight forward, let’s take a look:
This diagram shows how Google’s service fit in with Facebook. The communication happens in 5 main stages:
- You login to Facebook as normal. No location details are provided yet.
- Facebook provides you with the URL of the location service, in this case - Google.
- Your browser then requests your location from Google; this step sends the currently detected wifi networks, mobile base stations, as well as your source IP address as detected by the server.
- Google makes an educated guess of your location based on the information provided in step 3, and returns the longitude and latitude co-ordinates. It can also send street addresses, national dialling codes and other information based on the area.
- Your browser then sends these co-ordinates to Facebook, who looks up locations nearby.
The process is quite simple, and the trick to fooling it is to feed fake details to Facebook at step 4.
Let’s take a look at the Google response body which contains the co-ordinates.
{"location":{"latitude":xx.xxxxxx,"longitude":-x.xxxxx,"address":{"country":"United Kingdom","country_code":"GB","county":"London","city":"London","street":"Central Rd","postal_code":""},"accuracy":25000.0},"access_token":"1:ydew8aVQH2yVK5So:GIRbx-NJEKeB7P6u"}
The information contained within the HTTP response is documented at the Google API found here: http://code.google.com/apis/gears/geolocation_network_protocol.html.
As you can see, the vital part Facebook requires is the latitude and longitude. So all we need to do is spoof this response when Facebook asks for it, something very easy to do on your own PC.
Spoofing Google
The first thing we’ll need is our own web server. We need to return the above data (with amended long\lat data). Because Facebook requests the content over SSL by default, we’ll need an SSL enabled server. We’ll also have a couple of problems with certificates, but we can simply trust our own Google server and work around that problem.
For my tests, I set up Apache with OpenSSL, and created a self signed certificate. The hostname obviously doesn’t match Google, and the certificate is untrusted by any browser, but once your server is up and running, simply visit your site via HTTPS and install the certificate using the browser you’ll eventually login to Facebook with. This then gets around the problem of certificates.
Next, create the directory /loc/json and add an index.html file into it. Add the following contents to the HTML file:
{"location":{"latitude":x.xxxx,"longitude":-xxx.xxxx,"accuracy":25000.0}}
Replace the X’s with the co-ordinates of where you want to be. A good website to get these details from is http://www.satsig.net/maps/lat-long-finder.htm.
Now, the last task is to direct traffic from your PC to your server. The simplest way is to edit your hosts file, or DNS to resolve www.google.com to your local server IP (the hosts file can be found in Windows\system32\drivers\etc).
Confirm the setup works by visiting [https://www.google.com/loc/json] (https://www.google.com/loc/json), you should be directed to your own server, and the contents of index.html should be displayed, ensure no certificate warnings occur.
Finally, if all works well and you see the co-ordinates you supplied, login to touch.facebook.com and navigate to ‘Places’. You can then check in based on your location which will be centred on your new co-ordinates!
A little tip is to ‘tag’ others at the same location, if they have not yet changed their privacy settings, you’ll be able to take any of your friends along with you too ;)