Flash应用程序安全全攻略(组图)

Adobe的Flash技术已经变得越来越流行,现在它不仅用于创建动画和广告,而且还用来开发复杂的互联网应用软件。

  

  一、XSS威胁

  从事Web应用程序的开发或者测试工作的人都知道,Web应用程序有一个常见的安全漏洞,即通常所说的跨站点脚本攻击(XSS)。一般地,如果一个应用程序接受不可信任的源提供的恶意代码,并且在没有对这些数据进行消毒处理的情况下直接将其返回给毫无防备的用户的话,就会发生XSS。虽然Flash应用程序对XSS及其他类型的安全威胁也没有免疫能力,但是web管理员和Flash应用程序开发人员却能够通过采取相应的安全措施来提高这种新兴技术的安全性。

  一般情况下,进行跨站点脚本攻击时,攻击者需要将恶意脚本代码(诸如t或者VBt代码)注入到Web应用程序中,这通常是通过哄骗用户单击一个链接或者访问一个邪恶的网页来完成的。随后,该web应用程序将在受害者的web会话的上下文中显示并执行注入的代码。这种攻击通常能导致用户帐户失窃,但是却不会导致执行命令,除非同时利用了浏览器的安全漏洞。因为SWF程序可以嵌入到网站中,并对HTMLDOM(文档对象模型)有完全的访问权,所以可以通过利用它们来发动XSS攻击。想像一个显示第三方Flash广告的免费电子邮件web服务:一个恶意的广告商可以创建一个恶意的SWF应用程序来劫持您的电子邮件帐号,以便发送垃圾邮件。默认时,FlashPlayer对同域的DOM具有完全的访问权限。

  下面介绍针对SWF应用程序的XSS攻击的基本流程。第一步,攻击者必须首先设法将代码注入到应用程序中,以便让代码重新显示给其他用户。Adobe为程序员提供了各式各样的用户界面组件,诸如组合框、单选按钮以及文本字段等,它们的用法跟HTML表单对象极为相似。此外,让SWF应用程序接受从外部输入的参数的方法也很多。

  我们可以使用 < T > 和< d >标签将属性FlashVar嵌入到一个HTML文档中。

  图1

  此外,还可以直接通过URL传入数据:

  图2

  另外,可以利用类LoadVars来装载外部数据。

  图3

  对于Actiont2来说,FlashVars会被自动导入到Flash应用程序的变量空间,但是在Actiont3中,加载外部参数时需要额外的代码来完成。一个常见的错误是,从FlashVars或者URL参数接受数据后,没有经过恰当的输入验证就直接将它们传递给了与浏览器直接通信的那些函数了。Actiont2中的函数getURL以及Actiont3中的函数navigateToURL具有将指定的URL装载到一个浏览器窗口的能力。可以考虑一下以下Actiont代码:

  图4

  该代码直接利用一个来自外部源的变量来调用函数getURL,这会将用户重定向至指定的URL。例如,攻击者可能会建立如下所示的请求:

  图5

  发出该请求之后,会弹出一个t警告框,并显示站点cookie的内容。Cookie经常用于存储敏感的帐户数据,诸如会话标识符等。DOM是一种标准对象模型,用来以树状结构表示HTML;DOM可被t代码用于动态刺探或者修改HTML页面。可以考虑下面的t代码,它将更改在这个HTML页面上的第一个图像的属性source。属性source被修改后,在该页面上显示的图像也将随之改变。

  图6

  攻击者常用的一种手法是,通过修改HTMLDOM插入一幅新的图像,并让该图像的属性source指向在攻击者所控制的服务器上的一个文件,同时将cookie内容作为一个参数。通过这种方法,攻击者只要监视他的计算机的日志就能够获取cookie数据。如果其中含有会话id的话,攻击者就能够完全控制用户的帐户,直至会话到期为止。还有一个Actiont函数可用于发动XSS攻击,它就是fscommand。SWF文件可以通过这个fscommand函数跟FlashPlayer或者托管FlashPlayer的程序进行通信。通常情况下,FlashPlayer会驻留于一个Web浏览器中,但是它也可以位于其他能够托管ActiveX控件的程序中。函数fscommand由两个部分组成:一个命令和一个参数。下面的fscommand函数将发送一个changeText命令,该命令的参数是由FlashVar来指定的。

  图7

  清单 1中的t代码因此能留驻在处理SWF应用程序发送的命令的HTML文档中。它只是取得参数,然后修改由text指定的HTML元素。开发人员应该注意从用户那里接收的、用于fscommand函数的输入数据的类型,以及各参数在HTML文档中是如何使用的。

  清单 1. 接收fscommand的代码

