PHP 编程 ·

「安全笔记」CVE-2018-12613复现

CVE-2018-12613 phpMyAdmin后台文件包含溯源


flask项目差不多告一段落了,最近做ctf意识到代码审计的问题,对于源码阅读还是很差,打算省赛结束开始php学习,提高代码审计能力,先从一些简单的cve开始,学细一些思路。

漏洞影响

该漏洞影响phpMyAdmin 4.8.0-4.8.1版本,本次使用4.8.1版本,复现环境Ubuntu16.04

漏洞分析

漏洞入口 index.php54-63行,看到最后的include,只要绕过前面五判断即可达到任意文件包含。

$target_blacklist = array (
    'import.php', 'export.php'
);

// If we have a valid target, let's load that script instead
if (! empty($_REQUEST['target'])
    && is_string($_REQUEST['target'])
    && ! preg_match('/^index/', $_REQUEST['target'])
    && ! in_array($_REQUEST['target'], $target_blacklist)
    && Core::checkPageValidity($_REQUEST['target'])
) {
    include $_REQUEST['target'];
    exit;
}


1. target非空
2. target必须是字符串
3. target不能以index开头
4. 不能再黑名单中(import.php、export.php)
5. Core类的checkPageValidity方法返回True
前四个很好绕过,重点放在第五个条件,跳转到libraries/classes/Core.php里的checkPageValidity方法

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 . '?', '?')
    );
    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;
    }

    return false;
}
  1. 因为我们没有传入$whitelist,所以现在的白名单使用定义的白名单。(太长了就不贴出来了)
  2. 传入的参数未被定义或者不是字符串,就返回False
  3. 参数在$whitelist里直接返回true,但是就不能包含了
  4. 第四步首先经过一次urldecode,这里容易想到二次url编码,然后取第一个?号前的字符串,这一步的意思是,如果target包含的文件带参数同样可以成功包含。
  5. 判断截取的被4截取过的字符串再放到白名单中判断。
    分析完了就很好利用了,只需要用一个存在白名单的文件然后就可以包含一个需要的文件了
    这里可以利用ph师傅的方法,在phpmyadmin中执行一次sql查询例如,select,然后包含session文件,一般的保存在tmp/sess_你的sessionid中,sessionid可以在cookies里的phpmyadmin里找到,但是我碰到了不再tmp下的情况,可以去phpinfo中找到session.save_path找到保存路径包含即可,可以利用目录穿越去找到想包含的文件
    payload: http://localhost/phpmyadmin-4.8.1/index.php?target=db_sql.php?/../../../../../../../var/lib/php/sessions/sess_n286l45an4ugi5akup174176pn
    这里注意,大多数payload给出的都是二次url编码后的?号,这里原因还不是很明确=,请知道的师傅务必联系我!!

总结,从小的点出发,开始深挖,比如从一个include开始,尝试绕过判断包含任意文件。利用一些函数来突破限制如urldecode。从目标出发,只要可以绕过判断就好。

参与评论