前言
六月份的挑戰沒解出來,這篇透過兩篇公開的 writeup 來學習一下其他人的做法,順便檢討一下自己哪邊可以再加強。
談到 XSS(Cross-site scripting),許多人可能都只想到「就是網站上被攻擊者植入程式碼」,但若是仔細去想的話,會發現這之中其實還有很多環節都可以再深入探討。
而我所謂的這些「環節」,也可以理解成不同的「關卡」。
舉例來說,第一關當然就是盡可能防止自己的網站被 XSS 攻擊,不要讓攻擊者在網站中能夠植入程式碼。而「讓攻擊者在網站中植入程式碼」這件事,又可以往下再細分成不同地方的植入,例如說 HTML 的植入,或者是 HTML 元素屬性中的植入,又或是 JavaScript 程式碼中的植入,這些都有著不同的攻擊以及防禦方式。
而除了防止被植入程式碼以外,防守方應該還要進一步去想:「那如果真的不幸被植入程式碼了,可以怎麼辦?」
這就是第二個關卡。雖然說第一關我們已經盡可能做好準備了,但難保不會有漏洞產生,因此守好第一關是不夠的,也要對第二關進行防守。
假設今天攻擊者真的找到一個地方植入程式碼,那我們是不是可以想辦法阻止它執行?這就是 CSP(Content Security Policy)出場的時候了,藉由設定一些規則讓不合法的程式碼無法執行。例如說可以讓 inline 的 JavaScript 無法執行,那 <img src=x onerror=alert(1)>
就會變得無效。
若是攻擊者真的很厲害,連 CSP 的規則都繞過了呢?這時就進入到第三關了,第三關的假設是攻擊者已經能夠在網站上執行任意程式碼。
這時候還可以防守什麼呢?那就是試圖把損害控制到最低。
以 Medium 這種部落格的平台來說,若是可以利用 XSS 把別人的帳號奪走(account takevoer),就是個嚴重的漏洞;或是因為 Medium 有付費牆的功能,因此若是能透過 XSS 把錢轉到攻擊者的帳號,也會是一個很嚴重的問題。
而我們要在「網站已經被 XSS」的前提下,試圖去防禦這些攻擊。
接著,就讓我們來看看不同的關卡有哪些不同的防禦方法。
Intigriti 是國外的一個 bug bounty 平台,每個月都會推出一個 XSS 挑戰,有大約一到兩週的時間可以去思考,目標是在特定網站上面執行 alert(document.domain)
,解出來之後把結果透過 Intigriti 平台回報,最後會隨機抽 3 個解掉的人得到他們自己商店的優惠券。
上個月的挑戰因為解出來的人不多,所以我有幸運抽到 50 歐元的優惠券,其實很划算,因為商店賣的東西其實都滿便宜的,我買了一件 t-shirt + 兩頂帽子再加國際運費,大概 45 歐元左右。
不過這種獎品就是靠運氣啦,還是解題好玩比較重要。
有天我在網路上閒晃的時候,看到了一個 XSS challenge:Intigriti’s 0421 XSS challenge - by @terjanq,除了這個挑戰本身很吸引我之外,更吸引我的是出題的作者。
之前在網路上找到的許多比較偏前端的資安相關資源,都是由這個作者在維護或是貢獻的,例如說 Tiny XSS Payloads 或者是令人大開眼界的 XS-Leaks Wiki。
Intigriti 這個網站似乎每個月都會舉辦這種 XSS challenge,而這一次的是他們有史以來舉辦過最難的一個。挑戰時間從 4/19~4/25,有一週的時間可以嘗試,最後成功解出的有 15 人。三月份的挑戰有 45 人解開,二月份有 33 人,所以這一次解出的人數確實少了許多,可想而知題目的難度。
我大概花了五天的時間,每天卡關的時候都想說「放棄好了,坐等解答」,但卻又時不時會有一些新的想法出現,想說就繼續試一下,最後終於在截止的那一天於時限前解開,解開的時候雙手握拳然後手肘往後,大喊:「太神辣」。
這篇想來記錄一下解題的心得,之前有寫了英文版的但大概比小學生作文還不如,還是寫個中文版的比較能完整表達自己的想法。標題會有個「上」是因為這篇寫我的解法,下一篇想來寫作者的解法,下下篇分析其他人的解法。
但我的部落格似乎被下了還沒寫好的系列文都會斷連載的詛咒,希望這次可以撐過去。
如果你不知道什麼是 XSS(Cross-site Scripting),簡單來說就是駭客可以在你的網站上面執行 JavaScript 的程式碼。既然可以執行,那就有可能可以把使用者的 token 偷走,假造使用者的身份登入,就算偷不走 token,也可以竄改頁面內容,或是把使用者導到釣魚網站等等。
要防止 XSS,就必須阻止駭客在網站上面執行程式碼,而防禦的方式有很多,例如說可以透過 CSP(Content-Security-Policy)這個 HTTP response header 防止 inline script 的執行或是限制可以載入 script 的 domain,也可以用 Trusted Types 防止一些潛在的攻擊以及指定規則,或是使用一些過濾 XSS 的 library,例如說 DOMPurify 以及 js-xss。
但是用了這些就能沒事了嗎?是也不是。
如果使用正確那當然沒有問題,但若是有用可是設定錯誤的話,還是有可能存在 XSS 的漏洞。
前陣子我剛從公司內轉到一個做資安的團隊 Cymetrics,在對一些網站做研究的時候發現了一個現成的案例,因此這篇就以這個現成的案例來說明怎樣叫做錯誤的設定,而這個設定又會帶來什麼樣的影響。