V0W's Blog

XSS漏洞原理&复现

字数统计: 1,743阅读时长: 8 min
2018/08/16 Share

XSS原理&复现

前言

之前也学习和总结过XSS,但是由于当时能力有限,理解不是透彻,还有很多骚姿势,都没看懂,现在因为遇到几个XSS的题目,并且有了新的理解,遂总结一下XSS原理&复现,之后还将总结XSS攻击手段&在CTF中的运用以及XSS的绕过姿势

什么是XSS

CSS(Cross Site Scripting,跨站脚本攻击),为了和层叠样式表(Cascading Style Sheet,CSS)区分,所以安全领域改为叫XSS。
XSS攻击能让攻击者在受害者的浏览器中执行js脚本,并劫持用户会话、破坏网络或将用户重定向到其他恶意的站点。

XSS的分类

1. 反射型XSS

所谓反射型XSS,就是简单的吧用户输入的数据‘反射’给浏览器。也就是说,黑客我那个网需要有事用户‘点击’一个恶意链接,才能攻击。这其实是比较被动的。

2. 存储型XSS

存储型XSS会把用户输入的数据‘存储’在服务器端。当访问数据库数据时,从数据库取出数据,并由HTML显示,这时导致了XSS的产生。

比如黑客将恶意js脚本写在一个博客中,下次任何人访问这个博客,都会在他们的浏览器中执行这段恶意js脚本。导致‘Cookie劫持’等。

3. DOM型XSS

首先是关于DOM节点:
整个文档是一个文档节点 从每个 XML 标签是一个元素节点 包含在 XML 元素中的文本是文本节点 每一个 XML 属性是一个属性节点 注释属于注释节点。

HTML 文档中的所有内容都是节点:

  • 整个文档是一个文档节点
  • 每个 HTML 元素是元素节点
  • HTML 元素内的文本是文本节点
  • 每个 HTML 属性是属性节点
  • 注释是注释节点

和反射型XSS类似,但是这类XSS执行脚本的位置与反射型XSS不同,是修改了页面的DOM节点而造成了恶意js脚本的执行。

总结

XSS类型 反射型 存储型 DOM型
触发过程 正常用户访问携带XSS的url 1.黑客构造XSS脚本
2.用户访问有XSS脚本的网站
正常用户访问携带XSS的url
存储位置 url 数据库 url
谁来输出 后端web 后端web 前端JS
输出位置 HTML响应 HTML响应 动态生成的DOM节点

简单复现

反射型XSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS原理重现</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="xss_input">
<input type="submit"></form>
<hr>
<?php
$xss = @$_GET['xss_input'];
echo "your input:".$xss."\n";
?>
</body>
</html>

很简单的功能,输入数据,返回数据
mark

但是,如果输入的数据是XSS攻击语句,就会造成弹窗等问题

mark
看一下源码,发现XSS语句已经嵌入到html中。

1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS原理重现</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="xss_input">
<input type="submit"></form>
<hr>
your input:<script>alert('xsss')</script>
</body>
</html>

存储型XSS

复现代码xss_save.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>存储型XSS重现</title>
</head>
<body>
<form action="" method="get">
<input type="text" name="id" value="id">
<input type="text" name="xss_input" value="text">
<input type="submit"></form>
<hr><!--分割线-->
<?php
$id = @$_GET['id'];
$xss = @$_GET['xss_input'];
mysql_connect("localhost","root","meimima123");
mysql_select_db("test");
if($xss !== null){
$sql = "insert into xss(id,text)values('$id','$xss')";
$result = mysql_query($sql);
echo $result;
}
?>
</body>
</html>

展示代码show_save.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html><!--此网页用于展示数据库中的所有数据-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>存储型XSS重现2</title>
</head>
<body>
<?php
mysql_connect("localhost","root","meimima123");
mysql_select_db("test");
$sql = "select id,text from xss";
$result = mysql_query($sql);
while(@$row=mysql_fetch_array($result)){
echo $row['id'].":".$row['text']."</br>";
}
?>
</body>
</html>