图8

  清单 2. 简单的密码检查代码

图9

  上述的示例代码为攻击者直接向DOM注入HTML或者脚本代码提供了方便之门,例如,下面的请求将包含并执行一个存放在远程主机上的t文件。

  图10

  二、HTML格式的组件  Adobe可以支持标准的HTML标签的一个子集,我们可以使用Actiont2.0中的TextField组件或者TextArea组件把这些受支持的HTML标签可以放到Flash电影片段中。如果不对用于构造HTML的用户输入进行严格的验证的话,这两个组件都有可能被滥用。对image和anchor标签的验证需要格外仔细,因为它们尤其容易导致安全漏洞。在Flash中,利用标签不仅可以在SWF文件和电影片断中嵌入外部图象文件,而且还可以嵌入SWF文件和电影片断,从而发起各式各样的攻击。下面的代码会把来自外部源的数据赋给HTML的text组件:

  图11

  将t嵌入图像的尝试将会失败,因为Flash Player好像会验证图像是否真是一幅JPEG、GIF 或者PNG格式的图像。

  图12  但是以下代码将向您证明,FlashPlayer所做的验证太小儿科。它只是检查给定的source属性是否以字符串.jpg结尾的,因此,只需添加一个类似C语言的行注释,我们无需改变这个脚本代码的功能便可哄骗FlashPlayer去执行标签中的脚本。浏览器一旦加载了这个SWF文件,不需要人工介入该t就会被执行,并出现一个弹出式窗口。

  图13

  使用此方法我们可以很轻松地将t或者VBt注入TextArea组件中。以下请求说明对于锚标签没有这样的验证,但是这类XSS攻击要求人工介入。用户必须单击这个连接才会执行代码。

  图14  就像前面提到的那样,标签不仅能够装载实际的图象文件,而且还可以装载SWF文件。这可能导致一个不怀好意的SWF文件被载入到一个受信任的应用程序中。当装载其他SWF文件时,应该使用一个框罩来限制这个子SWF文件的显示区。如果原始的SWF没有设置框罩,那么子SWF文件就有可能覆盖整个播放区域。这可用于欺骗受信任的应用程序。但是如果这个注入的SWF来自一个外部域的话,Flash安全策略仍旧对其有效。

  三、Actiont的函数协议

  上述的例子使用了t来演示用户常见的XSS攻击,但是有一个专门用于Flash的协议即asn,它可以致使一个连接调用一个Actiont函数。例如,当用户点击了存放在TextArea组件中的锚点时,下面的代码会调用带两个参数的本地函数foo。

  图15

  显而易见,这种能够从HTML组件内部直接调用Actiont函数的能力存在极大的安全隐患。可以考虑一下清单2所示的一个简单Flash应用程序,该程序通过接收用户名和口令来进行身份验证。当用户输入了错误的密码时,用户名以基于HTML的TextArea组件形式回显给用户。假设一个输入了如下所示的用户名,并随意猜了一个密码。

  图16

  应用程序将通知这个用户,提供的用户名/密码无效,同时用户注入的锚也作为HTML输出的一部分显示了出来。当用户点击这个链接时,setPassword函数将会被调用,从而将密码设为abc。上例说明了允许用户执行任意的Actiont函数来操纵程序的应用程序数据是非常危险的。如果一个Flash应用程序中存在持久性的XSS安全漏洞,这会导致存心不良的用户能够让其他用户在受信任的沙箱中执行任意的Flash函数。受本地信任的SWF文件甚至能读取本地的文件,并向任意服务器发送消息。Actiont包含有丰富的函数库,因此攻击者可以通过更高级的攻击类型利用这些库函数进行联网和通信,以至于访问本地的文件系统。

  四、未初始化的变量

  PHP程序员可能听说过一种有争议的特性,叫做RegisterGlobals,该特性允许从POST和GET请求将请求中的变量注入到一个脚本的变量空间中。当然,该特性并不常用,甚至有的程序员都不知道该特性的存在,由于备受抨击,所以将在新的PHP6中去掉该特性。理论上,使用registerglobals也有可能写出完全安全的程序,但是现实中在Web应用程序中发现的大量漏洞都是由于该特性使用不当所导致的。

  Actiont也有一个类似的特性,不过在版本3的时候已将其取消了,但是因为Actiont2依旧在Flash社区内广泛使用,所以这个问题仍然值得我们关注。任何未初始化的变量都可以作为FlashVar进行初始化。当程序员忘记给关键变量赋初值或者将变量指定为undefined的时候,很可能会带来后患。可以考虑一下清单3中的代码,它决定用户是否被允许查看一些机密信息。

  清单3. 依赖于未初始化变量的代码示例

