0x01-XSS基礎實戰-XSSGame 6集全

目錄

這是什麼?

XSS 系列開篇。WebApp 滲透測試是一個大話題,之前的 SQL 系列之後還會繼續深入。本篇的 XSS 系列也一樣,在後續的工作學習中,不斷記錄。

我不再講 XSS 的基本原理,網上有太多的教程。

最權威的學習資料,列舉在下面:

OWASP,Rapid7,Protswigger(Burp Suite)三大家。

另外,W3School 是必備的學習資料

如果對於 XSS 的基本概念不太熟悉,建議先閱讀這三篇文章,再繼續下面的內容。

今日目標

今天,我們一起把 XSS Game 這個有 6 個等級的 XSS 實戰小教程做完。理論結合實踐,是最快的學習方式。

所有的 6 個等級,都要求我們使用 XSS 讓瀏覽器彈出一個 alert,即可過關。

在開始之前,先推薦兩個個 JSBin HTML JS 線上測試工具JSFiddle。在學習的過程中,如果有代碼需要測試,可以很方便地在兩個工具上運行。

例如你知道了一個輸入框中的用戶輸入會被直接嵌入到 <strong></strong> 標籤中,你想確認在 <strong> 標籤中,<script> 是否能被成功執行。那就可以到 JSBin 做個小測試。

在這裏插入圖片描述

另外,HTML URL Online Encoder Decoder 也是非常有用的工具,可以將需要在地址欄注入的腳本做 url encode。

最後再推薦兩個 XSS Payload Cheet Sheet,OWASP XSS Cheet SheetXSS Cheet Sheet From Github

Level 1

Level 1 的頁面是這樣的。

在這裏插入圖片描述

XSS Game 模擬了一個瀏覽器在頁面中央。頁面底部的 toggle,點擊可以查看頁面的源代碼。

在這裏插入圖片描述

點擊 show,可以顯示提示信息。

在這裏插入圖片描述

Level 1,展示了最基本的反射型 XSS 攻擊。這裏,有兩種方式可以判斷開發者有沒有對用戶輸入做校驗。

第一種方式,看源碼。

在這裏插入圖片描述

可以看到,沒有任何的用戶輸入校驗。後端代碼從 request 中獲取 query 參數,然後直接拼接到 html <b> tag 中間。

另一種方法,輸入測試。

對於網頁應用來說,最最敏感的字符,就是兩個尖括號,<>。所以我們可以直接輸入一個 <test 測試以下是否有過濾機制。

在這裏插入圖片描述

有點奇怪的結果,但是我覺得這是瀏覽器的行爲,跟環境沒有關係。我的瀏覽器也是 Chrome,可以做個小測試。

我寫了一個簡單的 html 頁面。

頁面模擬了Level 1 的情況,在 <b> 標籤中間,加上了 <test 作爲用戶輸入。

在這裏插入圖片描述

我們啓動一個 http server。

在這裏插入圖片描述

我在 Windows WSL 下運行的 Ubuntu,它的 IP 是 192.168.1.108。用瀏覽其訪問該測試頁面。

可以看到一樣的情況。

在這裏插入圖片描述

換成其他標籤也一樣。

在這裏插入圖片描述

無論怎麼說,可以肯定的是,後端沒有做用戶輸入的校驗,導致我們可以直接使用 <script> 注入 javascript。

因此,在搜索框中輸入:

<script>alert(1);</script>

或者在 url 中(?query=)輸入:

# html url encode
%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E

即可。

在這裏插入圖片描述

Level 2

Level 2 是典型的持久型 XSS。

同樣的步驟,我們看一下源碼。

存儲評論的時候,沒有做任何輸入校驗,直接將用戶輸入存儲到數據庫。

在這裏插入圖片描述

顯示評論的時候,同樣沒有做用戶輸入的校驗處理,直接將用戶輸入拼接到 DOM。

在這裏插入圖片描述

根據前一 Level 的經驗,我們也輸入一個 <script>alert(1);</script> 就可以了。但是這裏不行。

innerHTML

innerHTML 可以設置 DOM 樹中的節點的內容。

var ele = document.getElementById('id');

ele.innerHTML = 'this is not an attack';

innerHTML的安全問題

innerHTML 將字符串解析爲 HTML,意思是,如果字符串中有腳本,瀏覽器就有可能會執行。

