Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直是web漏洞中比较危害大的漏洞,在OWASP TOP10的排名一直处于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
XSS 漏洞可以进行钓鱼攻击、用户cookie获取、前端js挖矿,甚至可以结合浏览器自身漏洞对用户主机进行远程控制
1.跨站脚本漏洞类型
(1)反射型xss
交互的数据一般不会存在数据库,一次性,一般出现在查询页面
(2)存储型xss
交互的数据会存在数据库中,永久性存储,危害较大,一般出现在注册、留言板等页面
(3)Dom型xss
不与后台进行交互,是一种通过dom操作前端代码输出的时候产生的问题,也是属于一次性的。
2.测试流程
要先了解XSS的测试流程,首先我们需要先了解XSS的攻击流程。
最主要的就是因为程序对输入和输出的控制不够严格,导致脚本输入后,在前端被当成有效代码解析执行当作危害。
那么,我们的测试流程也就有思路了
(1)我们首先在目标站点找到输入点,比如查询接口,留言板之类的。
(2)输入一组特殊的字符+唯一识别字符,来看它源码,是否有对应的处理
(3)通过搜索定位到唯一字符后,结合唯一字符前后语法是否可以构成执行js的条件,也就是构造闭合
(4)提交构造的脚本代码以及各种绕过姿势,看看是否能执行,如果行,就说明存在XSS漏洞。
我们通过Picachu靶场来看看,xss到底是什么。
根据我们前面的测试流程,我们首先输入一些特殊字符和唯一识别字符,我们来看看。
我们在输入框输入以后,点击提交
根据我们的思路,来看一下页面的源码
通过输入唯一识别字符,我们能看到我们输入的东西被输出到了P标签中
我们输入的东西好像被原封不动的输出出来了,那么,假如我们输入一段java script的代码,它还是会原封不动的输出嘛?
我们来试试
我们在输入框输入一段Java Script的代码
点击提交
没错,那这就说明存在XSS漏洞,这就是一个反射型的XSS。
我们来看它的源码
我们输入的东西被原封不动的输出了出来。
存储型的XSS与反射型的XSS一样,但它是将脚本存在了后台储存起来,构成更持久的危害,也称为永久性xss
话不多说,我们用实例来看
按照惯例,在留言框中输入特殊字符+唯一识别
提交之后,发现它会一直存在在那里
然后,我们接着输入一段Java script的代码,来看看效果如何。
提交之后,发现弹窗,当我们刷新页面的时候,会发现,会一直弹窗
我们查看源码,还是没有做任何的处理。
在这之前,我们先来了解一下什么是Dom。
DOM 是一项 W3C (World Wide Web Consortium) 标准。
DOM 定义了访问文档的标准:
“W3C 文档对象模型(DOM)是中立于平台和语言的接口,它允许程序和脚本动态地访问、更新文档的内容、结构和样式。”
W3C DOM 标准被分为 3 个不同的部分:
·Core DOM - 所有文档类型的标准模型
·XML DOM - XML 文档的标准模型
·HTML DOM - HTML 文档的标准模型
而html dom是HTML 的标准对象模型和编程接口
换句话来说,HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准
HTML DOM 方法是能够(在 HTML 元素上)执行的动作。
HTML DOM 属性是能够设置或改变的 HTML 元素的值。
也就是说dom就是一个前端接口,不与后台交互
打开我们的Picachu
在DOM型xss中输入框输入1111,点击click me!
接着我们查看源代码,看看它是怎么处理的
这段Java script的代码,我们看看是什么意思
首先它使用dom里面的document.getElementById获取到了id=text的值
text 就是下面input 也就是我们输入的内容,。
然后通过dom的操作,将我们输入的内容拼接在了a标签的href属性中
接着a标签会写在id=dom的div标签中
闲话不多说
我们来看看怎么搞
通过分析代码,我们发现我们输入的东西是str,而str又拼接在A标签中,这样的话,我们就有思路了
通过将前面A标签闭合,来构造一个恶意代码
可以看到它代码就是
然后我们来闭合它
'>what do you see
简单来说就是单引号闭合前面那个单引号
尖括号闭合a标签
中间再来一个弹窗
然后把我们自己写的拿出来
'οnclick=“alert(‘xss’)”>
我们来输入试试
按照我们之前的思路,我们输入的东西会被拼接到a标签中,然后它不做处理的话,就会执行我们的代码,也就是onclick的话,会弹窗
点击what do you see后
这样的话,它就是存在DOM型的xss漏洞
我们来看下一个
同样是在输入框输入1111点击
它弹出了一段话
我们看看它网页的源代码
同样是有一段Java script的代码
简单分析一下
它会将URL中传参的内容获取到,然后通过一个url的解码,获取到输入内容并赋值给xss
然后将变量xss写入a标签的href属性中
这样的话,我们的思路和刚刚一样
同样是闭合a标签构造代码
还是输入我们刚刚的脚本
'οnclick=“alert(‘xss’)”>
点击以后
这里我们要注意的是
上面url里的东西
http://127.0.0.1/pikachu-master/vul/xss/xss_dom_x.php?text=+%27onclick%3D%22alert%28%27xss%27%29%22%3E#
如果将这段url发送给受害者,那么当他点击连接的时候,就会执行我们构造的恶意的Java script代码了。
大家也可以去试试别的代码
我们先来了解一下get型xss利用
在用户访问xss页面后,触发脚本,然后会返回带有恶意js的页面
然后用户执行脚本,攻击者就会获取到cookie,然后伪造用户登录,造成破坏。
我们首先在下面的管理工具中搭建好要接收的cookie的后台
要将pkxss单独放在WWW目录下(pkxss是一个可以单独使用的后台)
接着我们修改config.inc.php中数据库的密码,与我们的数据库保持一致
安装好以后
有三个功能
回到网站,我们根据之前的逻辑
当用户访问存在xss漏洞的站点,会触发脚本,返回带有恶意的js的页面
我们就可以执行脚本,获取到用户的cookie
获取到的cookie呢,就在我们的pkxss网站中
这里要说一说这个网站的源码了
大致就是先用get方式获取cookie
然后将网站重定向到一个新的可信的网站
这个就是将接受到的cookie进行一个查询输出
回到我们的get型xss中
我们之前做过,如果我们输入一段Java script的alert代码的话,就会进行一个弹窗
那么,我们这次输出一个更加复杂的payload
我们通过获取到cookie并且传到pkxss中
首先将这个文本框长度修改一下
然后我们输入那段代码
点击提交之后,发现返回到了127.0.0.1首页
接着我们来看一下后台
这样的话,我们就接受到了用户的cookie
接着我们将referer里的url复制,打开一个新的页面
发现它会直接跳到首页,并且在后台也会获取到它的cookie
这就是简单的利用xss获取用户cookie
我们之间说过,反射型和存储型一样,只不过一个是一次性的,一个是永久储存的
和反射型一个思路
那么我们就来试试存储型来如何钓鱼
还是打开pikachu,存储型的页面
在我们pkxss中有一个xfish,里面有三个代码
我们都看一下。
第一个
简单理解一下,就是会给出一个认证框
然后获取用户输入的数据
按照之前的思路,我们来写一个payload
在留言版中写下我们的代码
然后点击提交
它就会提示让用户输入用户名和密码
如果我们输入后点确定的话,后台就会接受到。
什么是xss的盲打呢
就是说从前端无法判断是否存在xss
只有后台会看到前端输入的东西
我们用pikachu来试试
再试试我们之前的Java script代码
然后我们登录
弹窗了!
说明后台没有对输入的东西进行判断
管理员登录以后还是会被X
这种危害还是很大的
如果输入一段恶意的代码
就可以获取到管理员的cookie
那么 就可以伪造管理员登录了。
我们还是用之前方式打一遍
提交它
发现我们输入的script被过滤掉了,说明它后台对script进行了处理
那怎么办
我们尝试一下大小写混合输入script
发现弹窗了,说明绕过了它的验证
这里总结一下几种场景
1.前端绕过:
我们可以抓包重放,或者直接修改html前端代码
2.大小写:
有些措施会过滤掉你输入的代码,比如正则匹配
或者用一些查找的函数找到你的恶意代码
可以尝试大小写混合输入
3.拼凑:
有些后台会把script这些东西进行替换,但有些逻辑只会拼凑一次
比如:
ript>alert('xss')ipt>
他会把中间的script给替换掉
但是剩下的依然是script
4.注释干扰:
还是举个例子
ipt>alert('xss') ipt>
在前端的时候,被注释掉了
但是后台不认识它,不会认为它是script的标签,从而绕过
5:编码
后台会对特殊字符过滤,但是不一定认识编码后的东西
但是在编码的时候,要注意编码在前端输出的时候能被正常翻译,否则不行。
htmlspecialchars函数是把预定义的字符转化为html实体
我们依然是之前的方法,特殊字符、唯一识别字符
提交之后
接着 我们看看源码
对一些特殊字符进行了处理,但是常规的specialchars函数不对单引号做出了
我们来写一个payload
提交之后 点击
href中:
我们还是之前的逻辑,以此测试一遍
接着就是Javascript代码
还是不弹窗,我们来分析一下源码
之前的specialchars方法,这次还把单引号也给处理了
那怎么办呢
其实,输出在a标签的href属性里面,可以使用javascript协议来执行js
我们来执行一下这个payload
提交之后,点击下面的链接
弹窗成功!
那怎么预防呢,我们可以对输入的东西做要求
例如只输入http之类的 然后再用specialchars处理
js中:
我们来构造一个闭合
'
这里讲输入动态的生成到了js中,形成xss
Javascript里面是不会对tag和字符实体进行解释的,所以需要进行js转义
讲这个例子主要是为了让你明白,输出点在js中的xss问题,应该怎么修?
这里如果进行html的实体编码,虽然可以解决XSS的问题,但是实体编码后的内容,在JS里面不会进行翻译,这样会导致前端的功能无法使用。
所以在JS的输出点应该使用\对特殊字符进行转义
总原则:
输入做过滤,输出做转义
过滤:比如对输入的东西做要求,如输入手机号,只能输入数字
转义∶所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行html实体转义,输入到JS里面的进行js转义。
常用payload
#最普通的xss
#获取cookie
xss #a链接的xss
# 外部攻击代码
#加载图形失败执行