图17

  程序员依赖于这样一个事实,即如果变量userLoggedIn没有初始化,它就会被设为undefined。而undefined这个值在条件语句中被作为false对待。绕过Actiont2中的代码很容易,因为变量userLoggedIn未经初始化。只需在GET请求或者在HTML中作为一个对象参数将userLoggedIn设为true,如下所示:

  图18

  在Actiont3中,FlashVars只能通过LoaderInfo类的meter属性进行访问,这使得针对未初始化的数据的这种攻击不再可行,不过,开发人员仍然应该仔细检查传给SWF的所有参数。

  五、SWF之间的通信

  与浏览器的Cookie机制相似,本地共享对象(LSOs)为SWF应用程序提供了少量的持久性存储空间。LSO会受到特定的域、本地路径或者HTTPS连接等方面的限制。在清单4中的代码将生成一个共享对象,并且该对象可以被存储在/a/b或者其子目录(如a/b/c)下的其它SWF程序所访问。函数flush将强制将这个对象写到这个文件中。

  清单4. Sharedt示例代码

  图19

  如果您打算把机密信息储藏在一个本地共享对象之内,那么可以把标志secure设为true,这样一来就只有通过HTTPS才能访问这个SWF。不管它们是如何被传输的,LSOs是以明文的形式存放在客户端的机器中的。由于Actiont自身没有提供加密类,所以如果想保护存储在LSO中的重要的信息的话,就只好使用第三方加密程序库了。

  为了让运行于同一个客户端机器上的SWF应用程序之间可以直接相互通信,Actiont提供了LocalConnection类。这时必须有一个swf应用程序充当接收方,另一个充当发送方。这些SWF应用程序并不一定非要运行在同一个浏览器中不可,但是默认时,只有位于相同的域中的SWF程序才能相互通信。在调试阶段,开发人员经常使用allowDomain函数来放宽这个默认的安全限制。清单5中的代码,让LocalConnection来接收数据。

  清单5. 接受 LocalConnection 的代码

