[HCTF 2018]WarmUp
0x00
打开网页看到如下,并没有任何信息,那就让我去找一些信息。
在控制台看到了如下信息
可以知道存在source.php文件,打开如下
其中代码如下,进行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\" />";
}
?>
看到如下这处,发现由于未对传入参数过滤,导致了文件包含漏洞
根据代码我们可以知道,如何想要触发文件包含,需要满足如下三个条件:
##只有三个条件全部为true时才可触发
1. ! empty($_REQUEST['file'])
##条件1表示参数不为空时返回true
2. is_string($_REQUEST['file'])
##条件2表示参数为字符串时返回true
3. emmm::checkFile($_REQUEST['file'])
##条件3表示参数满足checkFile函数时返回true
由上我们可以知道条件1和条件2很好满足,我们只需要在满足条件三即可,然后我们来的分析checkFile函数
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
## 0
if (! isset($page) || !is_string($page)) { ##满足page变量不存在或page变量不是字符串时返回false
echo "you can't see it";
return false;
}
## 1
if (in_array($page, $whitelist)) { ##满足page变量在whitelist数组内返回true
return true;
}
## 2
$_page = mb_substr( ##截取page变量第一个?前的字符串
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
## 3
$_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;
}
由以上代码我们可以知道:
0:
我们可以先不用考虑,只要满足那两个条件让他不返回false即可
1:
我们只要保证传入的参数("file="后面的为参数),在whitelist里面即可,checkFile函数返回的就是true,就可以触发文件包含
2:
我们只要保证传入的参数在被截取后得到的变量,在whitelist里面即可
3:
我们要保证被url解码后在进行截取后得到的变量,在whitelist里面即可
现在我们已经知道了如何可以触发文件包含漏洞,接下来我们寻找Flag
在代码审计过程中我们看到数组中还有一个hint.php文件,我们去打开得到如下
我们可以知道flag在上图的那个文件里面,接下来我们尝试将那个文件包含进来
首先我们要满足可以触发文件包含,payload如下
/source.php?file=hint.php
我们可以看到已经包含进来了
然后我们要满足将 ffffllllaaaagggg 包含进来,可以构造如下payload:
/source.php?file=hint.php%253f/../../../../ffffllllaaaagggg
或
/source.php?file=hint.php?/../../../../ffffllllaaaagggg
如上payload,带入到代码里面为
include "hint.php%23/../xss.txt";
0x01
如果你对payload
/source.php?file=hint.php%253f/../../../../ffffllllaaaagggg
或
/source.php?file=hint.php?/../../../../ffffllllaaaagggg
有疑问,那需要知道如下知识点
-
- 在php中当前目录可以表示成
a%/..
## a可以为任意字母
-
- 在操作系统中
. 表示当前目录
.. 表示上一级目录
-
- ?的双重url编码为 %253f
-
- 后端获取前端传入参数时默认进行一次解url编码
-
- 后端获取到的参数变量为 "?file=" 后的字符串
接下来我们进行一步步分析:
- 后端获取到的参数变量为 "?file=" 后的字符串
1:
后端获取到的参数为
hint.php%3f/../../../../ffffllllaaaagggg
##已经进行了一次url解码
可以满足触发文件包含的前两条件,在分析是否满足checkFile返回true
2:
checkFile里面的四个条件,
可以保证让0条件不反回false,继续执行
不能保证让条件1返回true,继续执行
不能保证让条件2返回true,继续执行
条件3还需要在进行一次解码得到如下
hint.php?/../../../../ffffllllaaaagggg
然后在进行截取得到如下
hint.php
可以知道hint.php在whitelist里面,所以checkFile返回true,可以触发文件包含,接下来我们去分析文件包含部分
3:
代码如下:
include $_REQUEST['file'];
##$_REQUEST['file']即为我们在前端获得的参数,为 hint.php%3f/../../../../ffffllllaaaagggg
根据如上知识点我们可以知道 hint.php%3f/.. 表示当前脚本目录,所以这里代码可以替换为
include "../../../ffffllllaaaagggg";