Better late than never, this short Weely Web Hack shows how to deliver covert JavaScript in a SWF file.
For those too impatient to read the article, you can skip to the demo here:
Thanks to Flash's ExternalInterface, it is possible to call JavaScript functions from an SWF. A typical example looks something like this:
function someJSFunction( input ) { alert( 'input: [' + input + '] received!' ); }
ExternalInterface.call('someJSFunction', "Some value");
When the above Actionscript is put into a Flash SWF file and executed, it'll call the JavaScript function someJSFunction with the parameter "Some value" - predictably resulting in an alert dialog popping up.
Fortunately though, the above example can be easily written using pure Actionscript. That is, the someJSFunction method can actually be defined as part of the ExternalInterface call!
Here's the updated Actionscript, which behaves the same way, but without relying on a JavaScript counterpart:
ExternalInterface.call( "(function(){ window.someJSFunction = function( input ) {" + "alert( 'input: [' + input + '] received!' );" + "})" ); ExternalInterface.call('someJSFunction', "Some value");
Notice that the first ExternalInterface.call() invocation sets window.someJSFunction to a dynamically created anonymous function which does the same thing as the JS example from above. Of course, it's not necessary to create the function in the window scope if the only invocation will be immediately following. The following code works the same way, but without polluting the window scope:
ExternalInterface.call( "(function(input){alert( 'input: [' + input + '] received!' );})" , "Some value");
Notice that the entirety of someJSFunction has been collapsed away into a dynamically generated JavaScript function.
Suppose we still want to create the someJSFunction method at window scope, but using the original JS code. That is, define "function someJSFunction" rather than "window.someJSFunction =".
This can be done using setTimeout() with a timeout value of '0' (immediate). Consider this new example:
ExternalInterface.call( "(function(){setTimeout(\"" + "function someJSFunction( input ) {" + "alert( 'input: [' + input + '] received!' );" + "}" + "\",0);})" );
The inner JavaScript remains the same as in the first example, but now it's still wholly contained within Flash!
Note: In theory, window.eval() would work just as well as setTimeout(,0), but in practice, only the latter works. This may be a bug in Flash, or JavaScript, or both.
To this end I have created a Covert JavaScript haXe source code generator which takes arbitrary JavaScript and generates a haXe source code file from it which can be compiled into a covert JavaScript delivering SWF. Note that the generated source code has instructions on how to build a SWF from the haxe file and how to embed it into an HTML page.
I'm not sure what the use-case is for such as device as of yet other than perhaps extreme JavaScript obfuscation. Because the JavaScript code is contained in a SWF, it would be fairly difficult to get at and read. Doing a View Source on the page would reveal nothing useful, and neither would walking the DOM using a tool such as Firebug.
Of course, the covert JavaScript is just stored in an array of strings in the Actionscript of the SWF, so a SWF decompiler would probably make short work of exposing it.
Anyway, I thought it was an interesting idea - worthy of a blog post. Enjoy! As always, I'll be happy to answer any questions.
Got something to say?
or, read what others have said...