图20

  如果产品代码中遗留了allowDomain("*”)将是非常危险的,因为它允许来自任何域的任何SWF程序都能访问你的应用程序的内部函数。通配符最好的使用方式是只允许相同的域或者子域之间的SWF可以进行通信。例如,allowDomain(“*.test.com”)将允许在www.test.com和mail.test.com之间的通信。为了发送数据,可以使用LocalConnection函数,如清单6所示。如果不使用函数connect的话,发送方可以使用想要函数名和参数来直接调用函数send。

  清单 6. 发送LocalConnection的代码

图21

  六、正确的输入验证

  输入验证的常见方法是检查一块数据是否匹配一个正则表达式。正则表达式的作用是描述一个字符模式。Actiont在版本3开始对正则表达式提供本地支持,并使用EMCAt语言规范来实现正则表达式。仍然使用Actiont2的传统开发人员在验证数据时,却无法借助正则表达式或者诸如As2lib之类的第三方程序库。可以考虑一下以下有弱点的代码:

  图22

  不要盲目信任用户提交的电子邮件,而要使用正则表达式进行双重检查来将恶意用户拒之门外。清单7中的代码给出了一个使用正则表达式测试一个电子邮件地址是否合法的函数示例。

  清单 7.验证电子邮件的规则表达式

  图23

  如果您的应用程序必须迁移到Actiont3.0,那么即使不用正则表达式也能进行输入验证,尽管此解决方案不太优雅并且不太合乎RFC标准。不用正则表达式验证输入时,一般地需要调用许多标准串函数,如清单8所示。

  清单8. 无规则表达式的电子邮件验证

图24

  如果您必须使用用户输入的数据来供getURL函数或者HTML文本组件使用,那么可以利用正则表达式定义那些数据是可以接受的,并只接受http或者https协议处理程序用于有效的链接。不要依赖转义函数来进行输入验证。按照Flash帮助文档的规定,escape函数将参数转换成一个字符串,并以URL编码的格式对其进行编码,其中非数字字母字符被替代为%十六进制序列。可以考虑一下以下代码,它没有正确地使用escape函数来进行输入验证。

  图25

  Escape函数不能阻止恶意用户潜入t函数,并执行他们自己任意的脚本代码,例如请看以下请求:

  图26

  七、安全地公布内容

  不仅Flash开发人员应该花时间去验证输入,web管理员也应该通过设置安全措施来防止不可信的SWF文件访问浏览器和/或网络。可以通过 < d >标签把SWF应用程序作为对象嵌入在一个HTML页面中。您可以在影响安全策略的或者< t>标签之内规定三个可选参数。参数allowtAccess控制SWF文件是否能够访问HTML容器。而allowNetworking参数则控制SWF使用Actiont的网络API的能力。最后,allowFullScreen参数决定Flash应用程序是否被允许控制整个屏幕。

  参数allowtAccess有三个可能的值:

  always:允许SWF和HTML页面通讯,不管加载这个HTML页面的域名如何。只有在完全信任这个SWF的时候才能使用这个选项,它是FlashPlayer 7和早先的版本的默认行为。

  sameDomain:只有在两者位于同一个域中时才允许SWF应用程序修改底层的HTML页面。位于域www.a.com中的Flash应用程序不能修改位于www.b.com中的HTML页面。这个是FlashPlayer8及随后版本的默认行为。

  never :绝不允许在HTML页面和SWF应用程序之间进行通信。

  参数allowNetworking也有三个可能的值:

  all:SWF应用程序被允许使用网络API建立无限制的网络连接。

  internal:SWF应用程序不允许调用浏览器的导航或者交互API,但是被允许调用其他网络调用。

  none:禁止SWF应用程序使用任何网络API。

  参数allowFullScreen仅仅有两个可能的值:

  true :SWF应用程序被允许占用整个屏幕。 这个选项可能被恶意用于诱骗攻击。

  false:fullscreen模式不被允许。

  许多流行的论坛允许其管理员创建他们自己的BBCode以使得用户可以格式化讨论贴或者包含额外的内容。许多管理员已经增加了支持SWF的BBCodes。可以考虑一下以下不安全的HTML代码替换FlashBBCode。

  图27

  在一个有敌意的你不可以信任任何张贴的swf应用程序设置中,必须将在标签之内的allowNetworking、allowtAccess和allowfullscreen显式设置,以防止恶意应用程序进行非本意的网络或者脚本调用。不应依赖默认FlashPlayer安全设置,而应当假设一些用户无法或不愿意更新软件。清单9中的HTML代码给出了安全的设置。

  清单 9. 为 HTML 的t 标签添加适当的安全设置

图28

  八、安全分析工具

  目前,可用来对Flash应用程序进行安全审计的工具仍然不多。StefanoDiPaola已经编写了精巧的工具用来发现跨站点脚本攻击和跨站Flash漏洞,该工具名为SWFIntruder。这个工具提供了一组预定义的攻击方式,这些是可定制的,并能以半自动化的方式进行XSS测试。这个工具运行在Web服务器上,可以通过浏览器进行访问,它能显示全部未定义变量和SWF应用程序中所有已经实例化的变量。

  用户可以通过选择一个参数来测试和执行各种攻击,并提供XSS扫描的输出结果。SWFIntruder的一个主要局限性是它仅仅能分析低于版本8或者Actiont1或者2创建的Flash应用程序。当审计封闭源码的Flash应用程序或元件的时候,反编译器就显得尤为重要了。反编译器提供了编译程序的逆过程,因为它将低级计算机代码转换为一个高层的抽象化代码。Flash反编译器接受swf应用程序的字节码,然后生成相应的Actiont代码,而后者相对来说更易于人类阅读。为了揭露安全性缺陷,使用静态分析工具来针对生成的Actiont代码进行分析就更方便了。免费的反编译器的一个例子是Flare,它将从一个swf应用程序中提取全部Actiont文件。不过,就像SWFIntruder一样,Flare不支持Actiont。但是有商业产品可以从Actiont1/2或者Actiont3应用程序生成FLA文件,前提是必须掏钱。

  九、结束语

  在开发基于web的富应用程序的时候,许多Flash应用程序开发人员并没有意识到它们正受到恶意用户的各种安全威胁。尽管安全社区对XSS、未初始化的变量攻击及其他输入验证漏洞并不陌生,但是Flash提供了一种新的攻击类型,尤其是那些无防备的和未经严格测试的Flash程序。不过,只要经过程序员、测试人员和web管理员密切配合,经过适当的培训并对输入端进行严格检查,就能够有效减轻Flash应用程序中的跨站点脚本攻击漏洞所带了的威胁。

【作者:佚名 来源:比特网】 (责任编辑:和讯网站)
来源:和讯 作者:

免责声明:本文仅代表作者个人观点,与世界朋友网无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

[责任编辑:世界朋友]