跨站脚本的名称源自于这样一个事实,即一个Web站点(或者人)可以把他们的选择的代码越过安全边界线注射到另一个不同的、有漏洞的Web 站点中。当这些注入的代码作为目标站点的代码在受害者的浏览器中执行时,攻击者就能窃取相应的敏感数据,并强迫用户做一些用户非本意的事情。
在本文的上篇中,我们详细介绍了当前Web应用所采取的安全措施,如同源策略、cookie安全模型以及Flash的安全模型;而本文将介绍跨 站脚本漏洞利用的过程,并对HTML注入进行深入分析。
一、跨站脚本漏洞利用的过程
现在,您已经熟悉了浏览器中的各种安全技术,下面我们开始设法利用XSS规避这些安全技术。XSS的主要目标是通过把攻击者选择的 JavaScript、VBScript或者其它为浏览器所接受的脚本语言注入到(放进)某些Web应用程序之中。只要攻击者可以将脚本植入有弱点的 Web应用程序中的任何地方,浏览器就会认为这个脚本是来自该有弱点的Web应用程序,而非非出自攻击者之手。
这样的话,该脚本就能够在这个有弱点的Web应用程序的域中运行了,并能进行下列活动:有权读取那个有弱点的Web应用程序使用的 Cookie;能够看到该有弱点的Web应用程序提供的页面的内容,甚至能将它们发送给黑客;改变有弱点的Web应用程序的外观;回调运行有弱点的Web 应用程序的服务器。
大体上,跨站点脚本攻击可以分为三步进行:
1.HTML注入。我们将介绍把脚本注入到Web应用程序的各种可能的方法。所有HTML注入范例只是注入一个JavaScript弹出式的警 告框:a_lert(1)。
2.做坏事。如果您觉得警告框还不够刺激,我们将讨论当受害者点击了一个被注入了HTML代码的页面链接时攻击者能作的各种的恶意事情。
3.诱捕受害者。我们论述如何强制或者诱使受害者执行恶意JavaScript代码。
一、HTML注入简介
将HTML和(更为重要的)脚本代码注入Web应用程序的方法简直太多了。如果某个Web应用程序的HTTP响应中“照搬”了在HTTP请求中 输入的内容,例如尖括号、圆括号、句号、等号等,那么说明这个Web应用程序和域具有HTML注入漏洞,并且该漏洞十有八九可以用于XSS。
本节将为读者介绍最常见的HTML注入方法,但是无法包括所有方法,因为这些方法是在太多了。对于大多数小型至中型的网站来说,这些技术很可能 仍然奏效。只要有耐心,那么您或许也能够使用其中的一种技术成功应用于一个大型Web站点。
下面我们将分门别类的介绍各种注入方法。
二、传统的反射式和存储式HTML注入
传统的XSS攻击是一种反射式的HTML注入攻击,借此,一个Web应用程序接受在HTTP请求中的用户输入。该Web应用程序会返回一个 HTTP响应,其主体中将包含原封不动的用户输入。如果该服务器的响应跟用户的原始输入完全一致,那么这些用户输入就会被浏览器当作有效的HTML、 VBScript或者JavaScript进行解释。考虑下列的服务器端的
展示了这段代码放置到http://publicpages.daxue.edu/~someuser/MyPhp.php 上 后,客户端看到的页面内容。
图1 一个简单的PHP脚本,用以接收用户输入(MyPhp.php) |
当用户点击“提交查询”按钮时,就会生成下列GET请求:
http://public-pages.daxue.edu/~someuser/MyPhp.php?input=hahaha
这个PHP应用程序看到用户输入的“hahaha”后,将响应一个页面,如图2所示。
图2 用户输入“hahaha”后MyPhp.php回复的响应 |
下面显示的是图2中看到的页面的HTML 源代码,为醒目起见用户输入的内容这里以蓝色字体显示。
您输入的内容为: "hahaha".
注意,实际上这里用户可以输入任何东西,例如〈 script 〉 a_lert( 1 )〈 / script 〉、〈 body onload = a_lert( 1 ) 〉、〈 img src = x onerror = a_lert( 1 ) 〉 或别的东西来把JavaScript代码注入到该页面。如果输入 的话,将向服务器发送下列GET请求:
http://publicpages.daxue.edu/~someuser/MyPhp.php?input= <script>a_lert(1)</p> <p></script>
如前所述,这个PHP应用程序只是把用户输入放到返回的响应页面中。这时候浏览器会把这些用户输入的内容当作JavaScript指令,同时认为该 脚本来自服务器,这可真是应了那句老话“拿着鸡毛当令箭”了,所以浏览器就会执行这些JavaScript代码。图3展示了用户看到的样子。
图3 用户输入“ ”后MyPhp.php回复的响应 |
上图中显示的页面的源代码如下所示,其中用户输入用蓝色字体表示。
您输入的内容为: " ".
这是将 注入http://public-pages.daxue.edu/~someuser/MyPhp.php得到的结果。这个例子是一种典型的反射式的 HTML注入,因为用户在HTTP请求中发送JavaScript代码,同时Web应用程序立即响应(反射回)一个完全相同的JavaScript代码。 只要用户单击了下列链接,这个脚本就会执行:
http://publicpages.daxue.edu/~someuser/MyPhp.php?input=
从攻击者的角度来看,利用注入的ML代码让恶意的web页面完成单击或者指定次数的点击是非常重要的。假设前面的PHP应用程序只接受POST请 求,而不接受GET
在这种情况下,攻击者无法像上面的GET请求那样直接通过诱骗受害者点击一个链接来注入HTML代码;现在,他们必须采取一些额外的步骤。为此,攻 击者可以创建下列HTML页面
当用户单击了指向上述HTML页面的链接时,就会对http://public-pages.daxue.edu/~someuser /MyPhp.php进行HTML注入。当然,攻击者也能利用HTML注入干别的坏事,而不仅仅象征性地调用一个JavaScript的弹出窗口。“第二 步:做坏事”部分将解释攻击者除了弹出一个窗口外还能做些什么。
存储式HTML注入跟反射式HTML注入非常相似,唯一区别在于攻击者将脚本植入Web应用程序后,这些脚本会被Web应用程序存储到一个可以检索 的地方。例如,对于允许用户张贴和阅读消息的网络论坛,攻击者可以在张贴消息时注入HTML代码,然后其它用户阅读这则含有脚本的消息时,其中的脚本就会 执行。
三、定位存储式和反射式HTML注入点
为了寻找存储式和反射式HTML注入点,可以尝试在所有表单输入以及GET或者POST请求的所有参数中注入脚本。我们要假设参数/值对中的值都可 能有漏洞。甚至尝试在新生成的参数中注入HTML代码,如下所示:
〈 script 〉 a_lert ( ’ parameter ’ )= <script>a_lert(’value’)< /script ><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /></p> <p>或者您也可以尝试在Web应用程序其它的部分加入参数/值对,并在值部分注入脚本。大多数现代Web应用程序中,都有数不清的潜在HTML注入点,并且总有一两处是可用的。不要放过每个参数值对、URL、HTTP头部等等,要尝试所有可能注入脚本的地方——处处皆有可能!HTML注入点很可能是一些出其不意的地方。</p> <p>有时候,一些简单的HTML注入测试串例如 <SCRIPT>a_lert(1)</script> 不起作用,因为这些测试字符串并不出现在响应的HTML主体区。举例来说,假如向http://search.engine.com/search?p= 发送的这个请求返回的响应中,其预填充表单字段内是我们的HTML注入字符串,如: