一、靶場描述
這個靶場在搜索查詢的跟蹤功能中,包含一個基于DOM的跨站腳本(DOM-based XSS)漏洞。
該漏洞的產生是因為網站使用了一個名為 document.write
的 JavaScript 函數,這個函數會把數據直接寫入到頁面中。而寫入的數據來源于 location.search
,也就是網站 URL 中問號 (?
) 之后的部分,這部分內容是你可以完全控制的。
衍生一下,標簽<img>是在在網頁中插入圖片的意思,主要屬性包括:
- src:圖片的地址,必填,比如:src="example.jpg"
- alt:圖片無法顯示時的替代文本
- width、height:設置圖片大小
<img src="logo.png" alt="網站LOGO" width="100" height="50">
其中:
<img src=xxx οnerrοr=" ">:當src="xxx" 是不存在或無法加載的資源時,瀏覽器會觸發 onerror 事件,可以利用圖片加載失敗觸發 JavaScript 執行
<img src=xxx οnlοad=" ">:當src="xxx" 是有效且能正常加載的資源時,瀏覽器會觸發 onload 事件,可以利用圖片加載成功觸發 JavaScript 執行
我們訪問/resources/images/tracker.gif可以訪問
所以本靶場可以利用圖片加載成功觸發 JavaScript 執行通關,但是主要使用的是下面三、攻擊思路,這種也是一種辦法。
" onload="alert(1)"
當你的輸入被拼接到原始代碼中后,最終生成的HTML字符串變成了:
<img src="/resources/images/tracker.gif?searchTerms="" onload="alert(1)">
二、漏洞原理詳解
1、基于DOM的跨站腳本 (DOM-based XSS):
這是一種特殊的XSS攻擊。與存儲型和反射型XSS不同,DOM型XSS的攻擊載荷(payload)不一定會發送到服務器。
整個攻擊過程發生在用戶的瀏覽器端。具體來說,是頁面的客戶端JavaScript代碼,在處理數據時不夠安全,導致了漏洞。
在這個靶場中,流程是這樣的:
a. 瀏覽器加載頁面的合法JavaScript代碼。
b. 這段代碼從URL中讀取數據 (通過 location.search)。
c. 代碼沒有對讀取到的數據進行安全處理(過濾或編碼),就直接使用 document.write 將其寫入到頁面的文檔對象模型(DOM)中。
d. 如果URL中包含了惡意腳本,這個腳本就會被寫入頁面并執行。
2、危險函數 (Sink):
document.write
這是一個非常經典的導致DOM-XSS的函數。它會把傳入的字符串當作HTML來解析并插入到文檔流中。如果字符串里包含 <script>
標簽,瀏覽器就會執行它。
3、數據來源 (Source):
location.search這是指URL中從 ?
開始的所有內容(查詢字符串)。例如,在 http://example.com/search?query=apple
這個URL中, location.search
的值就是 ?query=apple
。攻擊者可以隨意構造這個部分。
4、解決目標
要成功完成這個靶場,你需要構造一個特殊的URL。當這個URL被訪問時,它能夠觸發DOM-XSS漏洞,并成功執行 alert
函數(即在瀏覽器中彈出一個警告框)。
三、攻擊思路:
在輸入框隨便輸入字符串,發現我們的輸入被拼接到url,然后函數?document.write()?將從url中獲取的search參數寫入頁面中
這是一段 JavaScript 代碼,它的主要功能是跟蹤用戶在網站上的搜索行為,但它包含一個嚴重的安全漏洞。
1、代碼詳解
<script>// 定義一個名為 trackSearch 的函數,它接收一個參數叫 queryfunction trackSearch(query) {// 使用 document.write 向頁面寫入一段 HTML 代碼document.write(// 這段 HTML 是一個 <img> 圖像標簽// 圖像的源(src)指向一個跟蹤像素(tracker.gif)// 關鍵在于,它把用戶輸入的搜索詞(query)作為參數拼接到了圖像的 URL 后面'<img src="/resources/images/tracker.gif?searchTerms=' + query + '">');}// 從當前頁面的 URL 中獲取名為 'search' 的參數值// 例如,如果 URL 是 https://example.com/?search=1// 那么 query 變量的值就是 '1'var query = (new URLSearchParams(window.location.search)).get('search');// 判斷 query 是否存在 (即 URL 中是否有 'search' 參數)if (query) {// 如果存在,就調用上面定義的 trackSearch 函數,并將獲取到的搜索詞傳進去trackSearch(query);}
</script>
2、功能總結
這段代碼的目的是:
從當前頁面的 URL 地址欄里,尋找一個名為
search
的參數 (例如:.../?search=關鍵詞
)。如果找到了這個參數,就把它的值(也就是用戶搜索的關鍵詞)取出來。
然后,它會動態地在頁面上創建一個看不見的圖像(一個1x1像素的跟蹤GIF)。這個圖像的 URL 地址會把用戶的搜索關鍵詞作為
searchTerms
參數附加上去。當瀏覽器嘗試加載這個圖像時,就會向服務器發送一個請求,服務器通過分析這個請求日志,就能知道用戶剛剛搜索了什么關鍵詞,從而實現搜索行為跟蹤。
3、嚴重的安全問題 (DOM-based XSS)
這段代碼最關鍵的問題在于它使用了 document.write()
函數來處理從URL中獲取的用戶輸入,并且沒有任何安全過濾。
一個攻擊者可以構造一個惡意的 URL,如下所示:
https://[網站地址]/?search="><script>alert('XSS')</script>
當用戶訪問這個 URL 時,代碼的執行流程會變成這樣:
query
變量獲取到的值是:"><script>alert('XSS')</script>
trackSearch
函數被調用,document.write()
執行的內容就變成了:<img src="/resources/images/tracker.gif?searchTerms=""><script>alert('XSS')</script>">
瀏覽器在解析這段 HTML 時,會先閉合
<img>
標簽,然后遇到<script>
標簽,就會立即執行里面的 JavaScript 代碼,導致彈出一個警告框。
結論: 這段代碼實現了一個簡單的搜索跟蹤功能,但由于直接將 URL 參數寫入頁面,導致了嚴重的基于DOM的跨站腳本(DOM-XSS)漏洞,允許攻擊者在網站上執行任意腳本。
你需要將一個惡意的JavaScript載荷(payload)放在URL的查詢字符串中。當頁面上的腳本讀取這個查詢字符串并用 document.write 將其寫入頁面時,你的腳本就會被執行。
一個典型的攻擊URL會類似這樣:
https://......./?search=<script>alert('XSS')</script>
至此,成功通關。