source.php分析
<?php
highlight_file(__FILE__);
//display the source code of the file.
class emmm
{
public static function checkFile(&$page)
//传入了变量page,也就是我们刚刚传进来的file
{
// 这里定义了白名单,包括source.php和hint.php
$whitelist = ["source" => "source.php", "hint" => "hint.php"];
if (!isset($page) || !is_string($page)) {
// $page != null and $page is a string
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
// $page is in the whitelist (source.php or hint.php) 不包含key
return true;
}
// 从page中截取出?前面的字符串
// 例如page=source.php?file=hint.php 截取出source.php
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
// The dot (.) is used to concatenate the two strings
// mb_strpos() returns the position of the first occurrence of ?
);
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;
}
}
// The $_REQUEST variable is used to collect data after submitting an HTML form.
if (
!empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
//执行file中的代码
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
任务分析:
绕过过滤:file=source.php?和file=hint.php?都可以绕过过滤
利用include函数的漏洞,include xxx.php 会执行xxx.php的代码,include xxx.php/ 此时xxxx.php是目录名include如果找不到目录会跳过/前的内容,继续向/后执行。
/…/…/…/…/…/…/flag.php 查找
小疑问:
为什么执行source.php 然后 include source.php 不会一直自己调用自己无限循环,file=source.php 只出现了一次源代码。