XSS漏洞靶場—(復現)
反射型 XSS 的特點是攻擊者誘導用戶點擊包含惡意腳本的 URL,服務器接收到請求后將惡意腳本反射回響應頁面,瀏覽器執行該腳本從而造成攻擊,惡意腳本不會在服務器端存儲。
Level 1(反射型XSS)
此漏洞主要源于代碼對用戶輸入未進行充分的過濾和轉義處理。在 PHP 代碼里,通過 $_GET["name"]
接收用戶從 URL 傳遞過來的 name
參數,接著直接將該參數輸出到 HTML 頁面中。若攻擊者在 name
參數里注入惡意的 JavaScript 代碼,當頁面加載時,這些惡意代碼就會被瀏覽器執行,進而達成 XSS 攻擊。
通過分析源碼,可在name參數上嘗試用簡單的JS代碼進行XSS攻擊,看到下面代碼執行成功
攻擊示例:
http://127.0.0.1/xss-labs-master/level1.php?name=<script> alert("攻擊成功")</script>
修復建議:
為了防止 XSS 攻擊,需要對用戶輸入進行過濾和轉義處理。在 PHP 中,可以使用 htmlspecialchars
函數將特殊字符轉換為 HTML 實體,從而避免惡意代碼被執行
解釋
htmlspecialchars($str, ENT_QUOTES, 'UTF-8')
:該函數把字符串中的特殊字符(如<
、>
、"
、'
等)轉換為 HTML 實體(如<
、>
、"
、'
等),如此一來,即使攻擊者注入了惡意的 JavaScript 代碼,這些代碼也會以文本形式顯示,而不會被瀏覽器執行。
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{ confirm("完成的不錯!");window.location.href="level2.php?keyword=test";
}
</script>
<title>歡迎來到level1</title>
</head>
<body>
<h1 align=center>歡迎來到level1</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
// 對用戶輸入進行轉義處理
$escapedStr = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
echo "<h2 align=center>歡迎用戶".$escapedStr."</h2>";
?>
<center><img src=level1.png></center>
<?php
// 對用于計算長度的字符串也可以考慮進行必要的驗證
$lengthStr = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
echo "<h3 align=center>payload的長度:".strlen($lengthStr)."</h3>";
?>
</body>
</html>
Level 2(反射型XSS)
雖然代碼在部分輸出時使用了 htmlspecialchars
函數對用戶輸入進行了處理,但在表單輸入框的 value
屬性賦值時,沒有對用戶輸入進行足夠的轉義處理。攻擊者可以通過構造特殊的輸入,繞過這種部分防護,使得惡意的 JavaScript 代碼在頁面中被執行,從而實現 XSS 攻擊。
在上述代碼里,$str
是從 $_GET["keyword"]
獲取的用戶輸入,在 <input>
標簽的 value
屬性中直接使用了 $str
,而沒有進行合適的轉義。
在h2標簽之中的惡意代碼被htmlspecialchars編碼了。其中<、>都被編碼成了html字符實體,惡意代碼被編碼了,只能從屬性值中的惡意代碼處進行突破了,,只需要將屬性的引號和標簽先閉合就可以了。
攻擊示例:
http://127.0.0.1/xss-labs-master/level2.php?keyword="><script>alert('XSS 攻擊成功!')</script><"
修復建議
為了防止這種 XSS 攻擊,需要對表單輸入框 value
屬性中的用戶輸入也進行轉義處理。可以繼續使用 htmlspecialchars
函數。
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{ confirm("完成的不錯!");window.location.href="level3.php?writing=wait";
}
</script>
<title>歡迎來到level2</title>
</head>
<body>
<h1 align=center>歡迎來到level2</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
// 對輸出到 h2 標簽中的內容進行轉義
$escapedStrH2 = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
// 對輸出到 input 標簽 value 屬性中的內容進行轉義
$escapedStrInput = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
echo "<h2 align=center>沒有找到和".$escapedStrH2."相關的結果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$escapedStrInput.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
<center><img src=level2.png></center>
<?php
// 對用于計算長度的字符串也進行必要的驗證
$lengthStr = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
echo "<h3 align=center>payload的長度:".strlen($lengthStr)."</h3>";
?>
</body>
</html>
Level 3(反射型XSS)
嘗試Level 2 的攻擊方法后未能成功
代碼中對 $str
進行了 htmlspecialchars
處理,在大部分情況下能防止常見的 XSS 攻擊。不過,當攻擊者利用 HTML 事件屬性時,仍可能構造出能執行惡意腳本的情況。在 HTML 標簽的屬性中,如果輸入包含事件處理函數(如 onclick
、onload
等),即使使用了 htmlspecialchars
轉義了引號,攻擊者依然可以通過構造合適的輸入繞過部分防護。
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
雖然對 value
屬性的值進行了轉義,但如果攻擊者輸入的是包含事件處理函數的內容,可能會引發 XSS 攻擊
攻擊示例:
http://127.0.0.1/xss-labs-master/level3.php?writing='onmouseover='alert("XSS")
'οnmοuseοver='alert(“XSS”)
onmouseover
:
當用戶將鼠標懸停在輸入框上時,onmouseover
事件觸發,惡意腳本 alert("XSS")
就會被執行
修復建議:
為了更安全地處理用戶輸入,除了使用 htmlspecialchars
對普通字符進行轉義,還需要對可能的 HTML 事件屬性進行過濾和驗證,或者采用更嚴格的白名單機制來允許的字符和屬性。另外,在現代 Web 開發中,可以考慮使用 htmlentities
函數來進行更全面的轉義。
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{ confirm("完成的不錯!");window.location.href="level4.php?keyword=try harder!";
}
</script>
<title>歡迎來到level3</title>
</head>
<body>
<h1 align=center>歡迎來到level3</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
// 更全面的轉義處理
$escapedStr = htmlentities($str, ENT_QUOTES, 'UTF-8');
echo "<h2 align=center>沒有找到和".$escapedStr."相關的結果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".$escapedStr."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
<center><img src=level3.png></center>
<?php
// 對用于計算長度的字符串也進行轉義
$lengthStr = htmlentities($str, ENT_QUOTES, 'UTF-8');
echo "<h3 align=center>payload的長度:".strlen($lengthStr)."</h3>";
?>
</body>
</html>
Level 4 (反射型XSS)
漏洞分析
- 過濾不徹底
代碼嘗試通過 str_replace
函數去除輸入中的 <
和 >
字符,以防止用戶注入 HTML 標簽。然而,攻擊者可以利用 HTML 實體編碼繞過這種過濾。HTML 實體編碼允許將特殊字符用特定的編碼表示,例如 <
可以用 <
表示,>
可以用 >
表示。當頁面輸出時,瀏覽器會將這些實體編碼解析為對應的字符。
- 部分輸出轉義問題
雖然在 <h2>
標簽中使用了 htmlspecialchars
對輸出進行轉義,但在 <input>
標簽的 value
屬性中,使用的是經過 str_replace
處理后的 $str3
,沒有再次進行全面的轉義,這就給攻擊者留下了可乘之機。
攻擊示例:
http://127.0.0.1/xss - labs - master/level4.php?keyword="onfocus=javascript:alert('xss') "
當用戶點擊該 URL 時,瀏覽器會向服務器發送請求,服務器端代碼通過 $_GET["keyword"]
獲取到 keyword
參數的值為 "onfocus=javascript:alert('xss') "
。
原代碼中處理邏輯:
$str = $_GET["keyword"];
$str2 = str_replace(">", "", $str);
$str3 = str_replace("<", "", $str2);
這里代碼只是簡單地去除了 <
和 >
字符,而攻擊者輸入的內容中并沒有直接使用 <
和 >
來包裹腳本,所以這種過濾方式對該惡意輸入無效,$str3
仍然是 "onfocus=javascript:alert('xss') "
。
修復建議:
為了防止此類 XSS 攻擊,需要對用戶輸入進行更嚴格的過濾和轉義處理。可以使用 htmlspecialchars
或 htmlentities
函數對輸出進行全面轉義,確保特殊字符被正確處理
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{ confirm("完成的不錯!");window.location.href="level5.php?keyword=find a way out!";
}
</script>
<title>歡迎來到level4</title>
</head>
<body>
<h1 align=center>歡迎來到level4</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
// 對輸入進行全面的 HTML 實體編碼轉義
$escapedStr = htmlentities($str, ENT_QUOTES, 'UTF-8');
echo "<h2 align=center>沒有找到和".$escapedStr."相關的結果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword value="'.$escapedStr.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
<center><img src=level4.png></center>
<?php
// 對用于計算長度的字符串也進行轉義
$lengthStr = htmlentities($str, ENT_QUOTES, 'UTF-8');
echo "<h3 align=center>payload的長度:".strlen($lengthStr)."</h3>";
?>
</body>
</html>
Level 5(反射型XSS)
在這段代碼中,$str
變量接收用戶輸入的 keyword
參數,經過一系列處理后存儲在 $str3
中,而 $str3
被直接嵌入到 HTML 表單的 input
標簽的 value
屬性中,沒有進行足夠的 HTML 實體轉義,這就為 XSS 攻擊提供了可能。
攻擊原理:
攻擊者通過構造惡意的 keyword
參數,將包含 JavaScript 代碼的字符串注入到頁面中。當頁面加載時,瀏覽器會執行注入的 JavaScript 代碼,從而實現攻擊目的。例如,使用如下 URL:
http://127.0.0.1/xss-labs-master/level5.php?keyword="><a href=javascript:alert("攻擊成功")>"點這"</a>
在這個 URL 中,keyword
參數的值為 "><a href=javascript:alert("攻擊成功")>"點這"</a>
。當頁面加載時,這個惡意代碼會被嵌入到 input
標簽的 value
屬性中,導致瀏覽器執行 alert("攻擊成功")
代碼,顯示一個提示框,表明攻擊成功。
代碼中存在問題的部分:
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
在上述代碼中,$str3
直接被嵌入到 input
標簽的 value
屬性中,沒有進行足夠的 HTML 實體轉義,使得攻擊者可以通過構造惡意的 keyword
參數注入 JavaScript 代碼。
修復建議:
為了防止 XSS 攻擊,需要對用戶輸入的數據進行充分的 HTML 實體轉義。可以使用 htmlspecialchars
函數對 $str3
進行轉義,修改后的代碼如下:
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.htmlspecialchars($str3, ENT_QUOTES, 'UTF-8').'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
在這個修改后的代碼中,htmlspecialchars
函數將 $str3
中的特殊字符(如 <
、>
、"
等)轉換為 HTML 實體,從而避免了 JavaScript 代碼的注入。ENT_QUOTES
參數表示同時轉換單引號和雙引號,'UTF-8'
表示使用 UTF-8 編碼。
Level 6(反射型)
代碼嘗試對一些常見的用于 XSS 攻擊的關鍵詞進行替換,例如將 <script
替換為 <scr_ipt
,將 on
替換為 o_n
等。但這種過濾方式存在嚴重缺陷:
- 大小寫繞過:過濾操作是基于小寫關鍵詞進行的,攻擊者可以使用大小寫混合的方式繞過過濾。例如,在攻擊 payload
"><a hRef=javascript:alert(1)>test</a>
中,使用hRef
而不是href
,就繞過了對href
的替換。 - 不完整過濾:只對部分關鍵詞進行了替換,攻擊者可以利用其他未被過濾的 HTML 屬性和事件來注入惡意腳本。
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
這是漏洞的關鍵所在。雖然對 $str
進行了 htmlspecialchars
處理,但在將 $str6
嵌入到 input
標簽的 value
屬性時,沒有對其進行充分的 HTML 實體轉義。這意味著攻擊者構造的惡意代碼會被直接插入到 HTML 頁面中。
攻擊示例:
http://127.0.0.1/xss-labs-master/level6.php?keyword="><a hRef=javascript:alert(1)>test</a>
當用戶訪問包含惡意 keyword
參數的 URL 時,瀏覽器會解析并執行嵌入在頁面中的惡意腳本。例如,對于 "><a hRef=javascript:alert(1)>test</a>
這個 payload,當頁面加載后,input
標簽的 value
屬性會被提前閉合,后面插入的 <a>
標簽會正常顯示。當用戶點擊這個鏈接時,瀏覽器會執行 javascript:alert(1)
代碼,彈出一個警告框,表明攻擊成功。
Level 7(反射型)
$str2 = str_replace("script", "", $str);
$str3 = str_replace("on", "", $str2);
$str4 = str_replace("src", "", $str3);
$str5 = str_replace("data", "", $str4);
$str6 = str_replace("href", "", $str5);
代碼嘗試對一些常見的用于 XSS 攻擊的關鍵詞進行過濾,將它們替換為空字符串。但這種過濾方式存在明顯缺陷:
- 過濾不全面:只對部分關鍵詞進行了過濾,攻擊者可以使用其他未被過濾的 HTML 屬性和事件來注入惡意腳本。
- 可繞過過濾:攻擊者可以通過一些技巧繞過這些過濾,例如使用大小寫混合、重復關鍵字等方式。比如構造
javascscriptript
繞過對script
的過濾,當過濾操作移除script
后,仍能形成有效的javascript
。
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
這是漏洞的關鍵所在。在將處理后的 $str6
嵌入到 input
標簽的 value
屬性時,沒有對其進行充分的 HTML 實體轉義。這意味著攻擊者構造的惡意代碼會被直接插入到 HTML 頁面中,當瀏覽器解析該頁面時,就會執行惡意腳本。
攻擊示例:
http://127.0.0.1/xss-labs-master/level7.php?keyword="><a hrhrefef=javascscriptript:alert(1)>test</a>
攻擊者構造的 keyword
參數為 "><a hrhrefef=javascscriptript:alert(1)>test</a>
。通過重復關鍵字符(如 hrhrefef
和 javascscriptript
),使得過濾函數在移除 href
和 script
后,依然能保留有效的可執行代碼。經過過濾后,hrhrefef
變成 href
,javascscriptript
變成 javascript
,最終在頁面中形成有效的 <a href="javascript:alert(1)">test</a>
代碼,當用戶點擊鏈接時,就會觸發 alert(1)
彈出警告框。
修復建議:
為了防止 XSS 攻擊,需要對最終輸出到頁面的內容進行充分的 HTML 實體轉義。可以使用 htmlspecialchars
函數對 $str6
進行處理,修改后的代碼如下:
$str = strtolower($_GET["keyword"]);
$str2 = str_replace("script", "", $str);
$str3 = str_replace("on", "", $str2);
$str4 = str_replace("src", "", $str3);
$str5 = str_replace("data", "", $str4);
$str6 = str_replace("href", "", $str5);
$escaped_str6 = htmlspecialchars($str6, ENT_QUOTES, 'UTF-8');
echo "<h2 align=center>沒有找到和".htmlspecialchars($str)."相關的結果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$escaped_str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
通過 htmlspecialchars
函數將特殊字符(如 <
、>
、"
、'
等)轉換為 HTML 實體,這樣即使攻擊者構造了惡意的 keyword
參數,也無法在頁面中執行惡意腳本。