打开页面,得到了一只滑稽。
这种情况下,一般就只有两种方法:
- 打开F12看源码
- 抓包
打开F12得到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\" />";
}
?>
又是代码审计orz....
那么简单审计一下,这里采用了白名单的形式,而且又是一道文件包含题目(我为什么要说又呢)
根据白名单,先打开hint.php试试,得到了一个hint:
flag not here, and flag in ffffllllaaaagggg
得到了flag在ffffllllaaaagggg
下
很明显,我们需要越权访问。
这里有几个关键点:
- 变量
$whitelist
也就是白名单里规定了只能通过source.php
和hint.php
- 在
checkFile(&page)
函数里会检查$page
$page
为空或者不是字符串会返回false$page
在白名单里会直接返回true
- 在
$_page
里又对$page
进行处理,检查的是$page
?前的东西并取出。
mb_substr()返回字符串的一部分, eg: echo mb_substr("kodosan",0,4); // 输出 : kodo mb_strpos()返回查找的字符在其字符串首次出现的位置 eg : echo mb_strpos("kodosan",'o'); // 输出 : 1
也就是说,$_page
取出的是$page
从0到?前的所有字符
- 然后再对
$_page
进行urldecode处理 - 进行上面相同的操作
- 对
$_page
进行白名单校验,如果在白名单中返回ture。否则返回"you can't see it"
然后最为关键的来了
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
在if里对file进行检查,file需要满足三个条件
$_REQUEST['file']
不为空$_REQUEST['file']
是字符串$_REQUEST['file']
需要通过emm类的checkFile()检查
才能包含成功。
分析完成,下面来进行payload的分析
首先,我们要让file通过白名单的检查,就要先构造source.php?
让我们通过白名单。然后根据hint,flag在ffffllllaaaagggg下,很容易考虑到要用../来表示上一级目录的文件或文件夹,所以payload应该为:
source.php?file=source.php?../../../../../ffffllllaaaagggg
经过测试,至少需要五个../才能读到flag。
根据上述函数以及服务的编码问题,我们要讲?进行两次url编码。
我们不妨逆向思维一下,当传入%253f,也就是?两次编码后的值,服务器会先进行解码,变为%3f,经过urldecode就会变为?
所以如下payload也是可以的:
source.php?file=source.php%253f../../../../../ffffllllaaaagggg
Comments | NOTHING