FusionFall Retro: Using Fiddler to debug WebAPI

107 views fiddler reverse-engineering web

by CPunch

[Repository for this project is here]


[NOTE: If you're from the FFU dev team first of all I have major respect for you guys. Recreating a childhood classic of mine means so much to me and shows you guys are extremely talented. Second of all, instead of banning me, I would be more than happy to help you guys! Please contact me at [email protected] for more info.]


In my last post, I talked about their electron client and how they verified their URL argument that is passed to the client by the launcher. In this post, we'll be learning about how the launcher logins and passes everything to the client. The launcher takes care of logging in, getting a session token, listing the different games you can join (they have 2 versions of the game, only 1 of which is public), updating client files and of course, launching the game. If we could recreated the launcher, logging in, getting game token and launching the client, we could launch our own custom client! Since I expect a lot of web api requests to be going on, I decided it was best to use a tool like Fiddler to intercept these requests. I had to do this part on Windows because I was having trouble getting Fiddler to work system-wide in Linux :(. Make sure you have Fiddler's cert installed system-wide in Tools -> Options and click "Decrypt HTTPS".



Now I ran the launcher and tried logging in.



So now that I've captured the login, I cal look at the request.



There's a param called 'ffudevid' which is literally just the MAC address of your first network device as enumerated by Windows.


[My MAC Address & the ffudevid]



We also can look at what information it gives us,



So, when we login, it sends a requests to https://www.fusionfalluniverse.com/api/launcher/login/ with the parameters of username, password, and the ffudevid (which they probably log for MAC bans), and then it returns our session ID, access_level, username, and an error code. That session ID will come into play later. Next, the launcher gets the list of games and what we are allowed to play due to our access_level. This requires our session and username.



This returns a list of 2 games, retro and legacy. Retro's access_level is 99, while Legacy's is 20. This also includes stuff like the *Command Line* to use to launch each game and *what to install/uninstall*. Also news stuff is included.



This contains a bunch of useful information which we'll get back too later. Next when we try to launch the game, it'll get hashes of all the files of the client and compare them, if they're different it pulls the new one from the server & replaces it. Next it'll send a request to get a token for the client using my session ID and username.



Nice! Now, we have enough information to simulate the launcher and launch our client! Knowing this information, I created a custom launcher which not only supports the original client, but also has support for custom clients! I'll talk about that in my next part, but first let's create our own launcher so we'll be able to even run a custom client. Recreating the launcher is actually pretty simple. I tried to make my recreation of the launcher as close to the original as possible. That includes having the same cookies, making the same requests, and of course sending valid MAC addresses, invalidating the game token after the client closes, ect.


To show how this will work, I created an example of just 1 of the WebAPI requests. We'll be '''''''checking''''''' for an update.


import requests

SPOOFED_CLIENT_VERSION = "1.0.5"

# keeps cookies & headers across api requests
launcherSession = requests.Session()

# mimic launcher headers
launcherSession.headers = {
    'User-Agent': 'ffu-launcher', 
    'Launcher-Version': 'ffu-1.0.5',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Connection': 'Keep-Alive',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'en-US,*',
    'Host': 'www.fusionfalluniverse.com'
}

# get update information
ret=launcherSession.post("https://www.fusionfalluniverse.com/api/launcher/check_update/", data='current_version='+SPOOFED_CLIENT_VERSION)
print(ret.text)


In this script we mimic the EXACT headers that the launcher uses, this'll allow us to make requests too their WebAPI. Then we send a request "https://www.fusionfalluniverse.com/api/launcher/check_update/" with our client version (1.0.5). And...



It works! Our request went through! Now, the rest of the API is fairly simple and straight forward, although there is still the "ffudevid"! As stated before, ffudevid is just the first MAC address as enumerated by windows, because of this we could also just spoof our MAC faily easily with any free program online (like Technitium). But it would be a whole lot funner to just create our own launcher, and supply a randomly generated MAC! So that's exactly what I did.


First of all, I generated a valid MAC address and sent that with the login request.

# this will generate a random mac address registered to Xensource Inc.  
FAKE_MAC = "02:00:00:%02x:%02x:%02x" % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) 


Then I mimic the launcher, passing session tokens and etc. to the correct webAPI call. In the end I've created a pretty useful barebones launcher. You can even launch a custom client using the -client flag!



And of course, passing the -client flag will exploit that bug we found in the first post to go to any URL!



In my next part I'll be creating a custom client! See you then!!

Oct 13, 2019 by CPunch