Web安全 区分并理解XSS攻击方式(一)
什么是 XSS 攻击?
XSS
攻击又称CSS
,全称 Cross Site Script(跨站脚本攻击),其原理是攻击者向有 XSS 漏洞的网站中输入恶意的HTML
代码,当用户浏览该网站时,这段 HTML 代码会自动执行,从而达到攻击的目的。XSS 攻击类似于 SQL 注入攻击,SQL
注入攻击中以 SQL 语句作为用户输入,从而达到查询/修改/删除数据的目的,而在 xss 攻击中,通过插入恶意脚本,实现对用户游览器的控制,获取用户的一些信息。XSS 是 Web 程序中常见的漏洞,XSS 属于被动式且用于客户端的攻击方式。
xss 攻击可以分成两种类型:一种是非持久型 XSS 攻击一种是持久型 XSS 攻击
非持久型 xss 攻击:顾名思义,非持久型 xss 攻击是一次性的,仅对当次的页面访问产生影响。非持久型 xss 攻击要求用户访问一个被攻击者篡改后的链接,用户访问该链接时,被植入的攻击脚本被用户游览器执行,从而达到攻击目的。
持久型 XSS 攻击:持久型 XSS,会把攻击者的数据存储在服务器端,攻击行为将伴随着攻击数据一直存在。
也可分为两种方式:
- 反射型:经过后端,不经过数据库
- 存储型:经过后端,经过数据库
反射型
发出请求时,XSS 代码出现在 URL 中,作为输入提交到服务器端,服务器端解析后响应,xss 代码随响应内容一起传回给浏览器,最后浏览器执行 XSS 代码。这个过程像一次反射,故叫反射型 XSS。
接下来通过构建 node 应用来演示反射型 xss 攻击
Mkdir mybj cd mybj mkdir xss cd xss express -e ./
-e: 使用 ejs 作为模板引擎
然后安装依赖
npm install
正常情况下在 XSS 目录下执行npm start
整个服务就可以正常启动了
安装完成后进入目录看一下代码
cd ../
routes
下的index.js
就是服务端写接口的地方。
然后views
中index.ejs
就是我们视图部分
接下来我们启动一下服务
npm start
在浏览器中输入localhost:3000
,如下图,显示express
欢迎页面表示我们安装成功
到这里我们这个服务就简单搭建起来了。
接下来我们来演示 XSS 反射型攻击
首先我们在routes/index.js
接口中,这里是用来解析 search 内容,在这里我们设置一个字段 XSS,通过req
来获取用户在 url 中写的 search 内容xss:req.query.xss
,如下代码
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express',xss:req.query.xss }); }); module.exports = router;
然后在视图层 views/index.ejs 输出我们显示的内容,代码如下:
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <div class="mybj"> <%- xss -%> </div> </body> </html>
<%-xss-%>
表示服务端用模板的方式把刚才接口中下发的字段解析出来
注意:为什么<%-
中用的是”-”
号而不是”=”
号呢?如果是”=”
号会有什么区别呢?这里呢其实就是说要不要对html
进行转义,如果我这个内容允许输出 html,那么我们这里就不用进行转义,所以用”-”号。
然后我们重启一下服务,让我们的接口生效,看一下效果。
我们在浏览器中输入”?xss=mybj123.com”
,然后在页面上就会输出我们输入的 search 内容,如下图
接下来我们在输入一些具有攻击性的脚本,比如 ?xss=<img src=”null” onerror=”alert(123)”/>
从上图我们可以看到,我们输入的img
已经成功加入到页面上了,因为我们输入的 src 地址是 null,没有空地址,但是alert(123)
没有执行。当我们这个图片地址没有成功加载时,它会自动触发onerror
,那为什么这里这个脚本没有执行呢?我们来看一下 console 面板,答案就在这里。
从上图我们可以知道,XSS 具有 XSS 的这个能力脚本是被浏览器所拦截的,也就是说浏览器帮你自动做了拦截,换句话说如果我们把这个拦截关掉的话是不是攻击就可以生效了呢?我们来看一下如何关掉 XSS 拦截。
我们在接口调试中加入
res.set('X-XSS-Protection',0); var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res, next) { res.set('X-XSS-Protection',0); res.render('index', { title: 'Express',xss:req.query.xss }); }); module.exports = router;
也就是说把X-XSS-Protection
拦截响应设置成0
,即不要浏览器对它进行拦截,保存后,我们重启一下服务,看看效果如何
这个时候你会发现 alert 被成功执行,所以在这个阶段反射型的 xss 攻击已经生效了。
讲到这儿有的小伙伴可能要问了,这里只可以写 img 吗,当然不是了,任何其他脚本都可以。比如:
?xss=<p onclick=”alert(‘点我’)”>点我</p>
如图:
比如一个黑客想在页面中植入一部分内容,也就是篡改页面内容,从而破坏页面完整结构,你会在页面上看到具有引诱性的文字,当用户点击后,URL 中所具备的编写的XSS
脚本已经执行,这个时候就是整个网站具有被攻击的一部分了。那么,当黑客把这个地址通过其他渠道发送给用户,用户点击具有引诱性的文字后,这个XSS
攻击从攻击到受害流程就走完了。
上面我们通过 img 方式是自动触发的,p
标签方式是引诱触发的,还有一种形式是大家比较关注的,就是iframe
方式,如下图:
从上图可以看到,这个攻击方式使你的页面会嵌入一个页面。如果 xss 共计代码是这样写的,它就会实现各种广告的插入,这是最简单也是最常见的攻击方式。这样他就可以在你的页面插入任何他想插入的广告。
存储型
存储型 XSS 和反射型 XSS 的差别仅在于,提交的代码会存储在服务端(数据库,内存,文件系统等),下次请求目标页面时不用在提交 XSS 代码。
在反射型 XSS 攻击中,通过在脚本中获取 url 参数来做解析xss:req.query.xss
。如果是存储型 XSS 攻击,端口代码可能就是 sql 语句了xss:sql()
,通过读数据库,读缓存最后返回,至于视图渲染这一块两攻击方式渲染流程是一样的。
这里给大家一个疑问,存储型的攻击脚本是如何到达服务器端存储系统里面的呢?
码云笔记 » Web安全 区分并理解XSS攻击方式(一)