Security through obscurity doesn't work. Every once in a while I like to prove this fact, by getting worldwide high scores on vulnerable leaderboards. The first time I did this was to Area Flat 3 (which was an awesome game when I was in elementary school, and is still pretty fun). Check the all-time top 100 scores for H4X0R (I know, not very original; I was 13, sue me). But that hack was child's play compared to this one.
Recently I noticed that a Facebook game called Fast Typer 2 was becoming popular with my Facebook friends. I played it a few times and got the third-best score of all my friends when I noticed that the global leaderboard had some unbelievable high scores. Like 9223372036854775807. I was struck by the fact that: a) they use at least signed 64-bit integers to hold people's scores; and b) the leaderboard is vulnerable. In fact, the top 27 scores were obvious hacks. So, I got to work.
The first step is to enable the Tamper Data Firefox extension. I usually run Chrome, but I keep Firefox around for extensions like this. After playing the game again, I'd logged all the necessary communications to submit a high score. The Flash game POSTs to a few servlets at http://minifb-typer.mindjolt.com/servlet/<servlet>, with the NextSubmitScore servlet looking particularly interesting. Examining the POST data from that request, I found that there's a "score=" parameter right there. So I played again, but tampered with that request. I changed the value of the "score=" parameter to something much higher, and the game told me I had a new personal best score -- but with my real score from the game, not the tampered one! Turns out that "score=" is a red herring.
Next, I had to decompile the SWF file itself, to figure out what was going on. I used swfdump from swftools, but it just dumps the AVM2 opcodes. There's no true SWF decompilers that work for ActionScript 3 on Linux, it seems. No matter, soon I had figured out that the game itself loads an internal API from another SWF file, "api_local_as3.swf". After reading through some of the functions I finally found the important one, "createSession". This function makes an associative array that holds your score, a "token" which is always 1, and "delta" and "deltaAbs", with unidentified purpose. This array is converted to a string, then RC4 encrypted, with an 8-byte key, which is -- well, I don't want to spoil the fun, but it starts with "537E". True enough, the NextSubmitScore requests have a "session=" parameter, with a giant hex value. Decrypted, it looks like this:
So the procedure to hack the game is this: play the game, tamper with the "NextSubmitScore" request, decrypt the "session=" parameter, change the score to a gigantic number, encrypt the new session string, replace the request parameter's value with your tampered one, and submit it. If you do it right, the game will greet you with "Congratulations! You've just set a record for all of Facebook!"