• 1. Circles - Post
  • 2. Hollywood's_Bleeding - Post
  • 3. A_Thousand_Bad_Times - Post
  • 4. Allergic - Post
  • 5. Happier - Marshmello
  • 6. Here_With_Me - Marshmello

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

通过源码可以知道,需要让传入参数'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-------------------


    除非注明,ebounce文章均为原创,转载请以链接形式标明本文地址

    本文地址:http://www.ebounce.cn/web/20.html

    新评论

    captcha
    请输入验证码