How to Become Mayor for Any Place in Foursquare in 9 Perl Statements

Update #1: We have created a easy-to-use FourSquare checkin hack program you can run to checkin anywhere you like. You can download it for free here.

Foursquare is getting beat down today; hot on the heals of the breaking news that Foursquare is sending your passwords in plaintext (something they are fixing very soon) Mayank Lahiri has decided to figure out how exactly one could game Foursquare checkins to become the mayor of almost anywhere in no more than 9 Perl statements.

It looks like Mayank likely sniffed the Foursquare HTTP POST traffic from his phone to the Foursquare servers on checking and is simply mocking the POST request to the server by replacing the GPS coordinates with the ones of his favorite places that he wants to check into multiple times a day; in this case, a random time between 1 and 10 mins.

Here’s how to use his script…

How to Get GPS Coordinates from Google Maps

This is the bread-and-butter of this trick, you have to search for the location you want to find, so Google Maps centers it on the map, for example here is JFK Airport in New York.

Then on the top right of the map there is the “Link” text, copy it and paste it anywhere you want, for JFK, it looks like this (newlines and color added for readability):

http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=JFK+airport,+NY
&sll=32.221743,-110.926479&sspn=1.024688,1.413116&ie=UTF8&hq=
&hnear=John+F+Kennedy+International+Airport,+Queens,+New+York+
11422&z=14&iwloc=A

Notice the two blue numbers? Those are your latitude and longitude (in that order) that you need for the Perl script to work, so write those down for the location(s) that you want to “hack” the Foursquare mayorship to.

How to Base64 Encode your Email & Password

Now the next step is that you need to create a single Base64-encoded string that includes your email and password in the format “my@email.com:myPassword”; without the quotes.

Luckily The Buzz Media just launched our super-sexy free AJAX Base64 encoder/decoder utility that you can use. So in the example of the following data:

CLARIFICATION: The online AJAX Base 64 utility does not log/record or remember the values you put in or it generates in any way.

  • Email: steve@apple.com
  • Password: applerocks

We would create the string “steve@apple.com:applerocks” and plug that into the Base64 encoder utility, hit “Encode” and we get back the Base64-encoded string “c3RldmVAYXBwbGUuY29tOmFwcGxlcm9ja3M“, sweet!

How to Run the Perl Script

Ok so now you are ready for the script, Mayank provided the source code to his script and it is included here for longevity (and the sake of completeness for this guide).

You will want to take this code and paste it into a new .pl file to run it, here are Google search results for “How to run a perl script” (Windows and Unix included):

#!/usr/bin/perl -W
use IO::Socket;
srand;
sleep(rand()*600);
my $sock = IO::Socket::INET->new(PeerAddr=>'api.foursquare.com', PeerPort=>80,
                                 Proto =>'tcp', Type=>SOCK_STREAM) or die;
$ARGV[1] += rand() * 0.0001 - 0.00005;
$ARGV[2] += rand() * 0.0001 - 0.00005;
my $str = "vid=$ARGV[0]&private=0&geolat=$ARGV[1]&geolong=$ARGV[2]";
print $sock "POST /v1/checkin HTTP/1.1\r\nHost: api.foursquare.com\r\nUser-Agent:"
            ." Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ "
            ."(KHTML, like Gecko) Version/3.0 Mobile/1C10 Safari/419.3\r\nContent"
            ."-Type: application/x-www-form-urlencoded\r\nAuthorization: Basic "
            ."XXXXXX\r\nContent-length: ", length($str)+2, "\r\n\r\n$str\r\n";
$_=<$sock>;

(Download Script)

The key things to note are that this script takes 3 command line arguments:

  • $ARGV[0] – Foursquare Venue ID
  • $ARGV[1] – Latitude
  • $ARGV[2] – Longitude

You also need to replace the “XXXXXX” in the 2nd to last line, with that big Base64-encoded string we generated above that was the encoded version of your email and password (login) to Foursquare.

You would need to get the Venue ID from the Foursquare website in some fashion. If you just search for a place, the URL includes the Venue ID that you need (see screenshot above). Once you have that, running the script to start checking yourself into places in random intervals between 0 and 10 mins would look like this:

perl foursquare-mayor-hack.pl 123456 32.221743 -110.926479

Where the name of the .pl file would be based on whatever you named your script, and the first number is the Venue ID you would have to get from the Foursquare interface somewhere, and the 2nd and 3rd arguments are the Latitude and Longitude we grabbed from Google Maps in the first section of the article.

DISCLAIMER: Foursquare will likely get wise to check-in abuse pretty quickly to avoid degrading the integrity of the service, so if you start abusing this script, we imagine you’d probably get banned from the service. Use this at your own risk.

