FoE Decryption

Python tool and tutorial of how to decrypt the Forge of Empires Flash/SWF and generate request signatures

Used by FoE Bot for request signature generation.

Purely educational and to fuel curiosity

:exclamation: This project is no longer maintained by myself as I no longer player FoE, an from what i've heard they have/are switching to a 'HTML5' based solution. This approach may still work but you will need to make sure the version and secret (below) are up to date. :exclamation:

Summary

:star: Star the repo if you use this, would be nice to know if people are :) :star:


Explanation

Forge of Empires is a Flash based web and mobile game. Under the hood it uses simple HTTP requests to fetch data and perform operations whilst the game is being played, to build things, start production, collect resources, etc.

These HTTP requests contain a header called 'Signature' which in turn contains a hash of the request being sent. This is used to sign the request so that the server can verify it hasn't been tampered with and also to make it more difficult to manipulate the request.

If we want to issue our own requests then we also need to generate this signatures, for which we need to know how this hash is generated. To find this out we need to look inside the client.

The game's Flash application is called Main.swf which can be downloaded and run through a flash decompiler like FFDec, however, the Main.swf has been 'tampered' with so that tools like this cannot read them.

As a result of this, the standard Flash player also cannot read/load the SWF, so the 'tampering' needs to be reverted before it can be loaded. This is were Preloader.swf comes into play.

So, same kind of deal, we can open Preloader.swf inside of FFDec to see how it reverts the 'tampering', however, another layer of 'lets make things difficult' is that Preloader.swf has had its code obfuscated so it is harder to read and follow. Luckily, FFDec can (somewhat) fix this for us, replacing the obfuscated class, method, variable names with things like 'class_1', 'method_5', 'var_11'.

We can then see a file called 'Preloader' with in-turn instances a class called 'class_3' inside of 'package_1' (after the name changes), this class and the methods in it essentially just bit-shift a few specific bytes back to their originals, 'decrypting' the Main.swf (decrypting in a very loose sense of the word).

Then we can search for 'Signature' inside of Main.swf, finding where each and every request is constructed, and then find how the Signature is generated.

The crux of it is, it's just a simple MD5 of the user's key, a static salt (which was 'forgeofempires', now its a random string) and then the request body as JSON, all concatenated together, converted to hex, and then only the first 10 characters are used.

This can be seen inside of 'scripts/de/innogames/shared/networking/providers/JSONConnectionProvider'

For example, a request to get the player's great buildings (requestId is just an incrementing number, but doesn't seem to affect anything), in Python:

import json
import hashlib
from collections import OrderedDict

payload = [OrderedDict([
    ("requestClass", "StartupService"),
    ("requestId", 0),
    ("requestData", []),
    ("__class__", "ServerRequest"),
    ("requestMethod", "getData")]
)]

encoded = json.dumps(payload).replace(' ', '')

user_key = "thisistheuserskey"
# As of 12:00 28/08/2017 UTC (version 1.108 / timestamp 1503565657)
secret = "yOy3qr/HW9NZ9iLXjYLVADMO7wKMZcTgsUVqcqkl+h7ddVER8sHYEH6bxsSJOzerXci2kJKcMM9xQZjmdVD08Q=="

data = user_key + secret + encoded
# This should be the same value you see for the 'Signature' header in the request
signature = hashlib.md5(data).hexdigest()[0:10]

All-in-all this turned a couple of minutes exercise to craft HTTP requests into a 10-15 minute exercise, not sure it was worth Innogames going through all this trouble to hide it.


HOW-TO

Fetching FoE SWF files

If the 'encryption' algorithm hasn't changed

If the 'encryption' algorithm changes

Opening up Main.swf