phpMyAdmin 是一个以PHP为基础,以Web-Base方式架构在网站主机上的MySQL的数据库管理工具,让管理者可用Web接口管理MySQL数据库。借由此Web接口可以成为一个简易方式输入繁杂SQL语法的较佳途径,尤其要处理大量资料的汇入及汇出更为方便。其中一个更大的优势在于由于phpMyAdmin跟其他PHP程式一样在网页服务器上执行,但是您可以在任何地方使用这些程式产生的HTML页面,也就是于远端管理MySQL数据库,方便的建立、修改、删除数据库及资料表。也可借由phpMyAdmin建立常用的php语法,方便编写网页时所需要的sql语法正确性。

0x0 漏洞背景

在前天,也就是6月21号,ChaMd5安全团队 披露了他们发现的一个phpMyAdmin文件包含漏洞,并且演示了如何将本地文件包含升级至远程命令执行,目前在网络上有两种方法可以使LFI -> RCE。在这里用两种利用方法跟一下。

0x1 漏洞分析

漏洞成因不难分析。

如下图,可以看到蓝框内代码,如果没有进行过滤的话,就会存在文件包含隐患。

进入该流程需要满足

! empty($_REQUEST['target'])
    && is_string($_REQUEST['target'])
    && ! preg_match('/^index/', $_REQUEST['target'])
    && ! in_array($_REQUEST['target'], $target_blacklist)
    && Core::checkPageValidity($_REQUEST['target']

这几个条件,跟进checkPageValidity看一下

只要想办法让此函数返回true就可以利用了。

这个地方应该就是漏洞的成因所在了。它在这里分别进行了两次判断,第二次判断前,将$page变量进行了二次URL解码。也就给了我们可逞之机。

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

利用二次解码我们可以利用../进行目录穿越

? ==> %253f

构造payload,只需要满足$_page在白名单中就行了

而白名单定义如下

只需要从中抽选一个出来就行了。

最终payload:

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

 

0x2 漏洞利用

而这个洞最巧妙的点就在于它如何将文件包含升级为远程命令执行的手段了,除了老生常谈的包含日志,又引出了两个比较新颖的姿势。

0x21 利用mysql的data文件

The mysqlfrm utility is designed as a recovery tool that reads .frm files and produces equivalent CREATE statements from the table definition data found in the file

这个姿势是由ChaMd5提供 传送门

修改或者新建字段名

首先将字段名修改成恶意代码

然后获取datadir

datadir变量,一般为默认不会变

进入mysql 容器内查看该目录下test表的frm文件,发现我们的恶意代码已经写入。

反序列化数据

payload:

/index?target=db_datadict.php%253f/../../../../../var/lib/mysql/test/test.frm

但是在复现的时候,并没有利用成功。

万里江山一片红

根据debug,本人认为应该有两种解释:

  1. 站库分离,我本地就是以docker起来的环境,所以PHP无法include Mysql容器内的文件
  2. Web容器(apache,nginx)权限低
文件权限为root

上述也是这个姿势的缺陷,思路很骚,实在可惜。

那,有没有别的姿势可以弥补这两点呢?

0x22 利用PHP session序列化数据

这个姿势是由Phithon师傅在知识星球:【代码审计】中提供的,后 vulnspy 团队提供了在线靶场复现环境。

PHP会序列化参数传递的值,并且保存在本地的session文件中。

先获取我们的session

然后读取session文件的内容。

Macos的session保存目录为/var/tmp/

Linux的session保存目录为/var/lib/php/sessions/

 

可以看到我标记的地方,分别是我查询的sql语句,以及新建表的字段命名。都被记录进入session文件了。所以我们只需要包含这个session文件,即可执行命令。

Payload: index?target=db_datadict.php%253f/../../../../../var/tmp/sess_et3on4l18cib0fee6rv8722sic

0x3 补丁状态

该漏洞已经被修复,漏洞存在于版本号小于4.8.2的所有历史版本中,通过git changelog查看官方如何修复漏洞的:Merge branch ‘QA_4_8’

修复手法简单粗暴,直接在checkPageValidity中多加了一个参数$include

$include=true时,仅执行第一次判断$page的合法性,我们的payload也就没有办法进入到urldecode的步骤了。

 

0x4 Ref

推荐在线复线环境(由于权限问题,只能使用第二张方法):

http://www.vulnspy.com/phpmyadmin-4.8.1/phpmyadmin_4.8.1_lfi_to_rce_vulnerability/

 

 





本文链接地址: 【CVE-2018-12613】phpMyAdmin 4.8.1 LFI to RCE

原创文章,转载请注明: 转载自Lz1y's Blog

2 thoughts on “【CVE-2018-12613】phpMyAdmin 4.8.1 LFI to RCE

    1. 换手机了,没有及时下载知识星球…错过了这么骚的思路唉…推特上都说是他们那个团队给的方法…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.