漏洞概要 关注数(24) 关注此漏洞
缺陷编号:wooyun-2012-016532
漏洞标题:[腾讯实例教程] 那些年我们一起学XSS - 15. Flash Xss进阶 [ExternalInterface.call第一个参数]
相关厂商:腾讯
漏洞作者: 心伤的瘦子
提交时间:2012-12-26 14:55
修复时间:2013-02-09 14:55
公开时间:2013-02-09 14:55
漏洞类型:xss跨站脚本攻击
危害等级:低
自评Rank:2
漏洞状态:厂商已经确认
漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]
Tags标签: 无
漏洞详情
披露状态:
2012-12-26: 细节已通知厂商并且等待厂商处理中
2012-12-26: 厂商已经确认,细节仅向厂商公开
2013-01-05: 细节向核心白帽子及相关领域专家公开
2013-01-15: 细节向普通白帽子公开
2013-01-25: 细节向实习白帽子公开
2013-02-09: 细节向公众公开
简要描述:
除了上一节讲到的navigateToURL/getURL之外呢,另一个经常存在XSS缺陷的as函数就是ExternalInterface.call,此函数作为FLASH与宿主页面javascript通信的接口,一般来说,有“2”个参数,第一个参数为所调用js函数名,后续的其他参数则为所调用的js函数的参数。那么在参数可控的情况下,不论是第一个参数或是后续参数可控,我们均能加以利用实现XSS。本节先说一说第一个参数可控的情况。
详细说明:
1. 先从程序员的角度说下基础知识,有时候,我们需要在FLASH里调用当前页面中的javascript函数,例如:一个简单的需求,我们要在游戏加载完成后,执行弹出1的操作。
javascript代码:
as代码
2. 有的程序员就会觉得,直接弹出1太丑了吧。于是他自己写个js的函数
然后在as里
3. 又有一天,另外一个程序员觉得上面那个程序员写的东西不错,但是他的JS函数名不叫myalert,于是喊那个程序员改下as代码。于是那个程序员觉得,免得以后老是有人喊我改代码,他就将代码写成了下面这个样子。
这样一来,其他想用这个FLASH的人,不需要修改FLASH,只需要调用FLASH的时候带上参数即可。
比如我的JS函数是newalert, 我只需要按照下面这么调用:
4. 上述过程提高了程序的可重用性,为开发人员带来了极大的便利,但是却是缺乏安全考虑的。
攻击者可以采用以下的方式来执行自己的代码
http://some.com/xxx.swf?func=(function(){alert("hi jack")})
5. 为了方便理解,我们可以将
看成JS里的
而FLASH里实际最后执行的JS代码,形式如下(至于下面这句哪里来的,暂时不表):
因而 函数名 部分也可以写为 (function(){alert("hi jack")}) 的形式。
6. 上面说的是理论基础,有了这个基础,我们来看实例,就比较简单了。
http://quan.qq.com/swf/swfupload.swf
7. 怎么反编译,见上一篇。我们来看怎么查找缺陷。
8. 因为这是一个AS3.0的FLASH文件,我们首先确定FLASH是否有接受参数。
as3.0 接受参数的方法,所有参数存放在 root.loaderInfo.parameters 对象里。
例如 aaa.swf?a=1&b=2&c=3,
那么 root.loaderInfo.parameters 则等于
{
"a":1,
"b":2,
"c":3
}
9. 我们可以定位到 movieName变量
可以看出,FLASH的movieName参数,存放到了this.movieName中。
10.进一步, this.movieName被带入了到了this.flashReady_Callback及其它变量。
11. 我们再进一步看看,this.flashReady_Callback 被用到了哪里。
12. 再接着看看调用 this.flashReady_Callback 的Simple函数是啥样子的。
可以看到,最终这个参数被放到 ExternalInterface.call 的第一个参数中执行了。
13. 是不是很激动。我们来假设一下,按下面调用FLASH
http://quan.qq.com/swf/swfupload.swf?movieName=aaaaaaaa
那么this.flashReady_Callback就等于以下内容。
SWFUpload.instances["aaaaaaaa"].flashReady
最终调用的是
ExternalInterface.call('SWFUpload.instances["aaaaaaaa"].flashReady');
14. 如果我们要调用自己的JS代码,就需要构造闭合,但是你会发现有一定问题。。
我们最多能够造成下面的模样。
但是这样是无法正确执行的,因为 SWFUpload.instances没有被定义,从而SWFUpload.instances["aaa"]会失败。
15. 怎么办呢?这里就要拿出我们第5步里的知识了。我们把“函数名”换成call的第一个参数内容。变成下面的形式。
我们再基于以上代码来构造,
图片解析:
上面一行不好看懂的话,写的好看点。
16. 最后,我们把构造的代码,放进FLASH的参数里
可以看到成功执行alert(1)
漏洞证明:
见详细说明。
修复方案:
对传入call的字符串进行判断或过滤操作。
版权声明:转载请注明来源 心伤的瘦子@乌云
漏洞回应
厂商回应:
危害等级:低
漏洞Rank:5
确认时间:2012-12-26 16:13
厂商回复:
非常感谢您的报告。这个问题我们已经确认,正在与业务部门进行沟通制定解决方案。如有任何新的进展我们将会及时同步。
最新状态:
暂无