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

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

缺陷编号:wooyun-2013-020565

漏洞标题:QQ空间某功能缺陷导致日志存储型XSS - 8

相关厂商:腾讯

漏洞作者: gainover

提交时间:2013-03-24 09:25

修复时间:2013-05-08 09:26

公开时间:2013-05-08 09:26

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

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

接着上一个漏洞,不知道QQ空间的所有文件都是一个团队在写的,俺抱着“来自同一个团队的东西可能会有类似问题”的思想,不知廉耻的又去下载了另外一个文件,于是。。。

详细说明:

1. 我们下载这个音乐播放器的FLASH。http://ctc.qzs.qq.com/music/musicbox_v2_1/img/MusicFlash.swf
然后反编译出来。和上一篇一样,我们继续关注的是 Loader ,因此我们搜索 .load(
搜索到以下内容:
public class IconBox extends MovieClip {
.....
public function showIcon(_arg1:Object):void{
.....

1.jpg


可以看到这里 load了一个 iconPath, 而iconPath来自于song.singerUrl
2. 我们来看看 song.singerUrl 来自哪里。

2.jpg


上图说明 song 来自 showIcon的参数,继续追 showIcon(

3.jpg


说明数据来自于SingleSongPanel类的 item 属性。 那么我们接着可以搜索 item =

4.jpg


这次我们来到了Panel类的create函数,继续定位 create(

5.jpg


可以看出,数据来自于MusicFlash类的setSwfSongList函数,看这函数名称,我们应该是快追溯到尽头了。

6.jpg


最后,setSwfSongList 给通过addCallback交给了JS。这样一来,我们在FLASH之中的探索之旅就告一段落咯
3. 那么在JS中,哪里调用了setSwfSongList呢?我们来搜索下资源。

7.jpg


如上图,我们定位到了http://ctc.qzs.qq.com/music/musicbox_v2_1/js/musicblog_player.js这个文件中的initSwfData()函数。从图中不难看出,setSwfSongList的参数数据来自于 g_songList 数组。
因此,我们找找g_songList的数据来自于哪里。

8.jpg


如上图所示,在不远处,我们找到了 initMusicData 这个函数中就有我们想要的东西。可以清楚的看出数据是以 songInfo --> songList --> g_songList 的方向流入的。并且在songInfo这个对象中,我们看到了 singerURL,这个不正是我们想要控制的数据么?那么它可不可以控制呢?
我们来重点关注这个 singerURL。

singerUrl: "http://imgcache.qq.com/music/photo/singer/" + sT[j + 4] % 100 + "/singerpic_" + sT[j + 4] + "_0.jpg"


其中sT[j+4]这个部分是也许可以控制的,sT[j + 4] % 100 得到的是数字,无法控制。
代码上方不远处,可以看到sT来自于initMusicData的arguments(参数数组)

sT = arguments[i].replace(/\[music\]/g, "").replace(/\[\/music\]/g, "").split("|");


因而,我们需要继续追踪 哪里调用了initMusicData。搜索资源....

9.jpg


如上图:我们定位到了 http://ctc.qzs.qq.com/qzone/newblog/v5/script/common.js 中的QZBlog.Logic.initMusicPlayer 函数中,initMusicData的数据来自于musicParams,
向上不远可以看到 musicParams 的数据则来自于 ubb 这个属性。
因为之前我在乌云报过这里一处缺陷,所以对这段代码还是很熟悉的,如下图:

10.jpg


4. 这下我们就知道,我们的数据来自于 name="musicFlash**" 的标记的 ubb属性里了。
我们查看一下我们插入过音乐的日志中的HTML代码, 如下:

11.jpg


根据上面的代码分析,来自于UBB的数据,被以 "|" 分割后,得到sT数组,我们需要控制的是sT[j+4],即 sT[4] (第一次循环中 j=0),在UBB中,第4个位置的内容是 "96"。
5. 接着我们就是要操控 "96"这部分内容。 这里我直接说我的操控方法。
我们将"96"修改为 "96/../../../../../1.swf?a=",这样一来,即:
sT[j+4]="96/../../../../../1.swf?a=", 所以:
singerUrl = "http://imgcache.qq.com/music/photo/singer/" + sT[j + 4] % 100 + "/singerpic_" + sT[j + 4] + "_0.jpg" = "http://imgcache.qq.com/music/photo/singer/NaN/singerpic_96/../../../../../1.swf&a=_0.jpg"
也就是说,最后这个 singerUrl的地址,由于 ../../的作用,实际上变成了 http://imgcache.qq.com/1.swf?a=_0.jpg
6. 有人会说,这又有什么用呢? 这样确实没什么用,但是如果我们能够在 imgcache.qq.com 域名下找到一个存在缺陷的FLASH,结果就大大不同了。你别说,还真能找到!原因是腾讯大部分公用的FLASH基本都放在了这个域名下,所以要寻找还是能找到的。
7. 比如说:我们找到了这个有点鸡肋的FLASH。
http://imgcache.qq.com/qzone/app/controls/attachBar/templatePanel/templatePanel_3.0.swf
在这个FLASH中,有一个参数facadeId是没过滤的,并且进入了ExternalInterface.call中,但是不幸的是,腾讯在初始化的函数中,加入了一段以下的代码。

if (ExternalInterface.available){
pathname = ExternalInterface.call("eval", "window.location.pathname");
if (((pathname.match(/\.swf$/i)) || (!(pathname)))){
return;
};
};


这段代码的作用是, 当你直接打开 http://imgcache.qq.com/qzone/app/controls/attachBar/templatePanel/templatePanel_3.0.swf 的时候,由于pathname的结尾是swf,那么程序就不会继续往后执行了。
不得不说,这也确实是一段解决FLASH XSS的好代码啊!
8. 回到正题上来,由于我们这里是存储型的,那么拿上面这个鸡肋FLASH来使用,是一点问题都木有的~~,
因而我们可以构造好以下的利用代码:

<div><object codeBase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab#version=8,0,0,0" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="410" height="100" src="http://ctc.qzs.qq.com/music/musicbox_v2_1/img/MusicFlash.swf" bgcolor="#ffffff" menu="true" allowScriptAccess="always" name="musicFlash**" id="musicFlash0" ubb="1130617|3|http://stream6.qqmusic.qq.com/13130617.wma|雨人|96/../../../../../qzone/app/controls/attachBar/templatePanel/templatePanel_3.0.swf?facadeId=((function(){alert(1);return {onReady:function(){}}})())&a=|周华健|0" class="blog_music"><param name="movie" value="http://ctc.qzs.qq.com/music/musicbox_v2_1/img/MusicFlash.swf" /><param name="data" value="http://ctc.qzs.qq.com/music/musicbox_v2_1/img/MusicFlash.swf" /><param name="bgColor" value="#ffffff" /><param name="wmode" value="transparent" /><param name="menu" value="true" /><param name="allowScriptAccess" value="always" /></object> </div>


发表日志,用其它号看测试号日志,可以看到代码被成功执行。

12.jpg

漏洞证明:

see details. It works in both IE and chrome.

修复方案:

sT[j + 4] 进入 singerURL前,先做个类型转换。

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2013-03-25 11:32

厂商回复:

非常感谢您的报告。这个问题我们已经确认,正在与业务部门进行沟通制定解决方案。如有任何新的进展我们将会及时同步。

最新状态:

暂无