Technology / Web /
08 May 2009
Decoding Obfuscated JavaScript
Earlier today I got an instant message from a friend I haven’t talked to since 2003. Although normally I’d be pleased to hear from an old friend, the fact that the message contained nothing but a link to a web site in the .ru TLD made me suspicious.
Out of curiosity, I grabbed a copy of the page using curl
, and then
examined it using a text editor. This is the safest way I know of to
investigate potentially-hostile web pages; even if the page exploits a
flaw in your browser, chances are it’s not designed to exploit a bug
in emacs
or vi
when it’s just being read locally. To no surprise at
all, the page was nothing but a bit of JavaScript. (Which is a good
reason to browse with something like NoScript
enabled.)
Since I’ve just recently started to play around with JS, I thought it would be interesting to take the program apart and see what it does. For safety reasons and because I don’t want to give the malware authors any additional traffic, I’m not going to link to the original Russian site or actually host their index page, but in the interest of science, I’ve put it up on Pastebin for anyone who wishes to poke at. Just be careful and don’t run the thing outside of a sandbox.
Pastebin link to the page’s raw HTML.
They’ve done some (fairly trivial) obfuscation to hide the actual code
by way of the two script elements on the page. The first <SCRIPT>
defines a Decode
function and includes the actual payload in a long
string; the second <SCRIPT>
calls the decoding function.
Their decoder:
function Decode()
{
var temp = "", i, c = 0, out = "";
var str = "60!33!68!79!67!84!89!...blahblahblah";
l = str.length;
while (c <= str.length - 1) {
while (str.charAt(c) != '!') {
temp = temp + str.charAt(c++);
}
c++;
out = out + String.fromCharCode(temp);
temp = "";
}
document.write(out);
}
Decode();
Obviously I’ve truncated the value of str
here for brevity; it’s
several thousand bytes long. What we’re looking for – the actual,
presumably-malicious code – is inside that string. There are a
number of ways we could get at the contents, but since the malware
authors have so helpfully supplied us with a decoder, why not use it?
Of course, we don’t want to run it from within a browser, or using any
of the online JS shells (which might – stupidly – run the code
that’s being obfuscated), but the js
CLI shell is a pretty
safe option.
If we weren’t absolutely sure what the code was going to do when we ran it, we might want to take additional precautions, like running it inside a walled-off VM, but in this case the code to be executed is trivial.
In order to make Decode()
run inside the js
CLI shell instead of
inside a browser’s JS environment, one small change is necessary:
where the code above has document.write(out)
, we need to change this
to a simple print(out)
. This writes the results to standard output
when we run the decoder via js -f badscript.js > badscript.out
or
something similar.
What we’re left with after running this is the page that the hapless victim actually arrives at, but which the malware author attempted to hide inside the script.
I haven’t had a chance to step through the resulting page completely yet, but it seems like a mess of advertisements combined with scripts designed to make it impossible to close the page. I assume there’s probably more nastiness buried in it besides the obvious, however: since the link was sent to me automatically, it’s a good bet it has a way of propagating itself.
This entry was converted from an older version of the site; if desired, it can be viewed in its original format.