一日在某站點(diǎn)發(fā)現(xiàn)一個(gè)找茬活動(dòng),感覺是另類的src就參與了一下。就發(fā)生了這次有趣的XSS測(cè)試過(guò)程。

0×00 開始
(注意1)XSS不僅存在于頁(yè)面上直觀所在的位置,所有用戶輸入的信息都有可能通過(guò)不同形式返回到頁(yè)面上,因此直接操作數(shù)據(jù)包來(lái)查找XSS顯得更加有效。
回到該站點(diǎn),在該站點(diǎn)一處生成app處存在一處忘記過(guò)濾。
發(fā)送的數(shù)據(jù)包如下:
appName=TEST&icon=&loadimage=%2Ftemplate201309%2F29%2Floadimage%2F1a8aaba1-42bd-401b-9995-0f7ba08f191b.png&diyAppid=0210bd39-de98-4a1b-b855-4b0a0732894a
經(jīng)過(guò)測(cè)試發(fā)現(xiàn)其中l(wèi)oadimage參數(shù)未經(jīng)過(guò)過(guò)濾,這也就是我說(shuō)的隱藏的輸入輸出位,最終直接構(gòu)造:
loadimage=xxxxx"%20onerror="alert(1)"

0×01 覺醒
在漏洞上報(bào)之后,程序員覺醒了,由于涉及其它頁(yè)面參數(shù)輸出過(guò)濾的影響,無(wú)法直接使用粗暴的編碼把”(雙引號(hào))過(guò)濾,而是使用一定的過(guò)濾規(guī)則來(lái)規(guī)避xss攻擊。
(注意2)XSS繞過(guò)一般針對(duì)于程序員所使用的過(guò)濾規(guī)則的疏漏,但是首要目標(biāo)應(yīng)該是在程序員未過(guò)濾的點(diǎn)上,而只有規(guī)則的不嚴(yán)謹(jǐn)才有繞過(guò)的可能。
在得到客服的回復(fù)確認(rèn)漏洞修復(fù)之后,再次回到該點(diǎn)進(jìn)行測(cè)試,繼而發(fā)現(xiàn)了有趣的情況。
測(cè)試代碼:
loadimage=xxxxx"%20onerror="alert(1)" à
經(jīng)過(guò)這個(gè)測(cè)試用例發(fā)現(xiàn),在空格之后的內(nèi)容經(jīng)過(guò)了一次處理,將其中alert替換成了***,onerror=直接刪除。
分析發(fā)現(xiàn)空格之后的內(nèi)容會(huì)被直接刪除,onXXX被直接刪除。
于是結(jié)合過(guò)往經(jīng)驗(yàn),使用大小寫來(lái)嘗試?yán)@過(guò)字符串替換。
測(cè)試代碼:
loadimage=xxxxx"onError="alert(1)" à
于是我們利用了瀏覽器的一個(gè)特性,在解析的時(shí)候?qū)㈦p引號(hào)與其后內(nèi)容分割,所以在源碼中是:
而解析過(guò)程中顯示:
(自動(dòng)添加空格)
之后就是要構(gòu)造我們的alert。(只有alert才是我想要的,什么prompt,confirm都不是我想要的。)
這里要說(shuō)到的就是轉(zhuǎn)編碼的利用。
詳文可參考:
http://drops.wooyun.org/tips/689
處于html上下文的字符串將會(huì)優(yōu)先進(jìn)行一次html解碼,而處于onXXXX、javascript:、script等標(biāo)簽之中的則處于javascript上下文,其中變量字符串將會(huì)執(zhí)行一次javascript解碼。
運(yùn)用這個(gè)特性,我們可以在onerror事件當(dāng)中使用html編碼來(lái)構(gòu)造任意字符,而其中所必須的字符為&,很幸運(yùn)的時(shí)該字符并未被過(guò)濾。因此我可以使用其構(gòu)造任意字符,達(dá)到繞過(guò)的效果。
直接構(gòu)造:
loadimage=xxxxx"onError="%26#x61lert(1)"
0×02 絕殺
再次提交客服,并得到修復(fù)確認(rèn)后,又進(jìn)行了一次測(cè)試,之后繼續(xù)有趣。
(注意3)確定過(guò)濾規(guī)則是繞過(guò)限制的第一步,通過(guò)已知規(guī)則構(gòu)造繞過(guò)payload來(lái)生成所需字符為最終目的。
繞過(guò)富文本大概的思路就是這樣。
繼續(xù)通過(guò)輸入不同字符串來(lái)檢查新增的過(guò)濾規(guī)則,最終得到幾條有用的信息:
==>
==>
本以為結(jié)合一下就成了,沒想到變成這樣:
==>
初步分析等到的規(guī)則:
1、onxxx= 將會(huì)去除on以及=和它們之間的內(nèi)容2、有 = 號(hào)就會(huì)檢查前面有沒有on3、tab %20(空格)之后的內(nèi)容全部清除4、碰到雙引號(hào)就停止刪除
大概統(tǒng)計(jì)了一下以上的過(guò)濾規(guī)則,就可以開始構(gòu)造payload了。
使用src=”1″onerroonerrorr=r生成onerror。
使用%0a(換行)來(lái)分割導(dǎo)致過(guò)濾不起作用。
最終完成了整條payload:
(這次不計(jì)較與alert了,使用上一條方法即可。)
最終截圖:

同樣可以解析成功!

0×03 利用
完整的XSS一定需要附帶利用的過(guò)程,可完整構(gòu)造payload還需要考慮很多情況,比如關(guān)鍵字符串的替換、輸出點(diǎn)允許的最大字長(zhǎng)、是否可影響其他用戶或管理員。
最終偵查該點(diǎn),長(zhǎng)度為262個(gè)字符,替換了script、create等字符,不過(guò)通過(guò)之前記錄下來(lái)的方法完全可以利用。
Payload:
即使你的xss平臺(tái)URL很長(zhǎng),也可以通過(guò)利用短域名壓縮的方式達(dá)到一個(gè)較低的水平。
0×04 總結(jié)
新手在找XSS的時(shí)候總是存在一些盲點(diǎn),無(wú)法全面的獲取用戶輸入位以及該點(diǎn)的輸出頁(yè)面,對(duì)于存儲(chǔ)型XSS來(lái)說(shuō),輸出的頁(yè)面不局限于當(dāng)前頁(yè)面。
探查程序的代碼邏輯是繞過(guò)的根本,fuzz雖然提高了效率,但是想要準(zhǔn)確的發(fā)現(xiàn)問題必須有要針對(duì)性的構(gòu)造語(yǔ)句。
另外一些領(lǐng)悟可以移駕gainover所寫的一篇短文:
http://zone.wooyun.org/content/1557
0×05 后話
最后一次繞過(guò)是在5.12,不知道之后該站程序員會(huì)怎么樣去處理這個(gè)問題。