爲什麼 <script> 在 innerHTML 中無法執行,我們看一下文檔。

根據 Mozilla 官方的文檔,規定 <script> 在 innerHTML 中是無法執行的,僅此而已。

在這裏插入圖片描述

同一篇文檔中,Mozilla 也給出了我們需要的答案,我們仍舊可以使用 事件(Event) 來觸發 javascript 腳本。

在這裏插入圖片描述

Event

Event,也稱 DOM Event,用來通知開發者一些特定的操作或者事件被觸發了。比如,onmouseover 事件會在鼠標移入的時候被觸發,onload 事件會在頁面或者節點被加載的時候被觸發,即將使用的 onerror 在有錯誤發生的時候被觸發。

Mozilla 官方的文檔十分詳細

事件被添加到節點上之後,根據事件性質的不同,會在不同的情況下被觸發。

如 Mozilla 官方文檔所說,在 Level 2 的情況下,我們只需要使用一個事件,就可以觸發 alert 彈窗。

在評論區輸入:

<img src=# onerror="javascript:alert(1);" />

# 或者
<img src=# onerror="alert(1);" />

# 或者,連分號都不用
<img src=# onerror="alert(1)" />

持久型的 XSS 意味着每當你訪問這個頁面,彈窗都會執行。可以嘗試刷新以下頁面,彈窗會再次出現。

Level 3

看源碼找漏洞。

location.hash

圖片來自 Mozilla Location 官方文檔

在這裏插入圖片描述

這個 hash 大家都見到過,它就像一個麪包屑一樣,指出你正在閱讀的當前頁面上的那一部分內容。

比如大家到我的個人博客,閱讀 從頭開始寫操作系統-啓動扇區與內存的關係及內存尋址的應用 一文,你隨便點一個目錄,就會在 URL 後面看到一個 hash。

在這裏插入圖片描述

hash 是 Location 對象的一個屬性,代表的,就是上圖例子中的 #boosecbyte 部分。

我們結合 Level 3 的源碼看一下。

Level 3 中,chooseTab 方法接收 location.hash.substr(1) 作爲參數,也就是上 #exampleexample 的部分。

在這裏插入圖片描述

之後,這個 example ,被直接拼接到了 html 中,然後 jQuery 將 html 設置給 tabContent 節點來展示。

在這裏插入圖片描述

沒有看到任何用戶輸入的校驗。

我首先嚐試了以下直接使用 <script> 進行注入,但是沒有效果,說明還是要用事件來做。

有了 Level 2 的經驗,我們只需要構造一個一樣的 <img> tag,在錯誤發生的時候,執行彈窗即可。

在 URL 的 # 之後輸入

whatever.jpg' onerror='alert(1)'/>

即可。

Level 4

看源碼。

後端在獲取 timer 參數的時候,沒有做任何字符校驗,獲取之後,直接傳遞給 timer.html 渲染。

在這裏插入圖片描述

timer.html 中,onload 事件觸發後直接將後端獲取的 timer 參數的值傳遞給 startTimer() 方法,作爲參數。

在這裏插入圖片描述

onload 事件,會在圖片加載完成的時候調用。所以,可以在 onload 事件中,構造一個 XSS 注入。

我們需要做的是構造一個輸入,補全 startTimer(' 部分,然後注入 XSS 代碼,例如 οnlοad=“startTimer(‘3’); alert('1’);”

黑體加粗的部分就是我們需要構造的輸入。

在輸入框輸入

3'); alert('1

# 或者
3')+alert('1

或者用上面的 HTML URL Encoder Decoder 工具,編碼之後,在地址欄輸入

?timer=3%27%29%3B+alert%28%271

# 或者
?timer=3%27%29%2Balert%28%271

即可。

Level 5

我們點擊 sign up 跳轉到註冊頁面。

看源碼,註冊頁面選的時候,直接使用後端獲取的 next 參數,沒有任何字符校驗和過濾。

在這裏插入圖片描述

我們輸入了 email,點擊 Next >> 的時候,實際上是點了一個 <a> 鏈接,href 屬性是上圖中獲取的 next 參數的值。

在這裏插入圖片描述

因此,直接在瀏覽器地址欄輸入

javascript:alert(1);

在這裏插入圖片描述

點擊 Next >> 即可。

Level 6

最後 Level 6,還是對 location.hash 進行利用。

