XSS漏洞基础

概念

xss 跨站脚本攻击(Cross Site Scripting)

其实应该简称为css,但是这与层叠样式表的缩写重合了,因此改名xss。

攻击者会在web页面中的input表单、url、留言板等位置插入js代码,导致用户访问时触发,达到攻击目的。


原理

服务器对用户提交的数据没做过滤,或者过滤不严,导致浏览器把用户的输入当成了js代码并直接返回给客户端执行。


分类

  • 反射型(非持久)
  • 存储型(持久)
  • DOM型(非持久)

反射型

攻击流程:
攻击者:发现存在反射型xss的url -> 构造xss代码 -> 进行编码、缩短(增加迷惑性) -> 发送给受害者
受害者:收到链接并点开 -> xss代码执行

攻击对受害者而言是一次性的。

例:

php源代码: 发现未做过滤

1
2
3
4
5
6
7
8
9
10
11
<?php

header ("X-XSS-Protection: 0");

// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}

?>

测试: 在输入框输入xss探针、payload进行测试 发现构造的脚本被执行了

URL: 观察URL结构

1
http://localhost:8081/dvwa/vulnerabilities/xss_r/?name=

构造: 插入脚本语句

1
http://localhost:8081/dvwa/vulnerabilities/xss_r/?name=<script>alert("xss");</script>

编码:

1
http://localhost:8081/dvwa/vulnerabilities/xss_r/?name=%3Cscript%3Ealert(%22XSS%22);%3C/script%3E

存储型

应用程序通过web请求获取数据,在未检验是否存在xss代码的情况下就存入数据库。用户下一次请求从数据库中获取该数据的时候,该程序也没进行过滤,最终用户浏览器界面执行xss代码。

这种xss漏洞的影响是持久性的。由于xss代码被储存在了数据库中,因此每当用户获取这些数据时都会获取到xss代码。只要xss代码仍在数据库中存在,这个过程就还会重现。

这种类型的xss常见于网站的评论区。用户提交了包含xss代码的留言到数据库,当目标用户查询留言时,留言中的xss代码就会加载出来并被当成脚本执行。

攻击流程

攻击者: 发现存在存储型xss -> 构造xss代码并提交至网站数据库中

受害者: 点开目标网站,网站服务端将恶意代码从数据库中取出,拼接在html发送给受害者的浏览器 -> 受害者浏览器收到响应后解析执行,同时恶意代码也被执行

例:

php源代码:发现未做过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );

// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

//mysql_close();
}

?>

在评论区发送xss恶意代码,使其被存入网站数据库

1
<img src=1 onerror=alert('xss')>

等受害者浏览网页,查看评论区并加载该评论时,浏览器解析到xss代码并执行脚本

DOM型

通过javascript操作document,实现dom树的重构。

主要存在于用户能修改页面的dom,造成客户端payload在浏览器中执行

这个暂时理解不到位,正在深入学…


防御手段

对输入的数据和URL参数进行过滤

检查是否含有特殊字符 如

< > ‘ “

将以上字符过滤,或者编码

对输出内容进行编码

变量的内容输出到HTML页面时,用编码或者转义的方式来防御攻击。

HTML实体编码

将字符串js编码转换成实体html编码