为什么Flash还荼毒人间?
Flash依然是一个威胁。在2017年,我报导了Facebook,Youtube,WordPress,Yahoo,Paypal和Stripe上的Flash漏洞,在过去的三年里,我有报告了超过50个赏金程序bug的flash漏洞,赚了80K+的奖金。而且还有更多的我没有报告,或者我报了也没有修复。
另外,Flash已经被新的javascript/html5特性所取代。这些特性增加了复杂度和新的类型的漏洞,比如不好的CROS实现,由postMessage或者XHR Request,引起的DOM Xsses。了解Flash的失误可以帮助设计实施更加安全的javascript程序。这个新的Youtube html5的Api很可能是从Youtube的Flash Api移植到lavascript上的,使得它学起来更有趣。实际上,我通过所掌握的Flash Api的知识就能找到Youtube的html5的xsses。
我会解释我在Youtube的Flash Api中发现的一些高级的Flash漏洞,并且在这个过程中和Html/javascript做一个对比。这个太专业了,所以有槽尽管吐。如果有人不太明白或者想增长新知识。你可以看一下这里的Flash安全模型。
逆向工程Youtube的Flash Api
Youtube Flash Api允许开发者在外部网站嵌入youtube的视频。
这是APi流程图:
这个入口函数,Youtube Wrapper,是一个位于youtube.com/v/[Video_ID]的一个Flash文件,这只是HTML页面和主App的一层包装。主App是一个大约100k的一个大Flash文件,被放置在域名为s.ytimg.com的沙盒内。
这些模块处理类似于副标题或者广告之类的可选函数。他们不能是单独的Flash文件,必须得被主App加载才行。
另外,还有一个Flash到JavaScript的Api,允许html页面给youtube api发送诸如play(),pause()之类的命令。Flash文件也会执行ajax风格的跨域请求,加载配置文件和视频内容。
用户信息泄露
从一个简单的漏洞开始讲起吧,这有一个在Flash ActionScript3中的简化版的Youtube封装器代码。
public class YoutubeWrapper extends Sprite{
private var user_name = "The Victim";
private var user_picture = "https://googleusercontent.com/.../victim_photo.jpg";
private var appLoader = new Loader();
public function YoutubeWrapper(){
// allow external javascript/Flash files to access its public properties
Security.allowDomain("*");
// load the Main App
this.appLoader .load(new URLRequest("https://s.ytimg.com/.../watch_as3.swf");
// add as child of display container
this.addChild(this.appLoader );
// loaderInfo.sharedEvents Api
this.loader.contentLoaderInfo.sharedEvents
.addEventListener("REQUEST_USERINFO", this.onRequestUserinfo);
}
private function onRequestUserinfo(event:Event){
// write the user info into the event.data property
// which is accessible to the sharedEvents caller
event.data.user_name = this.user_name;
event.data.user_image = this.user_image;
}
}
youtube封装器立即生成,它的属性“User_name”包含了google用户的名字(如果他是连接到google的)这个属性"user_picture"包含了用户轮廓图的链接。在这个bug中,攻击者会窃取这些数值。
youtube封装器能从开发者自己的Flash文件中加载(还是叫它恶意封装器)这种情况下,它们都能在一个不同的Flash保密的沙盒中执行。
加载一个外部的flash文件跟Html中加载\<iframe>很相似。如果这个iframe来自于一个跟它的父类不同的源,他们因为Same-Origin Policy (SOP)原则就不能访问到彼此的属性。
Youtube封装器包含了这段代码Security.allowDomain(“*”)来允许JavaScript给Flash app发送play(),Pause()等命令。这还意味着恶意封装器可以获取到任何公开的属性,就好像它也在同一个沙盒里一样。然而,它是访问不到私有属性的。
user_name这个属性提供了loaderInfo.sharedEvents用于加载器和一个已加载文件之间通信。当这个主app分发一个时间给这个sharedEvents接口。这个youtube封装器接收这个事件并使用event.data属性把用户信息发送回去。
这跟javascript的postMessage api允许跨域ifames通讯一样的道理。postMessage的api不仅可以被iframes和他的父类使用,还可以给其他链接到iframe和父类的window使用。任何任意域都可以通过window.open和window.frames获取这些链接,也不受被SOP限制。
如果恶意加载器能获取到这个特别的loaderInfo对象,就能给YouTube封装器发送一个事件并窃取用户信息。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!