Thwarting New JavaScript Malware Obfuscation
I Don't Believe in Imaginary Property writes "Malware writers have been obfuscating their JavaScript exploit code for a long time now and SANS is reporting that they've come up with some new tricks. While early obfuscations were easy enough to undo by changing eval() to alert(), they soon shifted to clever use of arguments.callee() in a simple cipher to block it. Worse, now they're using document.referrer, document.location, and location.href to make site-specific versions, too. But SANS managed to stop all that with an 8-line patch to SpiderMonkey that prints out any arguments to eval() before executing them. It seems that malware writers still haven't internalized the lesson of DRM — if my computer can access something in plaintext, I can too."
I'm still not sure what I think of them.
I mean, it's a great idea. But they update their diary every day, which means for the most part, it's totally boring crap. Today's entry is a little different.
I still think of SANS as a bunch of old guys all sort of pontificating about the most mundane things. Wind back 5 years and I think they had a valid part to play, especially with the amount of viruses and worms flying around. These days, not so much. Security is so much higher on everyone's radar that they're a bit old in the tooth now.
This is still good work though and I do appreciate it. I just wonder if they need "handlers" and daily updates anymore, the Internet just isn't that risky anymore.
Tim
Is it just me or is this way of getting around it mind-blowingly obvious.
The techniques the malware writers are using are quite interesting though, i've never heard of arguments.callee.
It seems that malware writers still haven't internalized the lesson of DRM -- if my computer can access something in plaintext, I can too.
In fact, thats the lesson from any digital copy protection scheme, some of which precede DRM (at least the term DRM)
I guess I'm new to this whole Internet thing; I haven't been to SANS ICS before. But what's up with the color coded threat level indicator? Doesn't that seem a little pointless and similar to the ridiculed DHS Threat Level? I don't know, I respect their opinion, it's just harder to trust someone with an "internet threat level" indicator.
Who pays these freakin people ?!
I could sit here all day comming up with ways to put ghosts in the machine !
Wanna fight ? Bend over, stick your head up your ass, and fight for air.
This is too much, now we all will have to download a pre validator for javascript to view the code (what does this code do, i can't read this, I am an 80 year old grandmother...) before going to the webpage and view it...sucks to go on the web these days!
There are certainly legitimate uses of eval, and legitimate reasons to "obfuscate". Like to compress the script that you send to each & every client. The savings in bandwidth for you (and for them, especially if they're on dialup) can add up. For example: http://www.javascriptcompressor.com
This might sound like a troll, but it's just my limited understanding of this issue. So if we can detect the eval statements using this new technique, can we differentiate between what is malware and what is not? Or do legitimate scripts use eval too?
I turn off referrer headers for privacy (set network.http.sendRefererHeader to 0 in about:config in Firefox). Now it seems that it can also save me from malware :-).
Why would you want it enabled, anyway?
It seems that malware writers still haven't internalized the lesson of DRM â" if my computer can access something in plaintext, I can too.
The malware writers don't need a 100% success rate. They are simply tring to get their software on enough machines to build a nice bot empire.
See my journal for slashdot ID's by year. Mine created in 2005. http://slashdot.org/journal/289875/slashdot-ids-by-year
stop all that with an 8-line patch to SpiderMonkey
Cool, and now malware engineers will lose their jobs, you insensitive clods! Internet Explorer to the rescue!
Comment removed based on user account deletion
if you're using JSON (fairly common now), there's a good chance you're using eval(). Generally, it's overused and can be replaced with other techniques in a modern browser/js interpreter
Do you even lift?
These aren't the 'roids you're looking for.
This is not a detection method. It is merely an aid in reverse engineering, once you have found some malware that you want to analyze.
lets hope they don't try stuff like this:
http://en.wikipedia.org/wiki/Rob_Northen_copylock
it was hard. I guess there's no way to use special cpu modes, but you could still knock up a large amount (megs) of seemingly random data which contains code which you decrypt a few bytes at a time, re-encrypting the 'code' you just executed and hide, within thousands of jumps, loops and other messed up logic the actual guts of your code.
if you're using JSON (fairly common now), there's a good chance you're using eval().
Jeez, I hope not. I thought that by now everyone knew that using eval() is setting yourself up for failure.
Nothing for 6-digit uids?
Sure it may look like the attacker is cleverly trying to obfuscate their malware from prying eyes but usually they could care less about that. By the time you go reversing their code, they've already gotten the bulk of their victims anyway.
Rather, they're most often using it to make the code easy to replicate elsewhere. A lot of places they'll host it will inadvertently hiccup on certain characters in the code and change them. Like < to <, or + to space, or new line chars to end the string. Using an encoder that converts everything to alphanumeric is much easier to guarantee a successful propagation.
Especially true for XSS worms
Surely, that should read -
evil()
?
It is after all, an inbuilt function of Javascript.
See http://www.json.org/js.html
If you're using JSON, you're using eval(). Sure, there are some workarounds that avoid calling the eval() function directly, but in the end, they all eval-uate remote code.
JSON parsers use eval() after checking the JSON string to make sure it's actually a JSON string.
cat http://www.json.org/json2.js | grep eval(
Have you driven a fnord... lately?
You must wait a little bit before using this resource; please try again later.
If someone can modify your JSON messages, they can inject script into any .js files requested.
If your JSON generation is unsafe, then go home.
Happy moony
> I'm glad you highlighted that line of the summary. The point of the obfuscation was to slow down analysis of the code and require special tools (SpiderMonkey) that average web users don't have. Here the malware author clearly won. The article author spent hours figuring out a new obfuscation technique and writing an article about it.
Actually, it looks like they spent more time writing about it than solving it. That 8-line patch isn't exactly complex, and it appears that it'll kill most techniques they can use. Their only hope now is to rely on various variables that won't be present in the interpreter, but there's a limit to how complex those can be.
Also there's the fact that the guy's script was buggy thanks to case sensitivity (he named a file .HTM instead of .htm). But you have a point about them only needing to slow folks down, even though I don't think they're getting slowed down very much compared to all the work going into those obfuscation techniques.
Comment removed based on user account deletion
Isn't that the thing I've got turned off in my preferences?
Have gnu, will travel.
It isn't an either/or choice, but programs with verbose variable names (which is typically one of the first targets of javascript compression: "replace timeSinceLastUpdate with r") compress disgustingly well. You may find that the gzip compression is effective enough that the obfuscation isn't worth the various attendant headaches (maintaining two versions of the code, etc).
Help poke pirates in the eyepatch, arr.
I did a fairly detailed analysis of an instantiation of typical Javascript malware these days.
sigs are a waste of space
If you're using JSON, you're using eval(). Sure, there are some workarounds that avoid calling the eval() function directly, but in the end, they all eval-uate remote code.
Did you even bother to read that page that you directed me to?
To defend against this, a JSON parser should be used. A JSON parser will recognize only JSON text, rejecting all scripts. In browsers that provide native JSON support, JSON parsers are also much faster than eval.
So, you're claiming that a JSON parser, which is faster than eval, checks its input and then calls eval. I think I see a contradiction.
Or are you talking about legacy browsers that don't yet provide JSON support? In that case, I hope that you aren't invoking eval either directly or from some home-grown function library, but are using that json2.js that you point to; yes, it sometimes (not always!) uses eval, but only after checking that the browser doesn't provide a native JSON object. Furthermore, if you eliminate comments and blank lines from json2.js, you're left with 174 lines of code, of which one line invokes eval, and most of the rest make sure that there isn't anything bad hidden inside the text. I suspect that those 173 lines of code are better than anything that you or I could whip out on short notice.
Nothing for 6-digit uids?
Was there even a point to your tirade?
My comment was in reply to your sweeping generalization that “everyone” knew using eval() is just setting oneself up for failure. json2.js is proof that, with adequate attention given to security, eval() usage isn't a problem.
To the best of my knowledge, as of this writing, the only browser that supports native JSON is Firefox 3/Mozilla 1.9: http://developer.mozilla.org/en/docs/nsIJSON -- this still excludes most people, however.
The rest all require an external parser, such as Crockford's, which eval()s JSON code for everyone else. If you personally feel like writing a JSON parser based entirely on a combination of regex and String.substring()/String.indexOf(), for the sole purpose of avoiding evil eval(), be our guest.
Have you driven a fnord... lately?
You must wait a little bit before using this resource; please try again later.
My point was that programmers shouldn't use eval() in Javascript, just like programmers shouldn't use goto statements. That doesn't mean that you can't use tools that use those features (I use yacc and lex many times a year), it just means that using them is very hazardous and best avoided. And yes, I realize that this means that there are exceptions to the rule, since it is programmers who write those tools, but those exceptions are very, very, limited. Thinking that you can whip out some code that uses eval() just because json.js uses it is a supreme act of hubris. I wouldn't let anyone I work with use an eval(), no matter what the circumstances, because circumstances change and it's unlikely that the code will change in lockstep. Nor would I use some random library that someone found somewhere. I'd want code that had been looked at by a lot more eyes than mine and tested in the field in a lot of deployments. Crockford's stuff meets that criteria. Anything you might come up with is unlikely to.
Nothing for 6-digit uids?