February 8, 2010 - 13:05 UTC - Tags: blitzableiter flash security xss
As shown in several
articles and
mailinglists lately, input validation is also required when developing flash files. However a lot of sites already have a lot of existing flash files, to which they may or may not have the source code available, possibly because it was created by a 3rd party. However there is still hope.
Introducing BlitzableiterAt
26c3,
FX of Phenoelit held a
presentation called "Defending the Poor - Preventing Flash Exploits". This talk introduced
a great tool called Blitzableiter. This tool is written in .NET,
it's open source and allows you to patch flash files when you don't have the source code available.
You decide how to patch a given function (like getURL) by supplying a script (in Blitzableiter this is called a Mod). Writing such a Mod is rather complex, because it requires you to understand the underlying ActionScript byte code (assembly like function + stack). When downloading blitzableiter, documentation for the action script byte code is included. When a script is ready, patching a file is trivial and can be done by "anyone".
Example scriptAs described in
my previous blog post a common bug in banners and ads, is that they will take the target url the user will go to when clicking the flash, as an input. When clicked, they will call getURL(). So what we'll do is patch getURL() and add a whitelist for the urls.
We want to move from
getUrl(url, target)
to something similar to
if (url.substring(0,7) == "http://" || url.substring(0,8) == "https://" || url.substring(0, 1) == "/") {
getURL(url, target)
}
However in the flash byte code, it's just as easy to implement it like this:
if (url.substring(0,7) == "http://" ) {
getURL(url, target)
}
if (url.substring(0,8) == "https://") {
getURL(url, target)
}
if (url.substring(0, 1) == "/") {
getURL(url, target)
}
As we can see, we now have a repeating pattern looking like this:
if (url.substring(0, whitelistedUrl.length) == whitelistedUrl) {
getURL(url, target)
}
This pattern is quite easy to implement and repeat in actionscript byte code.
When the getURL function is about to be called, there are two parameters on the stack - first the url, and next the target window. We want to validate the URL so we have to swap the parameters on the stack:
ActionStackSwap
Then we duplicate the url, so we can use it inside the if:
ActionPushDuplicate
To call substring, we first have to push the zero parameter, and next the length of string we will extract:
ActionPush UInt32:0
ActionPush 'String:http://'
ActionStringLength
Now we push the string again to compare it inside the if, and then make the comparison:
ActionPush 'String:http://'
ActionStringEquals
Then we execute the if, and if it returns true we jump to the getURL() call:
ActionIf ActuallyDoGetUrl2:
Next we repeat the pattern once for each part of the whitelist:
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:http://'
ActionStringLength
ActionStringExtract
ActionPush 'String:http://'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:https://'
ActionStringLength
ActionStringExtract
ActionPush 'String:https://'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:/'
ActionStringLength
ActionStringExtract
ActionPush 'String:/'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
Now if none of the ifs above has hit, we need to remove the two original parameters (url and target) from the stack, and exit the call. And we have to define the label used in the ifs above and make the actual call. Before we make the call though, we have to remember that we swapped the parameters in the beginning of the script so we have to swap them back. The full script then looks like this (with comments):
# Swap the stack entries, as Target is on top and URL is below that
ActionStackSwap
# Duplicate the destination URL
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:http://'
ActionStringLength
ActionStringExtract
ActionPush 'String:http://'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:https://'
ActionStringLength
ActionStringExtract
ActionPush 'String:https://'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
ActionPushDuplicate
ActionPush UInt32:0
ActionPush 'String:/'
ActionStringLength
ActionStringExtract
ActionPush 'String:/'
ActionStringEquals
ActionIf ActuallyDoGetUrl2:
ActionPop
ActionPop
# Exit
ActionJump EndOfPatch:
ActuallyDoGetUrl2:
# This is executed when the origins match
ActionStackSwap
# Perform Action
ActionGetURL2
EndOfPatch:
For your convenience, here is
a link to download the script