很久以前写过这道题,当时绕不过去看着wp写出来,最后也没有完全搞明白,今天又遇到,结果还是没想到QAQ,果然写题目的意义还是知识点www
[HCTF 2018]WarmUp题解
首先f12查看源码,发现一个hint:
于是访问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\" />";
}
?>
又发现了一个hint.php文件,访问后的确有一个hint,提示我们flag在ffffllllaaaagggg文件中:
回过头继续看代码,其中有几个函数:
mb_strpos($string, $a):查找字符串a在字符串string中首次出现的位置,起始位置以0开始;
mb_substr($string, $start, $end):在字符串string中截取以start开始,以end结尾的子串;
通读代码后我们发现,如果想要得到ffffllllaaaagggg文件的内容,需要让**$_REQUEST[‘file’]**是ffffllllaaaagggg,并且checkFile(ffffllllaaaagggg)返回true;
可以让checkFile返回true的出口一共有三个,总结起来就是:
- 访问的文件是source.php或者hint.php(也就是白名单里的本来就让你访问到的;
- 截取文件名的第一个 ?之前的内容,该内容必须是source.php或者hint.php
- 经过url解码后截取文件名的第一个 ?之前的内容,该内容必须是source.php或者hint.php
这里就用到了PHPMyadmin4.81的漏洞了,详细的说明看这里:https://blog.csdn.net/Mikasa_/article/details/88594749
这个漏洞利用了一个性值:如果将 ?双重编码,经过包含时会把你包含的文件当作一个目录,也就是说,如果你写入:
hint.php%25%3F(%25%3F是?的二次编码)
那么解析时会把hint.php当作一个目录来看。
于是该题的payload可以是:
?file=hint.php%253F/…/…/…/…/ffffllllaaaagggg
至于要向上回退多少个目录再访问ffffllllaaaagggg我还不知道为什么……(求大佬解答)只是一直尝试,回退4个以上即可成功。