跟 Level 3 類似,在 getGadgetName 方法中,獲取 # 之後的部分,如果沒有用戶輸入,默認爲 /static/gadget.js

在這裏插入圖片描述

接着,獲取到的內容傳遞給 includeGadget() 方法最爲參數。

在這裏插入圖片描述

includeGadget() 方法中,首先創建了一個 script DOM 節點,接着,上一步獲取的 # 之後的的部分,作爲 script 節點的 src 屬性。

在這裏插入圖片描述

最後,這個 script 節點被添加爲 head 的子節點。

在這裏插入圖片描述

以默認情況爲例,創建的 script 節點爲

<script src="/static/gadget.js" />

因此,我們要傳遞一個惡意的 js 文件的路徑,輸入到 URL 上 # 的後面,替換掉 /static/gadget.js 即可。

自己沒有服務器的同學,可以使用 google 的 callback jsapi。

另外,還有一個點需要注意,如果直接輸入地址欄中複製出來的帶有 https 或者 http 的 URL,是會報錯的。

在這裏插入圖片描述

因爲代碼中(見前文第 21行 代碼)對 httphttps 進行了過濾,所以,有兩種解決方案。

  • 不要協議部分
  • 將協議部分全部大寫或者隨意大寫一個字符

Protocol-relative URLs

在 html 中使用 URL 可以不需要協議名的部分。例如,<a href="https://www.google.com" />,可以寫成 <a href="//www.google.com" />。根據 wiki 所述,這樣的使用方式叫 Protocol-relative URLs,對目標地址的訪問會使用當前頁面的協議。

在這裏插入圖片描述

因此,在地址欄輸入

//www.google.com/jsapi?callback=alert

# 或者
httpS://www.google.com/jsapi?callback=alert

即可。

Data URLs

還有另外一種方式,使用 Data URLs

Data URLs 是一種協議,可以讓開發者在文檔中嵌入文件。

Data URLs 由 4 部分組成:

  • data:,前綴
  • mediatype,數據類型
  • base64 token,非必要,用於嵌入 base64 編碼的二進制
  • data,數據本身

詳情見 MDN

我先在我本機上做了測試,XSS 腳本不只是在 head 節點中可用,添加到任意節點中均可執行。

在這裏插入圖片描述

在這裏插入圖片描述

所以,在地址欄輸入

data:text/plain;charset=utf-8,alert%281%29

同樣可以彈窗。

總結

  • 最基本的 XSS 漏洞,可直接使用 <script>code</script>
  • <script> 無法執行的時候,可以選擇使用事件來觸發 XSS 腳本
  • location.hash 等頁面地址相關的操作如果使用不當,也會造成 XSS 漏洞
  • Protocol-relative URLs 允許我們省略協議名,使用當前頁面的協議訪問目標地址
  • Data URLs 允許我們在 DOM 中嵌入並執行 XSS 腳本
  • 所有的 XSS 漏洞,都是由於沒有對用戶輸入做校驗和篩選造成的;所以,XSS 防禦的第一步,就是對所有的用戶輸入進行校驗,過濾


推薦閱讀(參考鏈接):

  • https://owasp.org/www-community/attacks/xss/#:~:text=Overview,to%20a%20different%20end%20user.
  • https://www.rapid7.com/fundamentals/cross-site-scripting/
  • https://portswigger.net/web-security/cross-site-scripting
  • https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
  • https://www.tutorialspoint.com/javascript/javascript_events.htm#:~:text=JavaScript’s%20interaction%20with%20HTML%20is,%2C%20resizing%20a%20window%2C%20etc.
  • https://jsbin.com/?html,output
  • https://jsfiddle.net/
  • https://www.url-encode-decode.com/
  • https://www.w3schools.com/js/js_events.asp
  • https://developer.mozilla.org/en-US/docs/Web/Events
  • https://www.w3schools.com/tags/ev_onclick.asp
  • https://stackoverflow.com/questions/7761149/dynamically-added-script-will-not-execute
  • https://developer.mozilla.org/en-US/docs/Web/API/Location
  • https://www.w3schools.com/jsref/event_onload.asp
  • https://github.com/rorymurphyza/GoogleXSSGame
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
  • https://github.com/payloadbox/xss-payload-list
  • https://owasp.org/www-community/xss-filter-evasion-cheatsheet
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章