Cyber Security - XSS Game
接續前篇 Cyber Security - XSS,XSS Game 是一個可被 XSS 攻擊的靶機
XSS Game
網址:https://xss-game.appspot.com/
XSS Game Intro
- XSS Game 的規則就是要噴出 alert() 就算通關了
- 一般來說,如果我們今天實際在打一個網站,或是其他 CTF 的時候,
- 我們會藉由看 source code,來看看這個網站有沒有過濾甚麼字元
- 而噴 alert 的話,通常會用 alert(1),因為最快也最方便,一但有跳出警告視窗就代表這裡可以被 XSS
- 有些關會有 Target code 和 Hints 可以做參考
WARNING
本篇文章有大量暴雷內容,若想自己體驗解題樂趣,請不要往下看!!!
Level - 1 Hello, world of XSS
Intro
- 題目敘述講到,這個 level 演示了跨站點腳本的常見原因,其中用戶輸入直接包含在頁面中但沒有經過適當的轉義
- 那大家可以試試利用下面這個感覺很容易受攻擊的輸入框,並找到一種方法使其執行 JavaScript
你今天要在 html 裡面執行 js 你會怎麼寫?
Hint
- 這個網站提供的 Hint 裡有提到,你可以去偷看他的 Target code
- 你寫 tag 會發生甚麼
- 那最後一個就是直接提示你要寫
<script>
去包 alert
Solution
1 | <script>alert(1)</script> |
- 那我們這邊這題的 payload 很簡單,就是這樣的一個
alert(1)
而已 - 那我們外層用
<script>
的標籤把他包起來,那這樣他就會噴出 alert,這題就解決了
Level - 2 Persistence is key
Intro
- onerror、onclick
- onerror 是無法載入連結時會執行的 JS 指令,他可以用來判斷圖片是否存在,也可以是代表當你圖片不存時,判斷使用預設圖
- onclick,是當你點擊你所指定的元素時判斷 event
Hint
- 那這個網站他所提供的 Hint 有提到,我們的這些 post 內可以包含 html 的模板
- 我們這次不能再用
<script>
tag 了,但是我們可以用其他 JavaScript 的元素屬性取代 - 然後第三點幾乎說出來了,我們這層跟 i、m、g 有關,而且也會跟 onerror 的屬性有關
Solution
- 我們可以發現這邊最下面是個網頁留言板
- 那我們這邊直觀的想到 html 是有標籤是可以加入圖片的,但我們這邊又沒有要讓圖片正常顯示的意思
- 所以我們可以在 src 的地方隨便寫,後面再寫個我們剛剛教的 onerror,而 onerror 的執行動作再寫個網站所要求的 alert(1)
- 那他的原理是今天你的圖片因為 src 是亂給的,那你就不會跑出圖片,那就會接著執行你的 onerror,然後 alert 就會隨之被噴出來了
1
<img src='NOPE' onerror='alert(1)'>
- 這題也有另解,可以利用剛 onclick 來寫
- 那他的 payload 也跟 onerror 差不多
1
<img src="xxx" onclick="alert(1)" />
- 原理跟 onerror 差不多,也是因為前面 src 死掉,後面 onclick 點下去以後也是直接噴 alert
Level - 3 That sinking feeling…
Intro
- 一些常見的 JavaScript function 是執行接收器,這代表著它們將導致瀏覽器執行出現在其輸入中的任何腳本
- 這一事實被更高級別的 API 隱藏,也就是在後台使用的功能之一
Hint
- 那我們再來看看 Hint,要定位錯誤的原因,可以看 JavaScript 然後依看它在哪裡去處理用戶所提供的輸入
- window.location 的對像數據可能會受到攻擊者的影響
- 你現在確定了注入點,可以想想你需要做什麼才能弄入一個新的 HTML 元素
- 最後這裡提到,和以前一樣,使用
<script>
不會起作用,因為瀏覽器不會執行頁面加載後添加的腳本
Solution
- 可以觀察到網址後方 `frame# 後面數字 (1 ~ 3) 決定的是頁面顯示圖片
- 那我們這裡一樣建議搭配
<img onerror = ''>
,讓他讀取一個不存在的圖片並加入 onerror 屬性 - 直接在後面加上 onerror 的屬性判別式就好
- 我直接示範一下 payload
1
https://xss-game.appspot.com/level3/frame#4.jpg' onerror = 'alert()'>//
- 那這邊解釋一下
4.jpg
: 指向不存在的東西onerror = 'alert()'>
: 加入 onerror 彈出 alert() 並關閉<img>
標籤- 這邊需要注意一下這裡在 4.jpg 後面有個
'
他是代表我們現在要把前面的語句關掉,那這個很重要 - 最後的 // : 把剩下不完整、關不起來的 JavaScript 整個註解掉
Level - 4 Context matters
Intro
- 用戶提供的每一位數據都必須針對將出現的頁面的上下文進行正確轉義
- 那因為這一題需要的觀念比較多,我直接先講解一點點的觀念
Hint
- 看一下 startTimer 函數是怎麼調用的
- 當瀏覽器解析標籤屬性時,它們首先對它們的值進行 HTML 解碼
- 嘗試輸入單引號
'
並觀察
講解
- 首先我們來看他的 target code,我們可以看出他這裡有一個 form 的表單,然後 method 是 GET
- 他有一個 buttom 跟他有一個設定的值,而且他的 default 是 3
- 當你點下他的表單之後,他就會跳到 timer.html 這個頁面
- 這邊有個大括號,他也是在 python 裡面會有一個 template 的模板,你可以把參數丟到這個大括號裡面
- 當使用者去對這個 timer 的參數去做更動的時候,他就去看到這個大括號的 template,然後去把值做更改
- 然後去根據使用者的輸入去做更新,看使用者輸入甚麼就去把它填在裡面
- 那這邊的 img 也是一樣,他會 onload 這個叫做 startTimer 的 function,如果你輸入 3 的話他就會把 3 帶進這個單引號裡面
- 那他就會把 3 當作字串傳進這個 function 裡面,那他就會去 startTimer 裡面等個 3 秒
- 等 3 秒回來可以看到這邊有個 message 是說你的 timer 會執行 3 秒
- 那我們現在回到我們的重點,我們要怎麼去 XSS
- 這邊的重點是這個 onload
- 我們可以發現我們的 Timer 沒有做任何過濾,所以我們也一樣有可能可以對程式碼做一樣關起來的行為
Solution
- 在 target code 上的
1
<img src="/static/loading.gif" onload="startTimer('{{ timer }}');" />
- 加上目標 payload(本題解答)
1
3'); alert(1)//');
- 完整會變成
1
<img src="/static/loading.gif" onload="startTimer('3');alert(1)//');" />
- 我們前面是說把 Timer 丟進來,會丟到這邊的大括號裡面
- 因此我們就可以 onload
- 那我們這邊可以利用 payload,像這樣寫的結果可以禮節成
- 我們先輸入 3,分號是這個 function 的結尾,分號會截斷這個 function
- 截斷完之後我們再來 alert,因此他就會去執行 alert 的指令,就可以完成我們這一關想要做的事情
- 那這邊要注意
- 後面要再把他註解掉,因為我們可以看到這邊的 Timer 後面還有東西
- 要記得把我們輸入的字串關起來,因為有可能會有一些垃圾的字串,所以這邊要再做單引號括號分號把他關起來做截斷
- 那我們這邊做到以後,我們輸入 payload,alert 噴出來,這一關順利結束
Level - 5 Breaking protocol
Intro
- 這關考的是跨站點腳本不僅僅是正確地轉義數據
- 有時,即使沒有向 DOM 注入新元素,攻擊者也可以做壞事
- 那因為這題一樣蠻難的,所以也先戴一下講解
Hint
- 這個級別的標題是一個提示,這關的 Title 如各位所見,叫做 Breaking protocol
- 查看註冊框架的來源並了解如何使用 URL 參數很有用
- 如果你想讓點擊一個鏈接執行 Javascript(不使用 onclick 處理程序的話),你會怎麼做?
- 如果你真的卡住了,可以看看這個 IETF 草案
講解
- 我們現在一樣來看 target code
- 一開始我們先看這份 confirm.html
- 我們可以看到他這邊如果按 signup 以後就會來到 signup.html 這個頁面
- 我們會發現這個 next 會去 confirm
- 那如果我們隨便輸入,他就會跟我們說謝謝我們的輸入
- 那很明顯這裡就可以動手腳
- 那這個 href 一般來說都是放連結,看你要連去哪裡,或是連到 local 的資源或文字檔
- 那我們這邊也可以插 JavaScript,所以我們現在的問題是要怎麼把 JavaScript 的參數塞到 next 裡面
- 我們原本 next 是要執行 confirm 裡的 function,但我們現在不想要他執行 confirm 裡的 function,我想要他執行 alert
- 那我們要怎麼在 href 裡面執行 JavaScript?
Solution
- 這題的關鍵在於要怎麼在 href 裡面執行 JavaScript
1
javascript:alert(1)
- 他就是把
:
後面的東西用 javascript 執行, - 那我們要先送出第一次的 request,這樣他在第一次的送出之後才會去渲染你的前端頁面
- 而在那之後你的 default 也才會有這個 script 在裡面
- 像我們這邊可以在網址列裡的 next 後面寫上
javascript:alert(1)
並且按下 go 一次 - 然後其實這個 next 的 href 後面就會被換成 javascript : alert(1),在那個頁面裡面
- 那接下來你就可以隨便輸入了
- 隨便輸入以後按 next,他就會去執行這個 href 裡面的 javascript
- alert 就會噴出來了
- 這提到此結束,那解法很多,只要能夠達到正確的結果的都是好解法
Level - 6 Follow the Rabbit
Intro
- 複雜的 Web 應用程序有時能夠動態的 load JavaScript libraries,是根據其 URL 參數的值或 location.hash 的一部分
- 要正確處理這一點非常棘手,因為在加載腳本或其他潛在危險類型的數據(如 XMLHttpRequest)時,允許用戶輸入影響 URL 通常會導致嚴重的漏洞
- 這題也蠻難的,所以我們這邊一樣先帶一點講解
Hint
- 我們可以查看位置片段的值(# 之後)如何影響加載腳本的 URL
- 那麼對於小工具,URL 的安全檢查真的萬無一失嗎?
- 有時候,當我感到沮喪時,我想尖叫… 這個好真實
- 如果您不能輕鬆地託管自己的惡意 JavaScript 文件,我們可以查看 google.com/jsapi?callback=foo 是否有所幫助
講解
- 那我們現在來看一下 code,我們可以看到 URL 後面有個井號,那這代表說他會去引入井號之後的 JS
- 接著他引入完這個 JS 之後就會在這個頁面做執行
- 那我們發現了這個洞,就會想要去引入外部的 JS 進來
- 但我們在第 21 行會發現,他有去比對我們的 http、https
- 所以如果我們去引入了一個外部連結,那這邊說他會去擋 http、https,所以我們可能要用其他的手法繞過
- 那我們現在有幾個思路
- 在井號後面的 JS 會被 include
- 所以我們要想辦法生一個 alert 的 JS,讓他從外部引入
- 那這邊要注意的就是前面說的,他會擋 http 和 https
- 但其實我們可以用大小寫去繞過他
- 那另外,因為有提到說我們要從外部去引入寫 JS 的連結,那要用甚麼工具,根據提示我們可以發現 google 就有這樣的文件
Solution
- 我們從最後的井號之後開始去編寫我們要引入的外部 JS
- 那我們這邊可以利用剛剛 Hint 提到的 google JS 的 API
- 那他的用法其實就是改提示的東西,提示長這樣
1
google.com/jsapi?callback=foo
- 那我們把他魔改成這樣,後面加上 alert,因為我們的目的是要噴 alert
- 但是這樣還不夠,前面也要補上 https,但不只要補上 https,還要改他的大小寫
- 因為我們剛剛有發現,target code 有說他會檔小寫的 http 和 https
- 所以我們這邊就故意用大寫去繞過他,像是寫 hTTp,h 大踢大踢 p 之類的去繞過他
1
hTTps://www.google.com/jsapi?callback=alert
- 完整的 code
1
https://xss-game.appspot.com/level6/frame#hTTps://www.google.com/jsapi?callback=alert
- 那最後會看到 alert 噴出來,這題也順利結束!
Congratulations
- 那我們成功順利地打完 XSS Game 的六關了!
- 並且收穫了一個大蛋糕,
其實我第一眼看他以為他是在對我比中指 - 那下面有你可以回應他說你覺得喜不喜歡、難度如何的小按鈕,給作者一點回饋