注意转义,将内容写入数据库:
mark
发现已经写入数据库:

1
2
3
4
5
6
7
8
mysql> select * from xss where id=3;
+------+-------------------------------+
| id | text |
+------+-------------------------------+
| 3 | text |
| 3 | <script>alert('XSS')</script> |
+------+-------------------------------+
2 rows in set (0.00 sec)

当另一个网页浏览show_save.php时,就会触发XSS
mark

并且将恶意代码插入了HTML:

1
2
3
4
5
6
7
8
<html><!--此网页用于展示数据库中的所有数据-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>存储型XSS重现2</title>
</head>
<body>
0:text</br>0:text</br>:text</br>:2</br>1:222</br>3:text</br>3:<script>alert('XSS')</script></br></body>
</html>

DOM型XSS

xss_dom.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>DOM型XSS重现</title>
</head>
<body>
<script><!--js脚本-->
function test(){
var str = document.getElementById("text").value;
document.getElementById("t").innerHTML = "<a href='"+str+"'>testLink</a>";
}
</script>
<div id="t"></div>
<input type="text" id="text" ="text" value="" />
<input type="button" id="s" value="url" onclick="test()" />
</body>
</html>

利用payload'><img src=# onerror="alert('XSS')"><'执行XSS攻击:
mark
利用firebug插件查看DOM节点的改变情况(js脚本改变DOM节点的内容,直接查看源码是不显示的),发现
mark
而原来的link变成了:

1
2
3
4
5
6
<div id="t">
<a href="">
<img src="#" onerror="alert('XSS')">
<''>testLink
</a>
</div>

从而简单的绕过了link,执行了XSS脚本。

也可以利用这样的payload' onclick=alert(/xss/) //

mark

原来代码变成了:

1
2
3
<div id="t">
<a href="" onclick="alert(/xss/)" '="">testLink</a>
</div>

闭合href标签,注释后面多余内容,从而在用户点击超链接时,触发XSS。


另外,DVWA上也有XSS漏洞环境,可以利用其复现漏洞,理解原理。

XSS预防

因为XSS的根本就是向网站插入脚本代码,并使它运行的一种手段。防御方法分为两种,服务端防御和客户端防御。
服务端防御:

  1. HttpOnly
    可以限制javascript不能读取cookie,防止会话ID泄露
  2. 处理富文本
    过滤掉富文本中的敏感标签如(script、iframe、form),还有敏感词(javascript:) 等等

客户端防御:

  1. 输入检查
    防止输入敏感字段,如javascript、cookie等等
  2. 检查输出
    脚本都是通过混淆在HTML当中,被当成html代码的一部分才得到执行。
    可以通过编码转义的办法,使得混淆在其中的脚本被当成文本处理,不会被执行。
    编码转义的话,有三种方法:
    1
    2
    3
    4
    5
    6
    7
    *1.  HTML encode*
    将字符转换成HTMLEntities,一般会转(&、<、>、"、'、/)这6个字符。一般是在html标签属性输出的时候使用
    *2. JavaScriptEncode*
    使用”\“对特殊字符进行转义。
    一般在script标签输出、事件输出、CSS输出
    *3. URL Encode*
    使用URLEncode的方法。

参考链接

  1. 《白帽子讲web安全》-道哥
  2. XSS原理及其预防
  3. 【从零开始学CTF】10、JavaScript 与 XSS 与 CSRF
CATALOG
  1. 1. XSS原理&复现
  2. 2. 前言
  3. 3. 什么是XSS
  4. 4. XSS的分类
    1. 4.1. 1. 反射型XSS
    2. 4.2. 2. 存储型XSS
    3. 4.3. 3. DOM型XSS
    4. 4.4. 总结
  5. 5. 简单复现
    1. 5.1. 反射型XSS
    2. 5.2. 存储型XSS
    3. 5.3. DOM型XSS
  6. 6. XSS预防
  7. 7. 参考链接