考点: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
以上分析了一通 其实我还是有点懵。。。