一、概述
XSS(跨站腳本)概述
Cross-Site Scripting 簡稱為“CSS”,為避免與前端疊成樣式表的縮寫"CSS"沖突,故又稱XSS。一般XSS可以分為如下幾種常見類型:
1.反射性XSS;
2.存儲型XSS;
3.DOM型XSS;
XSS漏洞一直被評估為web漏洞中危害較大的漏洞,在OWASP TOP10的排名中一直屬於前三的江湖地位。
XSS是一種發生在前端瀏覽器端的漏洞,所以其危害的對象也是前端用戶。
形成XSS漏洞的主要原因是程序對輸入和輸出沒有做合適的處理,導致“精心構造”的字符輸出在前端時被瀏覽器當作有效代碼解析執行從而產生危害。
因此在XSS漏洞的防范上,一般會采用“對輸入進行過濾”和“輸出進行轉義”的方式進行處理:
1.輸入過濾:對輸入進行過濾,不允許可能導致XSS攻擊的字符輸入;
2.輸出轉義:根據輸出點的位置對輸出到前端的內容進行適當轉義;
二、反射型XSS(get)
①在前端html修改可輸入長度,方便注入語句的使用。
②輸入<script>alert('xss')</script>
get形式的XSS會生成相應的url是比較好利用的一種漏洞。
三、反射型XSS(post)
①首先登陸 admin-123456
② 輸入<script>alert('XSS')</script>
並且我們觀察瀏覽器發現post的漏洞並不會在url中顯示出來。
四、存儲型XSS
①輸入<script>alert("xss")</script>
這類漏洞危害大,注入語句會寫入數據庫中,每次進入都會執行。
五、DOM型XSS
①什么是DOM?
DOM 是 W3C(萬維網聯盟)的標准。
DOM 定義了訪問 HTML 和 XML 文檔的標准:
“W3C 文檔對象模型 (DOM) 是中立於平台和語言的接口,它允許程序和腳本動態地訪問和更新文檔的內容、結構和樣式。”
W3C DOM 標准被分為 3 個不同的部分:
- 核心 DOM - 針對任何結構化文檔的標准模型
- XML DOM - 針對 XML 文檔的標准模型
- HTML DOM - 針對 HTML 文檔的標准模型
編者注:DOM 是 Document Object Model(文檔對象模型)的縮寫。
②漏洞利用
DOM可以理解為訪問HTML的標准接口,DOM里面會把我們的HTML分成一個DOM樹
我們可以以這棵樹為入口,通過DOM的某些方法對樹進行操作,比如對標簽的添加、改變和刪除等等。
DOM相當於在前端提供了一個 通過JS去對HTML進行操作 的接口
③觀察源碼
function domxss(){ var str = document.getElementById("text").value; document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>"; } //試試:'><img src="#" onmouseover="alert('xss')"> //試試:' onclick="alert('xss')">,閉合掉就行
在此的js代碼,通過getElementById獲取到了標簽ID為text的內容賦值給str,然后把str的內容通過字符串拼接的方式寫到了a標簽的href屬性中,a標簽會寫到id為dom的div標簽中
從上面可以看出來,通過value方式將text的值賦值為str,也就是框里面的值,然后通過innerHTML將標簽內的值取出來,比如<label id="lb1">this is a label</label>,取出來的值就是this is a label。所以結合前面的'做一個閉合,像<script>這種有前后標簽閉合的就不太方便用了,用提示里面的onclick來構造,' onclick=alert('xss')>就可以了。
④構造閉合語句
' onclick=alert('xss')>
六、DOM型XSS-X
①觀察源碼
function domxss(){ var str = window.location.search; var txss = decodeURIComponent(str.split("text=")[1]); var xss = txss.replace(/\+/g,' '); // alert(xss); document.getElementById("dom").innerHTML = "<a href='"+xss+"'>就讓往事都隨風,都隨風吧</a>"; } //試試:'><img src="#" onmouseover="alert('xss')"> //試試:' onclick="alert('xss')">,閉合掉就行
window.location.search
該屬性獲取頁面 URL 地址,window.location 對象所包含的屬性如下:
②構造語句' onclick=alert('xss')>
這一關和上一關的區別在於,這里的值是從URL中獲取到的,就像反射型XSS一樣。
七、XSS之盲打
盲打並不是一種攻擊類型,而是一種場景,輸入的東西並不會在前端顯示,而是提交到了后台。
登錄后台發現受到了攻擊
八、XSS之過濾
①輸入一些符號進行測試。
輸入 "'<>/
結果發現符號似乎都沒有被過濾掉。
②輸入<script>alert('xss')</script>
但是發現script似乎被過濾掉了
③大小寫試試
輸入 <sCRipt>alert('xss')</sCRipt>
直接成功了
④觀察源碼
$html = ''; if(isset($_GET['submit']) && $_GET['message'] != null){ //這里會使用正則對<script進行替換為空,也就是過濾掉 $message=preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/', '', $_GET['message']); if($message == 'yes'){ $html.="<p>那就去人民廣場一個人坐一會兒吧!</p>"; }else{ $html.="<p>別說這些'{$message}'的話,不要怕,就是干!</p>"; } }
我們發現這里是對script進行了過濾,雙寫也就不能繞過了,沒有區分大小寫所以可以繞過。
九、XSS之htmlspecialchars
①了解一下htmlspecialchars(),函數把一些預定義的字符轉換為HTML實體,下列都是預定義字符。
- & (和號) 成為 &
- " (雙引號) 成為 "
- ' (單引號) 成為 '
- < (小於) 成為 <
- > (大於) 成為 >
這里我們需要注意,默認情況的編碼是不會對’(單引號)進行編碼的,嘗試利用它來構造
首先我們試試onclick=alert(‘xss’)
這里發現后面多出了一個’ 干脆在alert前面再加一個’單引號 'onclick='alert('xss')
發現還是不太行,最后直接用雙引號替換掉xss的單引號
' onclick='alert("xss")'
輸入: ’ onclick=‘alert(“xss”)
成功閉合,並且彈窗,不過這里雙引號居然也沒有被轉義,查了后台php
,確實是默認的編碼風格,有點奇怪,當然如果被轉義這里也可以彈整形類的嘛,影響不大,經過了大量測試,應該是被當作字符串處理了,所以就沒有被當作標簽進行轉義。
十、XSS之href輸出
查看源碼,這次htmlspecialchars函數使用了ENT_QUOTES類,也加上了對單引號的轉義,但是在a標簽的href屬性里面,可以使用javascript協議來執行js
javascript:alert(123)
源碼
$html=''; if(isset($_GET['submit'])){ if(empty($_GET['message'])){ $html.="<p class='notice'>叫你輸入個url,你咋不聽?</p>"; } if($_GET['message'] == 'www.baidu.com'){ $html.="<p class='notice'>我靠,我真想不到你是這樣的一個人</p>"; }else { //輸出在a標簽的href屬性里面,可以使用javascript協議來執行js //防御:只允許http,https,其次在進行htmlspecialchars處理 $message=htmlspecialchars($_GET['message'],ENT_QUOTES); $html.="<a href='{$message}'> 閣下自己輸入的url還請自己點一下吧</a>"; } }
十一、XSS之js輸出
①查看源碼
<script> $ms='1'; if($ms.length != 0){ if($ms == 'tmac'){ $('#fromjs').text('tmac確實厲害,看那小眼神..') }else { // alert($ms); $('#fromjs').text('無論如何不要放棄心中所愛..') } } </script>
輸入tmac,誒呦不錯呦。
②這里使用的時候應該是先把之前的<script>
給閉合,然后就可以執行自己的JS
了。</script><script>alert('xss')</script>
,直接成功彈框。
這里講輸入動態的生成到了js中形成xss,javascript里面是不會對tag和字符實體進行解釋的,所以需要進行js轉義
//講這個例子主要是為了讓你明白,輸出點在js中的xss問題,應該怎么修?
//這里如果進行html的實體編碼,雖然可以解決XSS的問題,但是實體編碼后的內容,在JS里面不會進行翻譯,這樣會導致前端的功能無法使用。
//所以在JS的輸出點應該使用\對特殊字符進行轉義