A popular approach to obfuscating malicious browser scripts involves using JavaScript itself to decode the original script when the browser processes the malicious web page. Malware analysts can often bypass such defensive measures by running the script in a standalone JavaScript engine to observe its execution or examine its output. Mozilla's SpiderMonkey has been a common choice for this task. Google's V8 engine is a powerful, though lesser-known alternative for accomplishing this.

Deobfuscating JavaScript Using SpiderMonkey

SpiderMonkey is a standalone JavaScript language that is used in Firefox. We can use SpiderMonkey to run the malicious script outside of the browser, letting it deobfuscate itself. At the end of the deobfuscation process, the malicious script often transfers control to the newly-decoded code using document.write() or eval() commands.

One way to "spy" on such commands is to compile a customized version of SpiderMonkey, as Didier Steven did when tackling this challenge. Another is to use JavaScript itself to define document.write() or redefine eval() commands like this:

document = { write:print };

eval = function(input_string) { print(input_string); }

You can safe these definitions into a separate file (e.g., file.js) and load it into SpiderMonkey before the file containing the malicious script (malware.js). SpiderMonkey ("js") lets you do this from the command-line like this:

js -f file.js -f malware.js

In this case, SpiderMonkey will define the necessary objects and methods according to file.js contents, then execute the malicious script. The script will likely deobfuscate its protected components. If the script executes document.write() or redefine eval() at the end of this process, SpiderMonkey will show you the output, which should be the decoded contents.

SpiderMonkey runs best on a Unix platform. You can compile it from source code by following Mozilla's build instructions. On a Debian or Ubuntu platform you can install SpiderMonkey using the "spidermonkey-bin" package.

Deobfuscating JavaScript Using V8

V8 presents an alternative to SpiderMonkey, which you can use in almost the same way for deobfuscating malicious browser scripts. It's often useful to have different tools for the same task, in case one of the tools works better than the other. Since V8 is the JavaScript engine built into Google Chrome, you may prefer to use V8 when analyzing malware designed for the Chrome browser.

As we covered in an earlier diary, browsers differ in how they implement arguments.callee ; this means that a malicious script might deobfuscate fine on Chrome (V8), but not on Firefox (SpiderMonkey). In particular, SpiderMonkey optimizes the results of the arguments.callee.toString() call, while V8 does not. There are other differences in the way V8 and SpiderMonkey are implemented as well.

To build V8 from source code on a Unix platform, follow Google's instructions. First, install the tools necessary to get and build V8. These include g++, SVN and scons, which are available as packages on Debian and Ubuntu platforms. Then download the source code using SVN:

svn checkout http://v8.googlecode.com/svn/trunk/ v8

Then build the tool, including its command-line interface shell called "d8" using scons:

cd v8

scons d 8

Though Google's scripting engine is called V8, use the " d8 " command to invoke it, just like you'd utilize the " js " command for SpiderMonkey:

d8 -f file.js -f malware.js

SpiderMonkey and V8 will be installed in the upcoming update to the REMnux Linux distribution. If this topic interests you, check out the Reverse-Engineering Malware course I'll be teaching at SANS on-line in January-February 2012.

-- Lenny

Lenny Zeltser focuses on safeguarding customers' IT operations at Radiant Systems. He also teaches how to analyze and combat malware at SANS Institute. Lenny is active on Twitter and writes a daily security blog.