Part1 技術(shù)研究過(guò)程
這個(gè)案例是源于之前測(cè)過(guò)的一個(gè)有獎(jiǎng)活動(dòng)介紹的Web頁(yè)面,整個(gè)子域名只有兩個(gè)html靜態(tài)頁(yè)面,通過(guò)burpsuite抓包發(fā)現(xiàn)沒(méi)有任何動(dòng)態(tài)交互,因而漏洞挖掘的難度非常大。查看當(dāng)前html頁(yè)面源碼,分析了一下JS代碼,發(fā)現(xiàn)了memberId的傳值會(huì)在當(dāng)前頁(yè)面回顯,也就意味著存在XSS漏洞的可能性,但是需要閉合雙引號(hào)。輸入測(cè)試payload 402881111”; window.open(); //,發(fā)現(xiàn)當(dāng)前頁(yè)面對(duì)XSS進(jìn)行了防范,會(huì)對(duì)雙引號(hào)進(jìn)行轉(zhuǎn)義而變成如下形式:var memberId=”402881111\”; window.open(); //”,導(dǎo)致XSS代碼無(wú)法正常運(yùn)行。經(jīng)過(guò)測(cè)試發(fā)現(xiàn)這個(gè)頁(yè)面的編碼為GBK,由此想到了使用寬字節(jié)的方法吃掉\轉(zhuǎn)義字符,從而使雙引號(hào)繼續(xù)運(yùn)行。于是提交如下URL:index.html?memberId=1111%81%22;window.open();//&id=112233?由于當(dāng)前頁(yè)面編號(hào)為GBK,%81與后面的 \ 被解析成一個(gè)字符變成%81%5C%22,經(jīng)過(guò)GBK編碼后造成 \ 被吃掉,也就是 %81%5C 變成一個(gè)亂碼字符,從而使獨(dú)立的雙引號(hào)保留下來(lái)造成XSS漏洞。如下圖所示,表明轉(zhuǎn)義字符被吃掉,window.open();// 會(huì)被執(zhí)行。
利用unicode編碼觸發(fā)隱式DOM-XSS
對(duì)于innerHTML內(nèi)容可以自定義的情況,也可以傳入U(xiǎn)nicode編碼的XSS測(cè)試語(yǔ)句,繞過(guò)各種過(guò)濾與攔截。
提交如下Unicode編碼+URL編碼后的XSS測(cè)試語(yǔ)句:
userID=%5Cu003c%5Cu002f%5Cu0066%5Cu006f%5Cu0072%5Cu006d%5Cu003e%5Cu003c%5Cu002f%5Cu0073%5Cu0070%5Cu0061%5Cu006e%5Cu003e%5Cu0064%5Cu0064%5Cu0064%5Cu0064%5Cu0064%5Cu0064%5Cu0064%5Cu003c%5Cu002f%5Cu0073%5Cu0070%5Cu0061%5Cu006e%5Cu003e%5Cu003c%5Cu0069%5Cu006d%5Cu0067%5Cu0020%5Cu0073%5Cu0072%5Cu0063%5Cu003d%5Cu0030%5Cu0020%5Cu006f%5Cu006e%5Cu0065%5Cu0072%5Cu0072%5Cu006f%5Cu0072%5Cu003d%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074%5Cu0028%5Cu0031%5Cu0031%5Cu0031%5Cu0031%5Cu0031%5Cu0029%5Cu003e&hciPasswordTypeEOSOperator%2Fpassword
對(duì)于一個(gè)URL,#后面的部分是片段標(biāo)識(shí)符,通常用于頁(yè)面內(nèi)導(dǎo)航或者作為附加參數(shù),不會(huì)直接發(fā)送給服務(wù)器,但在某些情況下會(huì)被客戶端腳本讀取和處理。如果目標(biāo)頁(yè)面未正確處理或過(guò)濾片段標(biāo)識(shí)符中的內(nèi)容,可能會(huì)將這段HTML片段直接插入到DOM中,從而執(zhí)行嵌入的JavaScript代碼。攻擊者可以利用這種方法在受害者的瀏覽器中執(zhí)行任意JavaScript代碼,導(dǎo)致信息泄露、會(huì)話劫持、頁(yè)面篡改等安全問(wèn)題。由于#號(hào)后面的語(yǔ)句不經(jīng)過(guò)服務(wù)端,因而此類型的DOM-XSS可以繞過(guò)一切的WAF攔截。測(cè)試語(yǔ)句:http://www.xxx.com/voiceSysWeb/error.html?errorInfo=00000#%3c%69%6d%67%20%73%72%63%3d%31%20%6f%6e%65%72%72%6f%72%3d%61%6c%65%72%74%28%31%31%31%31%31%31%31%29%3eself.location.href會(huì)接受瀏覽器完整的URL值,包括#后面的字符串。而%3c%69%6d%67%20%73%72%63%3d%31%20%6f%6e%65%72%72%6f%72%3d%61%6c%65%72%74%28%31%31%31%31%31%31%31%29%3e會(huì)被str.substring(n + 1, str.length)處理,進(jìn)而被decodeURIComponent方法URL編碼解碼,變成<img src=1 onerror=alert(1111111)>,然后被Jquery組件的html解析執(zhí)行。
遇到返回body體中的script標(biāo)簽內(nèi)部的js代碼,有字符串拼接相加的情況,可以試試使用setTimeout方法來(lái)觸發(fā)XSS彈窗。測(cè)試語(yǔ)句:http://www.xxx.com/searchAll/searchByKeyWord.htm?keyWord=ddddd"+setTimeout(String.fromCharCode(97,108,101,114,116,40,49,49,49,41),0)+"String.fromCharCode方法用于將ASCII碼轉(zhuǎn)為字符串,97,108,101,114,116,40,49,49,49,41的ASCII碼是alert(111),setTimeout在0毫秒后執(zhí)行一個(gè)alert彈窗。
這個(gè)web應(yīng)用的XSS漏洞存在的位置,限制了XSS payload的長(zhǎng)度,但是經(jīng)過(guò)測(cè)試,可以使用分段提交的辦法繞過(guò)長(zhǎng)度限制,用注釋符拼接的方式,注釋掉不同payload之間拼接過(guò)程中產(chǎn)生的額外字符。以下是很早之前的一個(gè)實(shí)戰(zhàn)案例。以下是我的實(shí)戰(zhàn)版本,用/*xxx*/的注釋不可行,但是可以使用//的注釋方式,最終仍然可以造成彈窗效果。
以下這個(gè)業(yè)務(wù)系統(tǒng)對(duì)XSS進(jìn)行了一定的防范,對(duì)on事件進(jìn)行了黑名單過(guò)濾。經(jīng)過(guò)測(cè)試發(fā)現(xiàn)ondragstart沒(méi)有在黑名單之內(nèi),是可以使用的;然后這個(gè)Web應(yīng)用還對(duì)<>進(jìn)行HTML實(shí)體編碼,導(dǎo)致一切XSS漏洞均失效。但是我們通過(guò)另外的界面,通過(guò)搜索關(guān)鍵字查找我們剛剛提交的條目,發(fā)現(xiàn)了一個(gè)裂開(kāi)的圖片,這說(shuō)明重新調(diào)用過(guò)程中,該應(yīng)用又對(duì)其進(jìn)行了HTML解碼,導(dǎo)致繼續(xù)產(chǎn)生XSS漏洞。當(dāng)鼠標(biāo)滑過(guò)裂開(kāi)的圖片時(shí),XSS彈窗代碼被執(zhí)行。
Part2 總結(jié)
1. 對(duì)用戶提交的數(shù)據(jù)進(jìn)行HTML編碼以及各種關(guān)鍵字過(guò)濾,并慎用HTML解碼,防止二次XSS的情況發(fā)生。2. 以#號(hào)開(kāi)頭的隱式DOM-XSS攻擊語(yǔ)句不會(huì)經(jīng)過(guò)服務(wù)端處理,因而所有的WAF均無(wú)法攔截。3. XSS漏洞的深入挖掘及利用,需要Javascript功底,因此,學(xué)好Javascript是重中之重。
該文章在 2024/10/31 10:08:58 編輯過(guò)