Mayank goes on to explain why Foursquare will not be able to immediately protect against this type of gaming of their check-in system and what potential methods they could take to stop the fake checkins, but also equally notes the downsides to each approach.

He expects Foursquare (and likely Facebook Places and Gowalla) to remain susceptible to these type of hacks for a while.

Update #1: Alright, so I wrote a GUI app to do this for you, but for anyone interested, here are the relevant Java portions of the code to do it:

public static final String HOSTNAME = "api.foursquare.com";
public static final String API_URL = "http://" + HOSTNAME + ":80/v1/checkin";
public static final String USER_AGENT =
  "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1C10 Safari/419.3";
public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
 
... SNIP ...
 
Double lat = Double.parseDouble(latTextField.getText()) + (Math.random() * 0.0003);
Double lng = Double.parseDouble(longTextField.getText()) + (Math.random() * 0.0003);
String args = "vid=" + venueIDTextField.getText() + "&private=0&geolat=" + lat + "&geolong=" + lng;
 
URLConnection connection = new URL(API_URL).openConnection();
 
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Host", HOSTNAME);
connection.setRequestProperty("User-Agent", USER_AGENT);
connection.setRequestProperty("Content-Type", CONTENT_TYPE);
connection.setRequestProperty("Authorization", "Basic " + encodedAuth);
connection.setRequestProperty("Content-Length", Integer.toString(args.length() + 2));
 
DataOutputStream output = new DataOutputStream(connection.getOutputStream());
output.writeBytes(args);
output.flush();
output.close();

Tags: , , , , , , , , , , , , ,

About Riyad Kalla

Software development, video games, writing, reading and anything shiny. I ultimately just want to provide a resource that helps people and if I can't do that, then at least make them laugh.

, , , , , , , , , , , , ,

