预备知识:
文件包含相关知识:include 'xxx', 所包含的xxx文件会当作PHP代码执行。
include 'xxx/../123.php'# PHP中默认和 include './xxx/../123.php' 等效
首先这是一个相对路径,相对于当前目录而言
在解析这段路径的时候,首先先检查每一个目录名是否正确,此外,由于 / 的存在,会将xxx当作一个目录,即使这个目录并不存在,而../表示返回上一层目录,所以就是,进入当前目录下的xxx目录再返回上一个目录,结果依然在当前目录,最后在当前目录下寻找123.php。
# 寻找123.php..这个目录下的123.php# 在win下这样写直接报错,因为123.php..会被win10系统强制改为123.php# 那么php在找123.php..这个目录的时候,就找不到了include '123.php../123.php'# 寻找上一层目录下的123.php# 这行代码不会报错,即使123.php..这个目录不存在。include '123.php../../../123.php' 相当于 include './132.php../../../123.php'# 123.php..当作一个目录存在# 两个../向上返回两层目录,对于当前目录而言,相当于返回上一层目录,最后寻找123.php,
PHP函数说明:
- in_array ():in_array() 函数搜索数组中是否存在指定的值。
<?php $people = array("Bill", "Steve", "Mark", "David");if (in_array("Mark", $people)) { echo "匹配已找到"; }else { echo "匹配未找到"; }?>
2.mb_substr() : 用于截取字符串的长度。
<?php echo mb_substr("喵喵视角", 0, 2); // 输出:视角//0代表从第零个位置开始,2代表截取的长度为2?>
- mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置。
<?php $str = 'miaomiaoshijiao';echo mb_strpos($str,'shi');//返回值为8?>
好啦,准备工作欧克了,开始看题目吧:
打开F12 ,查看一下元素:
访问一下source.php:
public static function checkFile(&$page) { $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; if (! isset($page) || !is_string($page)) { echo "you can't see it"; return false; } if (in_array($page, $whitelist)) { return true; } $_page = mb_substr( //该代码表示截取$page中'?'前部分,若无则截取整个$page $page, 0, mb_strpos($page . '?', '?') ); if (in_array($_page, $whitelist)) { //若$page变量存在于$whitelist数组中 ,返回true return true; } $_page = urldecode($page); $_page = mb_substr( $_page, 0, mb_strpos($_page . '?', '?') ); if (in_array($_page, $whitelist)) { return true; } echo "you can't see it"; return false; }
我们主要看checkFile里的代码:可以看到,定义了白名单,我们访问白名单,发现了flag存在的文件。
然后这个就没用了。
- 第一个if语句对变量进行检验,要求$page为字符串,否则返回false
- 第二个if语句判断$page是否存在于$whitelist数组中,存在则返回true
- 第三个if语句判断截取后的$page是否存在于$whitelist数组中,截取$page中'?'前部分,存在则返回true
- 第四个if语句判断url解码并截取后的$page是否存在于$whitelist中,存在则返回true
若以上四个if语句均未返回值,则返回false
$page = hint.php?../../ffffllllaaaagggg
mb_substr()将截取 $page, 截取内容为 hint.php
$_page = hint.php ,$_page 出现在 whitelist 中, 然后 return true; 执行 include $_REQUEST['file'] 也就是 include 'hint.php?../../ffffllllaaaagggg'
构造:?file=hint.php?../../.../ffffllllaaaagggg (逐次往上一级目录跳转)//需要对?进行二次编码处理。
总结:
- cd dasdas/../ 还是在当前目录
- windows下,由于目录不能出现特殊符号,所以对于本题的第三个if ,无法使用, 但是在Linux下,我们可以使用 file=hint.php?/../../../../etc/passwd
菜鸡上路,多多关照,如有错误,欢迎指出。