点开即是->
通过查看源码,发现了/source.php,于是对他进行打开。
打开后发现是php代码,便对他进行审计。
首先看主函数
if (! empty($_REQUEST['file']) //首先判断file不能为空
&& is_string($_REQUEST['file']) // file必须为字符串
&& emmm::checkFile($_REQUEST['file']) //最后在在上方的函数进行检查
)
{
include $_REQUEST['file']; // 文件包含
exit;
}
else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
} //否则打印滑稽笑脸
在看checkfile函数
class emmm //定义类
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) // 需要定义page这个变量并且必须为字符串
{
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) //page需要在whitelist里
{
return true;
}
$_page = mb_substr
(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) _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;
}
}
1.第一个
if
语句对变量进行检验,要求
$page
为字符串,否则返回false
2.第二个
if
语句判断
$page
是否存在于
$whitelist
数组中,存在则返回true
3.第三个
if
语句判断截取后的
$page
是否存在于
$whitelist
数组中,截取
$page
中
'?'
前部分,存在则返回true
4.第四个
if
语句判断url解码并截取后的
$page
是否存在于
$whitelist
中,存在则返回true
若以上四个
if
语句均未返回值,则返回false
有三个
if
语句可以返回true,第二个语句直接判断
$page
,不可用
第三个语句截取
'?'
前部分,由于?被后部分被解析为get方式提交的参数,也不可利用
第四个
if
语句中,先进行url解码再截取,因此我们可以将?经过两次url编码,在服务器端提取参数时解码一次,checkFile函数中解码一次,仍会解码为
'?'
,仍可通过第四个
if
语句校验。
于是便尝试构造payload /source.php?file=source.php%253f../ffffllllaaaagggg
经过测试发现无返回值,这可能是因为我们不知道ffffllllaaaagggg文件存放的具体位置所以依次增加../最终成功拿到flag
也许可以根据ffffllllaaaagggg尝试加4次../ 这只是本人的猜想,在找到flag后才发现的