漏洞概要 关注数(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标签: 无
漏洞详情
披露状态:
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{
.....
可以看到这里 load了一个 iconPath, 而iconPath来自于song.singerUrl
2. 我们来看看 song.singerUrl 来自哪里。
上图说明 song 来自 showIcon的参数,继续追 showIcon(
说明数据来自于SingleSongPanel类的 item 属性。 那么我们接着可以搜索 item =
这次我们来到了Panel类的create函数,继续定位 create(
可以看出,数据来自于MusicFlash类的setSwfSongList函数,看这函数名称,我们应该是快追溯到尽头了。
最后,setSwfSongList 给通过addCallback交给了JS。这样一来,我们在FLASH之中的探索之旅就告一段落咯
3. 那么在JS中,哪里调用了setSwfSongList呢?我们来搜索下资源。
如上图,我们定位到了http://ctc.qzs.qq.com/music/musicbox_v2_1/js/musicblog_player.js这个文件中的initSwfData()函数。从图中不难看出,setSwfSongList的参数数据来自于 g_songList 数组。
因此,我们找找g_songList的数据来自于哪里。
如上图所示,在不远处,我们找到了 initMusicData 这个函数中就有我们想要的东西。可以清楚的看出数据是以 songInfo --> songList --> g_songList 的方向流入的。并且在songInfo这个对象中,我们看到了 singerURL,这个不正是我们想要控制的数据么?那么它可不可以控制呢?
我们来重点关注这个 singerURL。
其中sT[j+4]这个部分是也许可以控制的,sT[j + 4] % 100 得到的是数字,无法控制。
代码上方不远处,可以看到sT来自于initMusicData的arguments(参数数组)
因而,我们需要继续追踪 哪里调用了initMusicData。搜索资源....
如上图:我们定位到了 http://ctc.qzs.qq.com/qzone/newblog/v5/script/common.js 中的QZBlog.Logic.initMusicPlayer 函数中,initMusicData的数据来自于musicParams,
向上不远可以看到 musicParams 的数据则来自于 ubb 这个属性。
因为之前我在乌云报过这里一处缺陷,所以对这段代码还是很熟悉的,如下图:
4. 这下我们就知道,我们的数据来自于 name="musicFlash**" 的标记的 ubb属性里了。
我们查看一下我们插入过音乐的日志中的HTML代码, 如下:
根据上面的代码分析,来自于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中,但是不幸的是,腾讯在初始化的函数中,加入了一段以下的代码。
这段代码的作用是, 当你直接打开 http://imgcache.qq.com/qzone/app/controls/attachBar/templatePanel/templatePanel_3.0.swf 的时候,由于pathname的结尾是swf,那么程序就不会继续往后执行了。
不得不说,这也确实是一段解决FLASH XSS的好代码啊!
8. 回到正题上来,由于我们这里是存储型的,那么拿上面这个鸡肋FLASH来使用,是一点问题都木有的~~,
因而我们可以构造好以下的利用代码:
发表日志,用其它号看测试号日志,可以看到代码被成功执行。
漏洞证明:
see details. It works in both IE and chrome.
修复方案:
sT[j + 4] 进入 singerURL前,先做个类型转换。
版权声明:转载请注明来源 gainover@乌云
漏洞回应
厂商回应:
危害等级:高
漏洞Rank:15
确认时间:2013-03-25 11:32
厂商回复:
非常感谢您的报告。这个问题我们已经确认,正在与业务部门进行沟通制定解决方案。如有任何新的进展我们将会及时同步。
最新状态:
暂无