BUU_warm_up
考察点:远程文件包含利用漏洞
打开题目网址,提示代码审计,直接审查源码:
访问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\" />";
}
?>
审查源码发现一个 hint.php ,尝试访问获得一个关于flag的提示:
查阅大佬们的 wp, 才明白这题是关于 php文件包含漏洞;
代码段分析:
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\" />";
}
这里先分析最后一个if , 需要满足三个条件,才对文件进行文件包含:
- !empty() ,传入字符不能为空;
- is_string() ,传入的字符为字符;
- 满足 checkFile() ,即 checkFile() 返回 TURE;
前两个条件满足很简单,最关键的是 checkFile() 这个函数的满足,分析checkFile() 函数:
- 第一个if,$page为非空字符串即可绕过;
- 第二个if,判断 $page 是否在 whitelist 这个数组里面;这个if主要用于题目给出源码以及flag位置提示的需要;
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
这段代码,首先 使用 mb_strpos() 函数,给 $page 拼接 ? ,然后返回到 ? 的位置;再用 mb_substr() 函数,截取从 $page 开头到 ?前一个字符的子串,将截取的子串赋给 $_page;
- 第三个if,将 $_page 使用 in_array() 函数检测是否存在于数组 whitelist 中,如果存在,返回 TRUE;
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
urldecode() ,将$_page进行一次 url 解码,然后是给 $_page 拼接 ? ,然后在截取到 ? 的子串再赋给 $_page;
- 第四个if,仍然是判断 $_page 是否在 数组中,成立返回TRUE;
至此整个代码分析过程结束;
接下来,构造 payload,两种方法利用远程文件包含漏洞,进行目录穿越:
- 第一种方法:绕过第一个if,满足第三个if
payload: ?file=hint.php?/../../../../ffffllllaaaagggg
分析:此时,$page=hint.php?/…/…/…/…/ffffllllaaaagggg, 被送入mb_substr() 和 mb_strpos() 做处理后,使 $_page = hint.php , $_page再被送入第三个 if 做判断,显然 hint.php 在whitelist 数组中 ,checkFile() 函数返回 TRUE;
- 第二种方法:绕过第一个if,满足第四个if
?file=hint.php%253f/../../../../ffffllllaaaagggg
分析:此时,$page=hint.php%253f/…/…/…/…/ffffllllaaaagggg,url首先对传参进行一次解码,使得 $page=hint.php%3f/…/…/…/…/ffffllllaaaagggg;因为 ? 进行了二次url编码,所以第三个if不成立, $page 被送入urldecode(),再次被解码,使得 $page=hint.php?/…/…/…/…/ffffllllaaaagggg,最后 $_page=hint.php ,在 数组 whitelist 中,checkFile() 返回TRUE;
关于文件包含漏洞以及目录穿越请参阅:
推荐阅读