考点:PHP代码审计
抓包发现source.php,访问下,出现了php代码
代码主体在这部分,满足三个条件:file不为空&file是字符串&checkFile通过
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\" />";
}
然后就要读懂这个checkfile()的代码逻辑 ,然后进行绕过:
1、in_array(value,array,type):检查数组中是否存在某个值
value 必需。规定要在数组搜索的值。
array 必需。规定要搜索的数组。
搜索page中是否在whitelist,存在返回true,但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;
}
whitelist 表示白名单包含source.php和hint.php,再访问hint.php看看,说flag在ffffllllaaaagggg里面
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
2、搜索_page中是否在whitelist,存在返回true
_page截取的是page从第0位到?出现的位置
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
mb_substr( $str, $start, $length, $encoding ) 截断函数
$str,需要截断的字符串
$start,截断开始处
$length,长度(1就代表一个中文字符)
$encoding,编码,我设为 utf-8
mb_strpos (haystack ,needle )查找字符串needle在字符串haystack中首次出现的位置
3、_page为urldecode后的page,然后截取_page在?前的字符串赋值给_page,最后判断_page是否在whitelist中,是就返回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;
最后构造的payload是/?file=source.php?../../../../../ffffllllaaaagggg,或者source换成hint
以上分析了一通 其实我还是有点懵。。。