(1)确保代理服务器能够正确拦截浏览器扩展送出的所有流量。如有必要,使用嗅探器确定任何未正确拦截的流量。
(2)如果客户端组件使用标准的序列化方案,确保拥有解压并修改序列化数据所需的工具。如果浏览器组件使用专用编码或加密机制,则需要解译或调试该组件,对其进行全面测试。
(3)检查服务器返回的触发关键客户端逻辑的响应。通常,及时拦截并修改服务器响应能够“解锁”客户端GUI,从而轻松发现并执行复杂或多步骤特权操作。
(4)如果应用程序执行不得由客户端组件执行的任何关键逻辑或事件(如在赌博应用程序中发牌或摇骰子),这时,可以寻找执行关键逻辑和与服务器通信之间的任何联系。如果客户端在确定事件的结果时不需要与服务器进行通信,这说明应用程序肯定存在漏洞。
迄今为止,在对浏览器扩展组件实施攻击时,最彻底的方法,是反编译对象、对源代码进行全面分析、修改源代码(如有必要)以改变对象的行为,然后重新编译源代码。如前所述,浏览器扩展被编译成字节码。字节码是一种由相关解释器(如Java虚拟机或Flash播放器)执行的、不依赖于特定平台的高级二进制表示形式,每种浏览器扩展技术都使用它们自己的字节码格式。因此,浏览器扩展能够在解释器本身可运行的任何平台上运行。
字节码表示形式的高级本质意味着,从理论上讲,最终可以将字节码反编译成类似于最初的源代码的内容。但是,字节码可能采用了各种防御机制,以防止反编译,或者输出非常难以理解或解释的反编译代码。
尽管字节码采取了上述防御机制,但是,在理解和攻击浏览器扩展组件时,反编译字节码仍然是首选方法。通过反编译字节码,可以查看客户端应用程序的业务逻辑、访问它的全部功能,以及有针对性地修改其行为。
1.下载字节码
第一步是下载要处理的可执行字节码。一般情况下,字节码会从HTML源代码(运行浏览器扩展的应用程序页面)中指定的URL加载到单独的文件中。Java applet通常使用<applet>标签加载,其他组件则使用〈object〉标签加载。例如:
某些情况下,加载字节码的URL可能并不是非常明显,因为组件可能使用不同浏览器扩展框架提供的各种包装脚本(wrapper script)进行加载。确定字节码的URL的另一种方法,是在浏览器加载浏览器扩展后,在代理服务器历史记录中查找该URL。如果采用这种方法,需要了解以下两个可能的问题。
一些代理服务器工具对代理服务器历史记录应用过滤器,以隐藏渗透测试员通常并不感兴趣的视图项目,如图像和样式表文件。如果找不到与浏览器扩展字节码有关的请求,那么应对代理服务器历史记录显示过滤器进行修改,以显示所有项目。
通常,相比于图像等其他静态资源,浏览器会在缓存中更多地存储已下载的扩展组件字节码。如果浏览器已加载某个组件的字节码,那么,即使完全刷新使用该组件的页面,浏览器也不会再次请求该组件。在这种情况下,可能需要完全清除浏览器的缓存,关闭每一个浏览器实例,然后启动新的浏览器会话,才能强制浏览器再次请求字节码。
确定浏览器扩展字节码的URL后,只需将该URL粘贴到浏览器的地址栏中,然后,浏览器会提示你将字节码文件保存到本地文件系统中。
提示
如果已在Burp Proxy历史记录中确定了与字节码有关的请求,并且服务器的响应中包含完整的字节码(而没有引用以前缓存的副本),这时,可以将字节码直接保存到Burp内的文件中。最可靠的方法是选择响应查看器中的“标题”(Herders)选项卡,右键单击包含响应主体的下方窗格,然后从上下文菜单中选择“复制到文件”(Copy to File)。
2.反编译字节码
字节码通常以独立文件包的形式发布,可能需要进行解压缩才能获得单个字节码文件,然后再将其反编译成源代码。
正常情况下,Java applet打包成.jar(Java档案)文件,Silverlight对象则打包成.xap文件。这两种文件均使用zip档案格式,因此,只需用.zip扩展名重命名这些文件,然后使用任何.zip读取器就可以将它们解压缩成单个的文件。Java字节码包含在.class文件中,Silverlight字节码包含在.dll文件中。解压缩相关文件包后,需要反编译这些文件才能获得源代码。
Flash对象打包成.swf文件,在使用反编译器之前,不需要对这类文件进行解压缩处理。
实际的反编译字节码需要使用一些特定的工具,这些工具因所采用的浏览器扩展技术的类型而异,我们将在以下几节介绍这些工具。
Java工具
Java字节码可以使用称为Jad(Java反编译器)的工具反编译成Java源代码,该工具的下载地址如下:
Flash工具
Flash字节码可以反编译成ActionScript源代码。另一种更加有效的方法,是将字节码反编译 成人类可读的格式,而不是将其完全反编译成源代码。
要反编译和反汇编Flash,可以使用以下工具:
Flasm——www.nowrap.de/flasm;
Flare——www.nowrap.de/flare;
SWFScan——www.hp.com/go/swfscan(此工具针对Actionscript 2和Actionscript 3)。
Silverlight 工具
Silverlight字节码可以使用一种称为.NET Reflector的工具反编译成源代码,该工具的下载地址为:
www.red-gate.com/products/dotnet-development/reflector/
3.分析源代码
获得组件的源代码或类似代码后,就可以采取各种方法对其实施攻击。通常,第一步是查看源代码,以了解组件的工作机制及其包含或引用的功能。以下是需要寻找的一些项目:
在客户端发生的输入确认或其他安全相关逻辑和事件;
在向服务器传送数据之前用于包装用户提交的数据的模糊或加密程序;
在用户界面中不可见,但可以通过修改组件进行解锁的“隐藏的”客户端功能;
对以前未通过解析应用程序确定的服务器端功能的引用。
通常,查看源代码可以揭示组件中的一些有趣的功能。渗透测试员希望修改或操纵这些功能,以确定潜在的安全漏洞。希望执行的操作包括:删除客户端输入确认、向服务器提交未标准化的数据、操纵客户端状态或事件,或者直接调用组件中的功能。
如以下几节所述,可通过各种方式修改组件的行为。
在浏览器中重新编译并执行
要改变组件的行为,可以对反编译得到的源代码进行修改,重新将其编译成字节码,然后在浏览器中执行修改后的组件。需要操纵关键的客户端事件,如在赌博应用程序中摇骰子时,通常首选这种方法。
要重新编译源代码,需要使用与采用的技术有关的开发者工具。
对于Java,可以使用JDK中的javac程序重新编译修改后的源代码。
对于Flash,可以使用flasm重新汇编修改后的字节码,或使用Adobe的某个Flash开发套件重新编译修改后的ActionScript源代码。
对于Silverlight,可以使用Visual Studio重新编译修改后的源代码。
将源代码重新编译成一个或多个字节码文件后,如果采用的技术需要,可能需要重新打包可分配的文件。对于Java和Silverlight,需要用修改后的字节码文件替换已解压的档案中的文件,使用zip实用程度重新压缩这些文件,然后根据需要将文件扩展名更改为.jar或.xap。
最后,需要将修改后的组件加载到浏览器中,使所做的更改在测试的应用程序中生效。可以通过多种方式达到这一目的。
如果可以在浏览器的磁盘缓存中找到包含原始可执行文件的物理文件,可以用修改后的版本替换该文件,然后重新启动浏览器。但是,如果浏览器并不对每个缓存的资源使用
不同的文件,或者浏览器只是将扩展组件缓存在内存中,这种方法可能无法生效。
可以使用拦截代理服务器修改加载组件页面的源代码,并指定另一个指向本地文件系统或受控的Web服务器的URL。正常情况下,这种方法很难奏效,因为更改加载组件的域可能会违反浏览器的同源策略,而且可能需要重新配置浏览器,或采用其他方法弱化同源策略。
可以使浏览器从原始服务器重新加载组件(如5.3.4节所述),使用代理服务器拦截包含可执行文件的响应,并用修改后的版本替换消息主体。在Burp Proxy中,可以使用“从文件中粘贴”(Paste from File)上下文菜单项达到这个目的。通常,这是最简单的方法,也是最不容易遇到上述问题的方法。
在浏览器以外重新编译并执行
有些时候,并不需要在执行组件的过程中修改组件的行为。例如,一些浏览器扩展组件会确认用户提交的输入,对这些输入进行模糊处理或加密,然后将其传送至服务器。在这种情况下,可以对组件进行修改,使其对任何未经确认的输入执行必要的模糊处理或加密,并在本地输出结果。然后,可以使用代理服务器在原始组件提交经过确认的输入时拦截相关请求,并用修改后的组件输出的值替换这些请求。
要实施这种攻击,需要对在相关浏览器扩展中运行的原始可执行文件进行修改,将其更改为可以在命令行中运行的独立程序。进行修改的方式因所采用的编程语言而异。例如,在Java中,只需要实施main方法。“Java applet:可用示例”小节将提供相关示例。
使用JavaScript操纵原始组件
在某些情况下,并不需要修改组件的字节码。相反,可以通过修改HTML页面中与组件交互的JavaScript来达到目的。
通过查看组件的源代码,可以确定组件的所有可直接从JavaScript调用的公共方法,以及组件处理这些方法的参数的方式。通常,除了可以从应用程序页面调用的方法外,还存在其他一些方法;另外,还能够了解有关这些方法的参数的用途及处理方式的详细信息。
例如,组件可能会公开这样的方法:调用该方法可以启用或禁用部分可见的用户界面。使用拦截代理服务器可以编辑加载该组件的HTML页面,修改其中的JavaScrip域在其中添加一些JavaScript,以解锁被隐藏的部分界面。