Part.0
目录
目录
一、XSS概述
二、XSS的分类
三、XSS的利用
四、XSS挖掘技巧
五、XSS的防护
Part.1
XSS概述
什么是XSS ?
XSS全称Cross Site Script,跨站脚本攻击。
通常指攻击者通过“HTML注入”篡改网页,插入恶意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击手段 。
在2017年的OWASP TOP10中,XSS攻击排行第七,破坏力强大,如下图所示:
到底什么是XSS呢?我们直接来看一个例子。
我们先写一个前端页面,要求用户输入用户名,并传给后端处理:
后端处理页面,网页将接收到的用户名直接输出到页面上:
访问前端页面,输入用户名Monster:
点击提交,页面返回后端处理结果:
如果我们提交一段HTML恶意代码,就会发现代码在当前页面执行了。
例如提交<script>alert('hacker')</script>,页面出现弹窗:
查看网页源代码,会发现恶意代码被插入到当前页面中了:
这就是一个简单的反射型XSS,虽然这里看上去没有什么大的危害,但其实XSS攻击可以做到更多事,例如盗取用户cookie,修改网页内容,恶意挂载木马等等。
Part.2
XSS的分类
XSS的三种类型
XSS一共有三种类型,分别是反射型XSS、存储型XSS以及DOM型XSS。
(1)反射型XSS:
反射型XSS也称为非持久性XSS,正如上面的例子,这种攻击方式只是简单的把用户输入的数据“反射”给浏览器,只对当前URL链接生效。因而攻击者需要引诱用户点击恶意链接才行。
(2)存储型XSS
存储型XSS又称为持久性XSS,会把恶意代码存储在服务器端,危害性极强。例如攻击者发表了一篇带有恶意js代码的文章,那么所有访问该文章的用户都会中招。
(3)DOM型XSS
DOM型XSS也是一种反射型XSS,需要向服务器输入数据,与常规的反射型XSS不同,DOM型XSS需要通过修改页面的DOM节点来形成XSS。
接下来我们先通过DVWA平台low等级看看这三种XSS的成因。
反射型XSS
本页面要求我们输入用户名:
前端代码,通过GET方法将name参数传递给后端:
后端代码,接收$_GET传递的参数后,不做任何过滤,直接输出到页面:
输入<script>alert('hacker')</script>
js代码执行,页面出现弹窗:
和前面举的例子一样,可以看出XSS产生的原因有两点:
存储型XSS
该页面是一个留言板
输入姓名和信息即可留言,例如输入Name为Monster,Message为Hello,world!
每次访问该页面,都会加载留言信息,如下:
如果在此处插入一个js恶意脚本,每次有人访问该页面,都会加载这个恶意脚本,这就是存储型XSS。
查看后端源代码:
我们来对其中一些函数进行解释:
由代码可知,并未对输入做过多限制,name和message栏都存在XSS注入漏洞。
直接在message栏输入<script>alert('hacker')</script>,之后每次访问该页面都会弹窗:
DOM型XSS
注入页面如下,需要我们选择语言:
后端源代码如下:
我们选择French,会发现URL变成了:
http://192.168.211.151/vulnerabilities/xss_d/?default=French
修改url中default=88888888,当前页面随之修改:
直接查看网页源代码,会发现有一段js代码:
修改了页面的DOM节点,将我们输入的内容直接插入到了HTML页面中:
修改url中default=<script>alert(1)</script>,出现弹窗:
查看网页源代码,恶意代码被插入网页中:
这就是一个简单的DOM型XSS的成因,效果和反射型XSS相似。
DVWA平台通关
DVWA平台XSS页面分为4种安全等级,从low等级到impossible等级。
low安全等级主要是展示漏洞成因,安全等级往上递增,会增加不同的防御手段,impossible等级不存在漏洞。
之前写过一期通关指南,直接搬运如下:
Part.3
XSS的利用
XSS的利用
1、利用XSS盗取用户cookie
2、利用XSS进行网页挂马
3、配合 CSRF 攻击完成恶意请求
【CSRF漏洞】通过实验教你学会CSRF攻击 Part3
4、利用XSS进行网页钓鱼
Part.4
XSS挖掘技巧
利用字符编码
一些网站会对我们输入的特殊字符加“\”进行转义,例如php在magicquotesgpc = On的情况下,如果输入的数据有:
单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。
我们来看一个例子:
在magic_quotes_gpc =Off 时,输入
?x=1";alert(1)// 即可弹窗:
现在我们开启magic_quotes_gpc=On,输入
?x=1";alert(1)// :
会发现双引号被转义,无法弹窗。
但是,如果返回页面像本网页一样是GBK/GB2312编码的话,我们也可以使用宽字节进行逃逸。
当网页使用了GBK编码时,会认为两个字符为一个汉字,例如%df%5c就是一个汉字(前一个ascii码大于128才能到汉字的范围),因此经过转义后,%df%5c(%5c为 \)就会变成一个汉字,把转义符吃掉。
输入?x=1%df";alert(1)// ,成功弹窗:
XSS注入点分析
XSS有可能发生在HTML标签中、HTML属性中、在标签中、在事件中等。
之前写过一次分析,没看过的小伙伴可以看一下:
不完整的黑名单
有些网站会使用黑名单的方式,过滤掉一些敏感js标签,例如:
过滤掉了大多数js标签,输入a\lert(1)试试:
alert被替换成了****
但这里的黑名单漏掉了eval()函数,这就是黑名单不如白名单安全的原因,黑名单会出现遗漏的情况。
为了避免被过滤,将alert(1)转换为ASCII码形式:
构造payload如下,成功弹窗:
Part.5
XSS的防护
开启HttpOnly
JS 原生的 API提供了获取cookie的方法:document.cookie,在XSS攻击中,常常被用于盗取用户的cookie。
如果能够盗取网站管理员的cookie,那么就可以用管理员的身份直接登录网站后台,而不必非要去获得管理员账号和密码。
在正常网页通过document.cookie可以获取当前页面cookie,例如在以下页面插入js代码:
访问该页面,弹窗用户cookie值:
通过以下恶意脚本,可以将用户cookie发送至远端服务器,完成窃取。
但是一旦我们给该页面cookie添加上HttpOnly属性,就可以防止这种恶意行为,修改代码如下:
HttpOnly属性用来设置cookie是否能通过 js去访问,默认情况下该选项为空,客户端可以通过js代码去访问(包括读取、修改、删除等)cookie。
当cookie带httpOnly选项时,客户端则无法通过js代码去访问了,是防御XSS攻击的常用手段之一。
再次访问该页面,无法获取到该页面的cookie:
输入输出检查
防护XSS首先可以从输入入手,因为我们默认所有用户的输入都是不可信的,因此需要过滤掉输入中的敏感字符,有时候也需要检查输入内容格式是否合规。
当我们需要将内容输出到网页时,为了确保即使包含XSS特殊字符,也不会被执行,我们可以对输出内容编码后再进行输出。
可以从以下几个角度来考虑:
(1)黑名单、白名单
通过黑名单匹配XSS特征,例如、javascript等敏感字符,但是可能出现遗漏而被绕过的情况。相较而言白名单则更加安全,匹配成功则放行。
(2)电话、邮件、日期等格式要求
比如电话号码使用is_numeric()函数进行检查,必须是纯数字才行。邮件、日期也都有其相应的格式,输入的字符串是否超过最大长度等,这种方法类似白名单。
(3)利用编码函数
对、'、"等特殊字符,进行过滤或者编码。
使用编码函数可以有效防止XSS攻击,以php为例。
addslashes():
strip_tags():
htmlentities():
htmlspecialchars():
Part.6
结束语
这就是今天的全部内容了,大家都明白了吗?
Peace !