Malicious Javascript Obfuscation: Divide et impera!

by David Maciejak
March 4, 2009 at 10:40 am

While malicious servers hosting “drive-by-install” scripts are continuously evolving, their goal remain the same: to silently drop and run malicious files on the victim’s computer. The flaws exploited by those Web Attacks Toolkits have been quite the same for a while, so what’s new in “malscripts” world?

As we pointed in a previous post, malicious web-based exploits writers worked out some advanced obfuscation methods to hide their malicious scripts from detection. It seems that this trend is taming down and being replaced by a simpler yet effective trick: split the malicious Javascript in multiple files.

Indeed, Javascript is a highly flexible language, where a given script can be cut in multiple files and stored at different places…

How does this method impact detection at IPS or/and AV levels?
As a matter of fact, a classic file-based detection is usually based on logical patterns that can be seen in the file (sometimes through a certain number of obfuscation layers). Thus, if for a given malicious file a required logical pattern actually sits in another file, the detection engine may fail to mark the file as malicious. See the code snippet below:

<script src="wokaono.js"></script><script>nnnnnnn["DownloadAndInstall"](SbSbSbSbSb);</script>

Here, the variable “SbSbSbSbSb” is declared in an external script named wokaono.js. This last script alone is not malicious, and neither is the quoted code above. It’s the combination of the two that gives birth to a malicious behaviour.

The detection logic therefore needs to be Javascript code flow-based, rather than Javascript file-based. That is to say, detection engines have to reconstruct the Javascript code stream before applying their detection logic. This, of course, requires implementing at least partially a Javascript embedded interpreter in the detection engine. Which has a performance cost, of course. And can be targeted by anti-emulation tricks. And so continues the race to arms…

But who needs drive-by-install scripts detection anyways, when one can simply detect the Trojan it aims at installing? ;)

Author bio: David Maciejak works as a security researcher for Fortinet. His primary role is to follow vulnerability trends and provide preventative protection to customers.

Malicious JavaScript obfuscation: To be called or not to be

by David Maciejak
February 25, 2009 at 8:17 am

Legitimate — and sometimes renowned — web sites are more and more subject to code-injection attacks; and it’s not rare today to find your every day site injected with malicious JavaScript code, which sole purpose is to silently redirect all visitors to malicious servers “behind the scenes.”

What happens on those servers is called a “drive-by-install” in the jargon, and results in malicious executable files being (again) silently pushed and run on the victim’s computer.

Details on the drive-by-install process, while interesting, are out of the scope of this post, which instead focuses on the initial, “silent redirection” code injected in the targeted web site.

This injected code is today systematically obfuscated, to evade manual and automatic methods of detection. Such obfuscation methods are very interesting to look at, as they are always evolving, in an ever-going race-to arms between malicious code authors and security analysts.

Our most security-oriented readers are probably already aware of the heavy use of the JavaScript “argument.callee” function made by malicious code authors to slow down the analysis of their obfuscated code.

As it name says, “argument.callee” returns the source code of the function that called it. For instance, the following code:

function my_example() { alert(argument.callee) }

Would pop up a message box displaying the content “function my_example() {
alert(argument.callee) }”

Malicious code authors use this somewhat odd function for fun, profit, and above all to irritate malicious code analysts: indeed, the decryption function of the obfuscated code uses as a decryption key… argument.callee! or in other terms, its own code.

Consequence: should an analyst change a single character in the decryption function, the decrypted code will be bogus, thus valueless.

Typical bits that an analyst may want to change in the decryption function would be “eval” for “print”, which eases the whole analysis a good deal.

Of course, there are ways for analysts to get around this, like for instance automatically replacing “argument.callee” by a static variable containing the expected key (i.e. the callee source code).

Malicious code authors seemed to become aware of it lately, as we started to see attempts to masquerade references to argument.callee. This is a “real life” example:

eval('a+rDgDu,mBeDn[tDs[.,c,aDl+lDe+e['.replace(/[D\[B\+,]/g,'')).toString().replace(/[^@a-z0-9A-Z_.,-]/g,'')

And so continues the race to arms…

Author bio: David Maciejak works as a security researcher for Fortinet. His primary role is to follow vulnerability trends and provide preventative protection to customers.