Friday 3 May 2013

Decrypting AES strings sent from server to an 'client-side browser based' Flash swf (using Javascript and C#)

So I was looking at this Flash-based website which used a really good security measure: it encrypted all GET and POST data using AES. 

This creates a ‘couple’ probs when testing/understanding how the app works, since we can’t easily see what is being sent to/from the server (by/to the flash swf running in the browser).

Ironically, because it is hard to see and change these values, apps that protect the client/server traffic this way usually have tons of server-side vulnerabilities, since it is easy to assume (by the devs and QA) that those values will never be changed (and it also makes it very hard to do any testing outside what the normal UI allows).

For example if we look at the login sequence, we will see that when the user submits its login details (entered via the Flash GUI), there is a request to /post.ashx that looks like this:

image

with the response looking like this:

image

this is actually a nice method to send Post data (in a way not easily viewed/modifiable by possible attackers).

Our objective is to read the response (i.e. decrypt that string). So how do we do it?

When looking at this type of problem it is important to take into account that:
  1. the client app (in this case the flash movie) is able to decrypt this message
  2. we have total control over the client app (since it is running on our box, in a browser that we have full access to).
So the first place to look is at the main flash movie (the swf file), since somewhere in there, we will find the ‘formula’ (i.e. how that flash movie is decrypting the data)

Now, if this was a .NET or Java app, I could already use the really powerful decompilation, reflection and process injection capabilities of the O2 Platform, BUT, since this is Flash, and there doesn’t seem to be a way to (easily) directly talk with the Flash VM from Javascript, we need to decompile the flash code.

After a bit of research/experimentation, I found the ActionScript Extractor tool:

image

which when feed the index.swf file (main Flash file from the app I’m looking at), produced this:

image

which is the entire actionscript source code :)

a real cool feature from this tool is the Save all... menu option:  

image

which will save all files into a local folder:

image

which can then be dropped into a file search tool, like this one (included in the O2 Platform)

image 

Ok, now that we have access to the source code of the flash movie, there are a couple things we need to find in this code base:

...the _decrypt function:

image

...the encryption KEY

image

...and the function (called by the form’s submission callback) that calls the _decrypt function:

image

Now, if this was .Net (or Java), I could just invoke (using reflection) this _decrypt function with the the cypher text received from the response :)

But since I don’t know how to directly invoke private Flash methods from Javascript (or a browser), and please ping me if you know how to do it, the solution is to replicate the decryption in Javavascript or .NET.

So let’s start by looking at how the _decrypt method works:

image

Here is a line by line description of this method (note that I have not programmed in ActionScript in ages, so I’m guessing some of this)
  • Line 328: param1 is a string that contains the text to decrypt
  • Line 330: _loc_2 gets the first 32 chars from the param1 string
  • Line 331: _loc_3 gets the rest of the param1 string (i.e. the string minus the first 32 chars)
  • Line 332: _loc_4 is a byte array with the value of the KEY string (which is the global variable we found earlier (see couple screenshots above))
  • Line 333: _loc_5 is a byte array of _loc_3 string (which is the param1 after the first 32 chars)
  • Line 334: _loc_6 contains the string “aes-cbc” (which is the type of cipher algorithm that is going to be used)
  • Line 335: _loc_7 is an IPad variable (I’m sure not related with the Apple product) with an object of the PKCS5() class
  • Line 336: _loc_8 is a ICipher variable with the execution result of Crypto.getCipher method , which is called with _loc6, _loc_4 and _loc_7 values. 
    • It is probably easier to read/understand this line if we read it like

      _loc_8
        =  Crypto.getCipher(“aes-cbc”, cipher_KEY, new PKCS5())
  • Line 337: calls the setBlockSize method of the PKCS5 object
  • Line 338: _loc_9 is set to the ICipher object casted into a IVMode class
  • Line 339: the IV parameter of the IVMode object is set to the first32CharsOfParam1 (see line 330)
  • Line 340: the decrypt method of the IVMode object is called with the cipherTextToDecrypt (see lines 333 and 331)
  • Line 341: returns a string representation of the decrypted string (which weirdly looks like it was done ‘on top of’ the cipherText)
Basically, what is happening is that:
  • The decrypt uses AES
  • The CipherKey is included in the Flash Movie
  • The IV part of the decryption is provided with every request (first 32 chars)
With this info, I googled a bit and found two ways to decrypt it

Decrypt Mode #1: Using Javascript’s Crypto-js

Using the code snippet from this StackOverflow thread:

image

I opened up the Util - Html Editor and WebBrowser.h2 script

image

and quickly got it to work (using the crypto-js library from https://code.google.com/p/crypto-js ):

image

You can see the script at this Gist: https://gist.github.com/DinisCruz/5510584#file-decrypt-using-javascript-html

Decrypt Mode #2: Using .NET’s System.Security.Cryptography Aes classes

Since it would be much more useful to script this using C#, I used O2’s C# REPL to create a gui to decrypt the messages.

Using the code sample from this MSDN article (http://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.100).aspx):

image

I created a C# script that:

1) consumed the decryptStringFromBytes_AES method as a lambda method:

image

2) used the stringToByteArray lambda method to convert hex bytes into strings

image

3) created a simple GUI to interactively (i.e. in real-time) decrypt strings

image

4) decrypted some sample text:

image

5) which looked like this:

image

6) if the text can’t be decrypted the textbox will be pink (I deleted the first char, i.e. 6):

image

7) if a valid string is provided the decryption will work in real time (note the that the first char is now 5 on the left-textarea and y on the right-textarea)

image

The source code for this GUI is on this gist: https://gist.github.com/DinisCruz/5510584#file-decrypt-using-c-h2-script-cs


Creating ExtensionMethods to handle the encryption and decryption (and adding them to the O2.Platform.Scripts folder)

Since these AES methods only use .NET framework APIs, they are a good candidate for O2/FluentSharp extension methods.

My first step is to add them to the O2.Platform.Scripts as a method in the _Extra_methods_To_Add_to_Main_CodeBase.cs file.

Here is the encrypt method (now back to a C# method, and with the more friendly name encrypt_AES)

image

Here is the decrypt_AES extension method

image

and the supporting method hexStringToByteArray extension method :

image

These methods can now be consumed by adding the //O2File:_Extra_methods_To_Add_to_Main_CodeBase.cs comment to the C# Script file:

image

And if we add another encrypt_AES extension method that receives the key and iv as strings:

image

We will be able to simplify the original code even more:

image

Here is a final example with a round-trip of encrypting and decrypting a sample string:

image

The source code for this last script is at this gist: https://gist.github.com/DinisCruz/5510584#file-decrypt-using-c-h2-script-cs