概述:
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
反射型XSS(GET):
1.进入页面,测试一个最常见的payload,发现输入框有长度限制。
<script>alert(1)</script>
2.检察元素,发现长度限制的代码,因此修改成一个足够大的长度
3.再次输入上方的payload,出现弹框
补充:
alert参数是可以连接字符串的,如果不加/或者单引号双引号,会被当做变量处理,如果变量有值则会弹出参数值,如果没有则不会弹窗。而后接数字就可以直接弹出。所以alert参数后接字母需要加/、单引号、双引号,后接数字直接填写。
反射型XSS(POST):
1.进入靶场,随便输入账号密码,
2.输入admin/123456登录
依然使用payload:
<script>alert(1)</script>
3.出现回显,
存储型XSS:
本题目输入框中的内容提交后会存储在数据库中,比前两种漏洞危害性更大。
提交payload后页面上会对它进行加载,然后每次打开该页面就会执行。
DOM型XSS:
DOM可以理解为理解为一个一个访问HTML的标准的编程接口,通过这个接口我们可以直接用js在前端对html文档进行操作
HTML DOM 对象 - 方法和属性
一些常用的 HTML DOM 方法:
- getElementById(id) - 获取带有指定 id 的节点(元素)
- appendChild(node) - 插入新的子节点(元素)
- removeChild(node) - 删除子节点(元素)
一些常用的 HTML DOM 属性:
- innerHTML - 节点(元素)的文本值
- parentNode - 节点(元素)的父节点
- childNodes - 节点(元素)的子节点
- attributes - 节点(元素)的属性节点
1.
查看源代码,定义str参数,把id=text的值给str,在id=dom的地方文本显示str的值。
我们发现这段代码用DOM里面的getELemeById在input中获取到了我们输入的内容,接着将获取到的内容用字符串拼接的方式写到了a标签的herf属性里面
之前我们接触的反射型和存储型都是后台接收到数据然后再输出到前台,而这里我们输入的内容被前端用DOM的getELemeById直接获取到了,再用一个div输出了
2.
本题目中输入被a标签的href超链接参数中,所以主要实现的脱破口在超链接处。
首先了解两个事件,onmouseover(鼠标悬停执行执行)和onclick(对象被点击时执行)。
字符串使用单引号或者双引号来起始或者结束
源代码中提供的方法,第一种闭合掉a标签,然后插入图片代码,然后鼠标悬停在图片上时执行payload。第二种在a标签上添加了点击执行payload的代码。
3.构造payload
' onclick=alert(1)>
DOM型XSS-X:
1.这道题点击提交后,有一个点击事件。
2.查看源代码,
3.构造payload
' onclick="alert(1)">
'><img src="#" onmouseover="alert('xss')">
4.
XSS之盲打:
1.进入页面,随意提交内容,发现并没有显示在前端,而是直接提交到后台管理员页面,
2.我们输入一行简单的payload,点击右上角的提示
<script>alert(1)</script>
3.进入登录页面,登陆到后台,出现弹窗
补充:
xss盲打其实是一种尝试性的攻击行为,因为攻击者并不知道后台有没有输出或者是过滤;
xss盲打本质还是存储型xss漏洞的利用只不是后台输出端由用户变成了网站管理员,但是危害性就更大了。
XSS之过滤:
1.进入页面,
2.在输入框输入一段payload,出现如下回显,
<script>alert(1)</script>
3.查看源代码, 可以看到我们输入的标签都被去掉了,说明后台有对<script>标签进行过滤
4.尝试大小写过滤,payload:
<Script>alert(1)</Script>
补充:
如果在没有自动添加双引号,且双引号被过滤的情况下(或者任意特殊字符被过滤),可以使用该特殊字符的实体。
XSS之htmlspecialchars:
补充关于htmlspecialchars()函数:
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
被转换的预定义的字符有:
- & 成为 &
- " 成为 "
- ' 成为 '
- < 成为 <
- > 成为 >
- : 成为 >
htmlspecialchars()函数语法格式:
$str = htmlspecialchars(string,flags,character-set,double_encode);
参数说明
第一个参数规定了需要转换的字符串;第二个参数规定了如何处理引号、无效的编码以及使用哪种文档类型,是可选参数;第三个参数也是可选参数,规定了要使用的字符集的字符串;第四个参数也是可选参数,规定了是否编码已存在的 HTML 实体的布尔值(TRUE:将对每个实体进行转换;FALSE:不会对已存在的HTML实体进行编码);
可用的引号类型:
ENT_COMPAT:默认。仅编码双引号。
ENT_QUOTES:编码双引号和单引号。
ENT_NOQUOTES:不编码任何引号。
1.进入页面,任意输入一段payload,
2.查看源代码,
3.闭合前面的引号,构造payload,发现某些符号被转义为字符实体了
'<script>alert("xss")</script>
4.构造payload,
' onclick='alert(111)'
#' onclick='alert(111)
XSS之href输出:
1.进入页面,输入一段payload,
" onclick="alert(1)
2.接着我们查看后端代码可以看到当我们输入的网址不是百度的网址时,它会通过htmlspecialchars函数进行处理,而ENT_QUOTES函数则会对单引号、双引号等特色字符进行转义处理
3.因为a标签的href属性是可以使用JavaScript协议执行JS代码的,因此构造一个没有转义字符的payload来进行绕过,可以看到整个payload里面是没有那些特殊字符的,输入payload点击提交,成功弹窗
javascript:alert(1)
补充:
JavaScript三种弹出框:
-
- 警告(alert):就是这几题一直使用的类型
- 确认(confirm):
- 提问(prompt):
href输出做防御的两个逻辑:
- 输入的时候只允许 http 或 https 开头的协议,才允许输出
-
再进行htmlspecialchars处理,把特殊字符给处理掉
XSS之JS输出:
1.进入页面,随意输入payload只返回一句中文sao话
2.查看源代码,发现一段js语句,
3.可见输入的值被赋值给了MS,我们可以构建payload,将前一句script闭合
</script><script>alert(1)</script>