开局一个表情,源代码发现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\" />";
}
?>
知识点
1.函数
empty:检查变量是否为空,存在值返回true,反之false
isset:检查变量是否设置,且不为空,存在值返回true,反之false
is_string:检查一个变量是否是字符串。如果是字符串,则返回 true;否则返回 false。
in_array:检查一个值是否存在于数组中。如果值存在于数组中,则返回 true;否则返回 false
mb_strpos:在字符串中查找另一个字符串的首次出现位置
mb_substr:返回字符串截取的一部分
$subStr = mb_substr($str, 0, 3, 'UTF-8'); // 从索引 0 开始,截取长度为 3 的子串
分析源码
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要满足三个条件,三个都返回True,才能进行文件包含include,第一个和第二个容易满足;第三个分析chekFile方法。
代码1.
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
创建$whitelist列表,给source和hint分别赋值给source.php和hint.php,满足变量$page既不能为空,又必须是字符串
代码2.
if (in_array($page, $whitelist)) {
return true;
}
判断变量$page的值是否在$whitelist列表中,如果在则返回true,反之false。
代码3.
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
这段代码表示:在$page中,从最开始的位置去匹配?
,然后返回?
前的所有字符串(不包括?
)
代码4.
$_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;
}
将$page进行url解码,然后进行?
截取,判断是否在列表中
payload
通过上面的代码分析,payload中必须有hint.php或source.php,(参考上面的代码1和代码2)和?
,因为有?,才能进行if判断。
它还要进行url解码,但是传进的值,经过url解码后,还是它本身。
?file=hint.php?../../../../../../../../ffffllllaaaagggg