Penetration Testing Flash Apps (aka “How to Cheat at Blackjack”)
18 Sep 2017
Reading time ~6 minutes
In this post, we will walk through detailed steps to intercept, review, modify, and replay flash-based web apps. For demonstration purposes, I’ve selected a blackjack-style card game. We will work to control what cards are dealt, as well as how a score is calculated.
The intent of this blog is to demonstrate how a penetration tester would work with a flash app, looking for client-side code that can be modified for unintended results.
The high level steps are as follows:
- Intercept the .swf file and save it locally using a proxy.
- Unpack the .swf file using a decompiler.
- Modify the code to alter application behavior.
- Replay the .swf via a valid HTTP session.
Important Note: In this tutorial, we are working with a free online blackjack game. The site I chose offers no monetary rewards for winning. There was no attempt to access or modify restricted resources. Please use this information for good (pentesting, developing secure code), not evil (being a dick).
I’ll be using a Mac, but each tool I mention will work equally well in Linux and Windows. You’ll need the following:
- Burp Suite: You should be familiar with this, have it installed, and have your web browser configured to proxy requests through it.
- ffdec: This is a really slick Flash decompiler. It’s free. Download it and have it ready to go.
- This file: Save it to your computer somewhere, we’ll need it in a bit.
Intercept the SWF
Configure your web browser to send your requests through Burp. At this point, you do not need to have “Intercept” set to on. Allow the requests to flow through freely.
Clear the cache in your browser. We need to load the .swf file from scratch, and it could be cached in there if you’ve already loaded it recently.
Now browse to the site containing your flash application and wait until it is fully loaded. Take a look in “HTTP History” under the “Proxy” tab of Burp. You should have an item with “swf” noted under the “Extension” column.
As shown above, select that line item and look in the “Response” > “Headers” tab below. You should see a bunch of random crap – this is the compiled content of the swf file. Right-click in that same section and choose “Copy to file” from the context menu that appears.
I saved mine to “blackhack.swf” on my desktop.
Note: You may also be able to access the cached version of the .swf file in your filesystem. I prefer the proxy method for consistency and reliability.
Unpack The .swf File Using a Decompiler
You should already have ffdec installed and this file saved to your computer. Launch ffdec and choose “Settings” > “Advanced Settings” > “Paths”.
See the item that says PlayerGlobal (.swc) path? Click the folder icon and navigate to the file you downloaded. It should look like this (I obfuscated my homedir name):
After you save this setting, you may need to restart the application to continue.
From here, simply choose “Open” and browse to the “blackhack.swf” file. If you saved the header properly (in full, not just a selection) you should see a tree view like the following:
Modify The Code to Alter Application Behavior
This is highly variable depending upon the application you are testing. You’ll want to spend some time browsing through all of the folders exposed, especially ones with juicy names like “scripts”.
I’ve found a script called “Play” which seems to have the major functions driving this particular game.
We want to see if things like scoring and card selection are handled on the client side. If so, we should be able to modify the outcome of the game.
I’ve found a simple code snippet we can modify. This array looks to be describing the suits in the deck = Clubs, Diamonds, Hearts, and Spades. You can see the original here:
Click on the “Edit ActionScript” button below the code. I went ahead and modified the array “this.arrSuit” to have only one character. If the dealer starts giving me diamonds 100% of the time, I know I’ve verified that the deal is being handled by client-side controls and not server.
After making the change, it is important to click “Save” both below the code and also in the menu bar at top. The first saves the individual script and the second writes it back into the .swf package.
It’s now safe to close the application. There is no need to repackage or recompile, this ffdec inline editing is pretty damn slick.
Replay The .swf Via a Valid HTTP Session
We now need the web site to execute our modified version of the game within a valid session. This may be important if there is server interaction such as publishing high scores or collecting rewards.
Completely clear your browser cache, and close and relaunch your browser. Your swf is most certainly cached at this point which would prevent you from completing the next steps.
Inside Burp, turn “Intercept” on. Go back to the site with your flash app and go through the process of reloading it. You’ll need to manually “Forward” each request as it comes through. Sites that host flash games usually have a shit-ton of advertising, so you may have to clear a few random requests.
PAY VERY CLOSE ATTENTION! We’re looking for the GET request that contains the .swf file. Mine looks like this:
When you see that, you’ll want to right-click in the box of raw text and select “Do Intercept” > “Response to this request”. This will allow us to modify the application before it hits our browser.
AFTER you have done that, you can now click “Forward”.
Depending on what other things are going on in your browser, you may need to click forward to get past some other random traffic (browser plugins, etc) that were queueing up. Be on the lookout for something that says “Response from http:///……..
In here, we are basically going to reverse what we did in step one. Remember all of that garbage text under Headers? Select it all and delete it completely. It should now look like this:
Now right-click in the empty area and select “paste from file”.
Select the blackhack.swf file we modified. It should fill that blank area back up with garbage. You can now select “Forward” and turn “Intercept” to off.
The game should now load in your browser, and you can see if the code modifications are affecting gameplay. As you can see from the image below, we are dealing 100% diamonds from the deck now.
That’s gotta be some kind of good luck, right?
Obviously, we’d want to demonstrate something a bit more impactful when helping a developer understand why this type of information should be controlled on the server.
I found another piece of code that assigns a numerical value to each card. This was a pretty quick hack, ensuring that each card had a value of 10. See anything fishy about the screenshot below?
This particular game would be a bit of work to deal a blackjack every time, as there is logic built in for what to do if a card is already dealt, etc. But, as we have complete control over the dealing and scoring logic – it could be done.