复现环境
https://buuoj.cn/challenges#[HCTF%202018]WarmUp
考察知识点
- 代码审计
- phpmyadmin4.8.1远程文件包含漏洞 CVE-2018-12613
- 文件包含+目录绕过
解题分析
访问题目是一个表情的图片,查看源码发现!--source.php-->
,直接访问这个文件,可以看到题目源码。
分两部分来看,首先是checkFile函数
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //设置白名单
if (! isset($page) || !is_string($page)) { //$page值不为空且是字符串
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) { //判断$page是否在白名单里面
return true;
}
$_page = mb_substr( // 用?来分割$page值
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page); //URL编码$page
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
我们来分析一下都有哪些检查:
- 判断传入的参数不为空且为字符串
- 判断是否在白名单里
mb_strpos — 查找字符串在另一个字符串中首次出现的位置
mb_substr — 获取部分字符串
- 以问号分割再次判断引号前的部分是否在白名单
urldecode — 解码已编码的 URL 字符串
- URL解码后再次判断引号前的部分是否在白名单
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\" />";
}
?>
接收file参数,传入checkfile进行过滤,如果通过过滤的话,就会通过文件包含显示文件内容。
接下来访问一下hint.php,看到提示flag not here, and flag in ffffllllaaaagggg
这时候基本可以确定要文件包含的是ffffllllaaaagggg,直接访问文件为404,说明flag文件不在同目录。
构造:
?file=source.php?/../ffffllllaaaagggg
绕过白名单检测可以到达第三个判断条件
page);此处是一个url解码,所以需要构造一个url编码的字符
?file=source.php%253f../ffffllllaaaagggg
此时就可以通过第四个判断条件
但还需要找到ffffllllaaaagggg文件的位置,通过../../../递归找到文件位置
?file=source.php%253f../../../../../ffffllllaaaagggg
至此成功获取到flag。
后来在网上发现不编码也可以解出来....应该是直接试出来的吧。
payload:
file=hint.php?../../../../../ffffllllaaaagggg
或者 file=source.php?../../../../../ffffllllaaaagggg
网友评论