Advanced JavaScript obfuscation (or why signature scanning is a failure)

Published: 2009-04-07
Last Updated: 2009-04-07 08:35:45 UTC
by Bojan Zdrnja (Version: 1)
2 comment(s)

Couple of days ago one of our readers, Mike, submitted a URL to another heavily obfuscated JavaScript. It appeared very interesting so I decided to spend some time figuring out how it works. While it was not ground breaking, the attackers did show advanced knowledge of JavaScript and its uses of object access operators.

In this diary I will go through several obfuscation methods the attackers combined into one JavaScript file. For those interested in analysis, the malicious JavaScript file is still available at hxxp://84.244. 138 [dot] 55 / google-analytics/ ga.js –
be careful if you go there.

1) Usage of lists to return last values

This obfuscation method is very simple and it is used to assign a value to a variable. The attacker can use an arbitrary number of values in front which are all ignored. So, the following example:

mutae=(9e1,"it");

assigns the string “it” to the variable “mutae”.

2) Expanding the list with conditionals

The attackers further expanded the expression mentioned above with a conditional. Conditionals are simply if/then statements, all in one line with special characters such as “?” and “:”. The following is an example of such usage:

rgvij=(0.2e1>=4e1?.9075:"i"+"f");

I put special characters in red so it’s easier to see what’s happening here: the interpreter checks if 0.2e1 (which equals 2) is greater than or equal to 4e1 (which equals 40). If it is, the interpreter picks first part before the “:” character (.9075). It, of course, isn’t so the interpreter will pick strings “i”+”f” and concatenate them into “if”. Finally, this will result in the variable “rgvij” containing the string “if”. Not bad for obfuscation you’ll agree.

3) Usage of [ and ] operators when referencing objects

Those of you following our diaries here have seen the document.write() call million times already. This calls the method “write” in the object “document”. However, the same method can be called by using the [ and ] operators as well, as shown below:

document[“write”](“text to print”);

We can now easily see how this can be obfuscated with the following simple script:

a = document;
b = “write”;
c = “text to print”;
a[b](c);


Now, as you can imaging, attackers started combining all previously mentioned obfuscation techniques to make it much, much more difficult to analyze. To show one example from the JavaScript file I mentioned at the beginning:

aaa=(((0x4435,7.)>=(.61,9.12e2)?(1,4.033e3):(266,7.1e1)),((0x97<=.1?7.616e3:2.176e3),(.39<8e0?document:2032)))

All of this results in the document object being assigned to the variable aaa. Simple and effective.

You can also see why signature based scanning is doomed to fail here – there are so many obfuscation possibilities that signatures simply can’t cope with all that. Luckily, some (most?) anti-virus vendors are implementing behavior based detection or they are embedding their programs deeply into the JavaScript interpreter which allows them to scan values after obfuscation (the whole blob of code results in a document.write() call, no matter how the attackers call it).

--
Bojan
INFIGO IS 

2 comment(s)

Comments

So what happens when you have normal, non-malicious, auto-generated JavaScript that looks just as ugly and difficult to comprehend? For example, try any of the ads on the Yahoo! Finance query page (http://finance.yahoo.com/q?). There are ads for eTrade, Ameritrade, Fidelity, and Scottrade. All of them create some gigantic and difficult to parse JavaScript files. Are the ad companies using the same techniques to avoid blocking measures?
Jason, exactly my point why anti-virus vendors must not based their actions on signatures. Even when embedding AV products into the browser/OS this can lead to false positives.
I have to say that I'm strongly against such obfuscation that I see used more and more in legitimate applications as well :(

Diary Archives