39 Responses to “How to Become Mayor for Any Place in Foursquare in 9 Perl Statements”

  1. Mayank L August 23, 2010 at 2:33 pm #

    Hi Riyad, thanks for the great tutorial on my little hack. Actually, I didn’t sniff any traffic, but just used Foursquare’s API docs. The security hole is quite evident just from there! :) -Mayank

    • Riyad Kalla August 23, 2010 at 8:06 pm #

      Mayank!

      I really enjoyed going through your original post. I tried to prototype it in Java (with a little GUI so people could just launch it and check in somewhere) but I kept getting back HTTP 401 codes (unauthorized) from the foursquare API.

      I gave up after a few hours of hacking, but I’d love to get it working. DId you run into any weirdness when interfacing with the 4sq API?

      I just pulled the Venue ID off the Foursquare website and the GPS from the “link” link on Google Maps; did I have that wrong?

  2. Mayank L August 24, 2010 at 11:23 pm #

    401 probably means that the Base64 encoding of the username and password are incorrect — did you put in a colon to separate the two fields? I would also double-check the HTTP headers. If my script works but the Java applet doesn’t, it’s probably something in the headers of the HTTP request. Good luck, and I’d love to have a link when you’re done.

    • Riyad Kalla August 25, 2010 at 12:03 am #

      Mayank,

      Hmmm I think you are right. What I’m doing to encode the username/password is as follows:

      Example username: sjobs
      Example password: applerocks

      String s = username + “:” + password;

      – then I take the “s” var, and base64 encode it into a String using the same code that is running: http://tools.thebuzzmedia.com/base64#encode

      and pass that in as a single blob as an addition param to:
      Authorization: Basic

      header.

  3. PTZ September 10, 2010 at 6:23 pm #

    I’m a cut and paste kinda guy with no prior coding experience. Where do I paste the $ARGV variables?

    vid=$ARGV[0]&private=0&geolat=$ARGV[1]&geolong=$ARGV[2]

    Using the example/variables below, what should the above code look like?

    Venue id = 1234567
    Latitude = 34.567890
    Longitude = -67.890123

    • Riyad Kalla September 10, 2010 at 11:38 pm #

      PTZ, even easier, right under the script, there is a “Download Script” link, just download the script and run it as:

      perl foursquare-mayor-hack.pl 1234567 34.567890 -67.890123

      – You’ll need perl installed, but there are plenty of instructions on how to do that easily enough online.

  4. PTZ September 12, 2010 at 8:31 pm #

    For clarification for others that are as ignorant as I am, using the example I gave, I can run it by typing in the following command?

    “perl foursquare-mayor-hack.pl 1234567 34.567890 -67.890123″ ?? No need to alter the script?

    You have to forgive me. I’ve never ran Perl before, let alone write it. However, I have installed it. My next step: learning to run script in my trial version of ActiveState. Thanks for your time, Riyad.

    • Riyad Kalla September 12, 2010 at 9:55 pm #

      PTZ, no worries. Yes that is exactly right, no need to alter the script, it is parameterized to take the variable arguments (venue ID, lat and long) from the command line, all the rest of it stays the same.

      Assuming 4sq hasn’t closed this hole in some way, yes then that should do the trick.

  5. Kev September 14, 2010 at 2:01 pm #

    I’m also getting the 401 with the downloaded copy of the script. I thought they might have started filtering on that specific user agent so I’ve tried several different ones at this point and none have worked. I’m also leary about using some online tool to do the base64 so, since I’m on Linux anyway, I just used the echo “username@domain.com:password” | base64 to generate the authentication string. I validated that tool against some other example pairs and it doesn’t appear the string is wrong.

    I’m at a loss and I’d really like this to work since there’s some a$$hat who’s checking into my venue simply because, and this is his quote, “I don’t have to leave my house.” I tried addressing this with foursquare and in two months they’ve not even acknowledged the request. I even tried moving the venue MILES away from him, then moving it back so I could check in, and their crappy cheat detection doesn’t even stop him from checking in when he’s nowhere near the venue. I think their service is doomed if that’s the support they’re going to offer and I see no reason why I shouldn’t be able to cron the one place I own. :/

    • PTZ September 14, 2010 at 8:30 pm #

      Kev,

      I never got it to work for me either. The hack tutorial here expects some level of knowledge of Perl. I have none. Since I use Windows, I altered the /usr/bin/perl path in the script to read /perl/usr/perl – I assume that was a correct move because when I executed the Perl script in the command prompt, it was the quickest to finish. Whenever I left it at /usr/bin/perl, it hung for 5-6 minutes before finally stopping.. However, as expected no indication is given if it succeeded or not. Subsequent refreshings of my Foursquare page revealed no checkins. I really hope they haven’t fixed the hole.

      I too was concerned about giving my password to an online tool. However, I created a fake account to test it anyway in case I was banned for hacking the service. I suggest you do the same to test it out. You could make a truce with the guy and ask him how he does it. Then, you could share with me. :D Most people like to share their knowledge as it inflates their perceived value.

      My only purpose for wanting to do the hack is to pull a prank on a buddy on the other side of the country. I want become King by one visit for every place he’s king at. It’s far from competitive for me. I don’t plan on using foursquare and I don’t plan on staying King of anything.

  6. Mayank September 14, 2010 at 9:03 pm #

    Hi all,

    Thought I’d clear a few things up. The script definitely still works. A couple of steps:

    (1) You have to edit the script and put the Base64 version of your username and password in the second-last line where it currently says “XXXXXXX”.

    (2) Leave the first line unchanged from what it is — if the script “hangs”, then it’s working. If you don’t want it to wait a random amount of time before it sends the checkin, remove line #4 from the script completely — where it says “sleep(rand()*600);”. Just delete the whole line.

    (3) To make sure your Perl is working, run the following command:

    perl -e “print ‘hello!’;”

    You should see a “hello” string printed. If you do, you’re all set.

    • Riyad Kalla September 14, 2010 at 9:48 pm #

      Mayank,

      What is the format of the text going into the base64 encode? If I can get that working I’ll release the Java GUI app to do this so you guys don’t need to try and run the Perl script and the soruce code along with it — I just didn’t get it working.

      @PTZ & @Kev — I absolutely appreciate not putting your username and passwords into the online base64 tool, but just so you know I actually wrote the code that does that encode and all it’s doing is using jQuery to pass through to a server side call to the Commons Codec API to generate the base64 text and return it — it’s not stored or logged anywhere and there are no server logs for the requests/responses.

      Just wanted to let you know that there is no shenanigans, but you are certainly welcome to keep using a local command line encoder.

    • Kev September 15, 2010 at 6:51 am #

      I’m glad to hear the Java tool is working! I was beginning to think they had tried to plug the hole.

      @PTZ: He’s able to check-in simply because foursquare doesn’t seem to be enforcing the “your phone thinks you are too far from this venue” option any more. I used to get that on my phone all the time if my phone thought I was more than about 275 meters from a venue even if I was standing right on it. It was probably the source of many complaints.

      So, as far as the perl goes, I’ve typically just removed the wait by commenting out the sleep line. I’m not a total noob to perl and was able to figure out the return by printing the $_, using Data::Dumper just to be safe. I’ll fire up an alternate account and try that with the perl given using the online base64 encoder just to see what happens. I’d also be happy to try out the java tool, especially if I can also pass it arguments via the CLI and cron it.

      BTW, I’ll take your word that the online tool doesn’t intentionally do anything malicious but I’m a CEH and paranoid by nature, so in my mind there’s the off chance that someone is sniffing my connection. I just didn’t want to take that chance with this account. ;)

      • Riyad Kalla September 15, 2010 at 6:55 am #

        Kev,

        Just so I feel like you trust me, please type all your credit cards into the tool and base64 encode them.

        *rubbing hands together very evilly*

        • Kev September 15, 2010 at 7:08 am #

          I tried but all I got back was this funny string

          MTIzNCA1Njc4IDkwMTIgMzQ1Ng

          ;)

  7. Riyad Kalla September 14, 2010 at 11:47 pm #

    Bingo!

    Ok guys I finally got my little Java GUI working to do this for you automatically. I just updated this post with “Update #1″ which includes all the relevant code from the program on how to do this and I’ll be releasing this for us shortly along with a blog post saying how to run it and use it.

    Just tested it and it worked fine, as it turns out I was encoding my password wrong in my previous snippet which is why I couldn’t get it working.

    Big thanks to Mayank for the clarifications and original idea.

  8. Riyad Kalla September 15, 2010 at 2:27 am #

    Alright guys, I finished the Java GUI implementation of the FourSquare mayor hack program, you can grab it for free (source code included, it’s GPL’ed).

    Here is a screenshot of it in action (I checked into the movie theater a few miles from my house when I took this):

  9. osman December 7, 2010 at 1:12 am #

    hi,

    for a long time it says working, how long it takes to be checked in?

    • Riyad Kalla December 7, 2010 at 7:18 am #

      osman, it should only take a few seconds. If you download the most recent version the status bar tells you which stage it is at, where is it hanging?

      • osman December 7, 2010 at 7:27 am #

        I have version is 1.0 there is no status bar, if there is a newer version, can you please share the download link with me?

        thanks.

      • osman December 8, 2010 at 12:31 am #

        IP restriction or anything that can affect the application, do you have any idea about this issue?

  10. Jonecir December 23, 2010 at 2:53 am #

    Hi Riyad, nice post.

    I’m new with Perl, so should I run this script only once per venue or as many times until I get the mayorship?

  11. Jonecir December 23, 2010 at 3:32 am #

    The java app (GUI) hangs and keeps showing the “Working…” status, never finishes!

    • osman December 23, 2010 at 3:35 am #

      he tries to fix it.

  12. Jonecir December 23, 2010 at 4:38 am #

    Well, i’m using the perl script, however I made about 15 checkins but foursquare is showing only 6. Any glues?

  13. hacking tutorials January 11, 2011 at 3:15 pm #

    great post man should check out destr0yed.com its a pretty cool hacking forum

  14. shukdog February 25, 2011 at 1:09 pm #

    Is there a way to tweak the perl script so the check-in is off the grid?

  15. Dhawal D March 9, 2011 at 3:03 am #

    This doesn’t help unlock badges does it?

    • Riyad Kalla March 10, 2011 at 8:24 am #

      Dhawal, I don’t believe so.

      • Dhawal D March 10, 2011 at 12:58 pm #

        sad! I wish there could be some workaround for badges as well :)

  16. szbr April 3, 2011 at 8:36 am #

    Hi Riyad!

    At first, I’d like to thank you for publishing this script and making the fantastic GUI program, it has helped me a lot. I just have a question: Is there any way to add a message to the check-in and publish it to twitter/facebook? I see that in the screenshot the author of the script, Mayank, had checked in at Revolution Cafe, saying “hi”. Could you help me with that?

    Thanks in advance,
    Bruno

    • Riyad Kalla April 12, 2011 at 5:09 am #

      Bruno,

      It would just be a matter of me adding that feature to the GUI app; I’ll see if I can add it later today for you guys.

      • Riyad Kalla April 12, 2011 at 6:49 am #

        Bruno,

        I just uploaded version 1.6 that added support for a shout message to go along with your check-in. If you go to the main hack page on the site you can download the new 1.6 version and give it a try.

        • szbr April 12, 2011 at 7:04 am #

          Wow, thank you very much for the fast reply Riyad, you helped me a lot! ;) Keep up the great work!

  17. Juan C, Del Carpio August 1, 2011 at 1:18 pm #

    Hey, bro! Today the Java GUI dosen´t work I think they change the API. Some solution?

  18. pb July 17, 2012 at 12:51 am #

    update for api v2?

Trackbacks/Pingbacks

  1. FourSquare Mayor Checkin Program w/ Source Code | The Buzz Media - September 15, 2010

    [...] few weeks ago we wrote about Mayank Lahiri’s working FourSquare checkin hack that allowed you to check in from anywhere provided you had the Venue ID and GPS coordinates for [...]

Leave a Reply


three + = 5