前言
反射型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标签。
漏洞利用
由于没有作任何防护, 我们可以直接注入:
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元素。