巴哈姆特電玩資訊站 Stored XSS
巴哈姆特電玩資訊站是台灣一個蠻大型的動漫、電玩相關論壇。去年年底的某天,閒來無事在巴哈姆特測試發文功能,意外發現到一個 XSS 漏洞。過了半年到最近才突然想起,這也是我第一次挖到網站漏洞,還不寫個 write-up 作紀念XD
不知道大家是否知道 BB Code?BB Code 是相對於 HTML 的一種極輕量化的標記語言,主要用途是讓網站論壇能夠發布含有圖片、超連結、表格等等的文章,雖然直接允許使用者嵌入 HTML 是最方便的作法,但危險性卻高出許多。後來發展出 BB Code,只允許簡單的語法限制使用者的輸入,再由網站後端將白名單中的 BB Code 轉換成對應的 HTML,以此確保論壇的安全性。
巴哈姆特同樣也使用自定義的 BB Code 來處理文章內容,參考下圖示範超連結與圖片的 BB Code。
其中「[img=url]」會被轉換成「<img src="url">」。突然天外飛來一道靈感,試著把網址改成「https://"」。果不其然地被擋下了,全部被替換成一般的文字。
心中忽然產生一個疑問,巴哈姆特是如何判定這是合法或非法的圖片網址呢?於是就試著改成「[img=https://".JPG]」,但卻發表文章失敗,看來是巴哈送出前還會檢查一次文章內容的合法性。
挖了一下巴哈的 JavaScript 代碼,發現文章送出前,會先將原始碼 (BB Code) 轉換成可視內容 (HTML),再把可視內容轉換回原始碼,過程中因為「[img=https://".JPG]」有不合法字元的關係,轉換失敗而變成空白,文章內容也會被一併清空導致無法送出文章。
這表示只要在轉換的代碼動手腳或是不透過正常的頁面送出,應該就能輕鬆繞過。透過直覺發現到轉換的這件事是由 bahaRte.toolbar.refreshContent 函式所負責,所以直接在瀏覽器的 console 中輸入「bahaRte.toolbar.refreshContent = function(){}」,就能直接發文。
既然雙引號可被嵌入,那就可以輕易寫出各種 Payload,只是測試過程中還發現到,Payload 中不能含有空白的字元,否則一樣不會被轉換成 HTML,要繞過這點倒不是什麼大問題。
[img=https://"onerror="alert(1)"".JPG]
這是我第一次挖到漏洞,不太清楚正確的回報流程,所以我直接透過巴哈姆特的站內信功能回報給哈啦區總管,沒想到隔天早上就被修補了,真是辛苦巴哈姆特的工程師 < ( _ _ ) >
以上就是我的漏洞挖掘初體驗,給各位獻醜了 ( / ・ω・) /