Fun Times with Fiddler

I hacked my colleague’s multiplayer rocket game. I mainly did it for kicks. But also to make an important point about the server never trusting a client.

My colleague is developing a small game in his spare time. It’s based upon the Amiga classic Roketz and uses Google playn to cross compile from Java to various native platforms, such as web browsers, Android, and iOS.

I won’t disclose the URL of the beta since it’s not yet launched but here is a sneak preview of the browser version:

Being a multiplayer game, there is usually more than one rocket. When hit by enemy fire, your rocket will take damage and eventually explode. You use thrust and rotation to stay clear of walls. There are landing pods where you can recharge. This pretty much sums up the gameplay of this charming, retro style game.

Having followed the development on the sideline I had gathered a few pieces of information that made made me conclude that hacking the game would be feasible. I knew that all clients communicated with the server using JSON and web sockets. Also I knew that, by design, each client is responsible for keeping track of the state (such as position and velocity) of its own rocket and all shots fired from this rocket as well as for communicating this to the server. The server, in turn, would pass information about rocket and shot state of all other players. Clients would do hit detection themselves and when a rocket took sufficient damage its client would tell the server about this. I argued that there would be plenty of ways to hack this. My colleague stated that this was largely a hypothetical problem. And so, the challenge was on.

Snooping upon the network traffic it turned out that the browser version was serving gwt compiled javascript, which is not all that surprising from a Google framework which offers Java to javascript compilation. It was bit dense due to the formatting but it was unminified and it wasn’t difficult to feel the Java below the surface.

rocketcode

The linefeeds are escaped but it’s readable. This particular function looks like it might be called to update the position of the rocket.

Next step was figuring out how to replace this benign javascript with evil javascript that I could modify to do my bidding. I unsuccessfully spent some time trying to find a tool for the Mac. I then switched to Windows, downloaded Fiddler and immediately made progress. After googling a bit I found out how to make it work as a proxy server .. and how to make this proxy server replace selected files by acting as a “man in the middle”. 

Fiddler comes with a very powerful scripting language. Using this, I configured Fiddler so that if I hit the rocket game URL at post 8888, it would serve the files as if I had hit port 80 — except for a few select files which I made Fiddler grab from my own domain (I’m sure that I could have stored them locally as well, I just found the other solution first).

As “candidates for evil” I picked two javascript files which are pretty much standard gwt stuff. The *.nocache.js file exists only to detect the browser type and load the correct flavour of the second one. The second file, the one with the autogenerated and highly volatile name, contains all the interesting stuff, i.e. the code that was compiled from Java. The only reason that I’m also shadowing the first file it to make the hack a little bit more robust since the name of the second file is referenced within the first one so they kind of go together.

rocketredirecting

Shadowing with my copies of the javascript files. I’ve beeped out the domains from the screendump. Hope you don’t mind.

Next, I set up Fiddler as reverse proxy as described in the first section of this instructionhttp://fiddler2.com/documentation/Configure-Fiddler/Tasks/UseFiddlerAsReverseProxy

It worked! If I went to the normal rocket game URL but I specified port 8888, I got a fully functional game, but Fiddler substituted my copies of the files (as was easily verified by a console.log() statement):

letthehacking

Ignition!

To be able to really work with the javascript, I had to deal with the escaped linefeeds which were caused by gwt having encoded most of the javascript as an escaped string. I copied the text into Notepad++ and replaced all the \n linefeeds with proper linefeeds. Before uploading the edited file I would do the inverse substitution. This simple approach turned out to work fine.

Here is the malicious piece of code that I added:

hackcode2

The piece of javacode that I added to the update loop. Also a few lines here and there to pass the required arguments. Not the prettiest Javascript in the world but it does its job.

Behold the final result. Distributed from my client to your client through a trustful protocol .. kiss my heat seeking missiles!

Comments are closed.