WAF攻防实践(4)
背景
上周在做安全测试时,发现站点的xss能够插入标签,当我想用on事件来执行javascript脚本时,发现被waf拦截了。
经常怼waf的,应该会碰到过,waf针对标签on属性名的拦截策略分为两种:
- on属性名在黑名单列表
- 以on开头,且满足其他条件,比如字符串长度大于一定长度
举个例子,payload包含<div onXXXXX=alert(1)>
时,按照第一种策略,只有onXXXXX
在黑名单列表中,才会被拦截。第二种策略就直接拦截了,因为onXXXXX
以on
开头,且还比较长。
本文碰到的waf拦截策略是第一种,所以只要找到一个on属性不在黑名单列表中,就应该可以绕过。
所以问题变成了:
- 怎么找到所有的on属性?
- 怎么判断哪个on属性没有被过滤?
- 怎么利用未过滤的on事件?
分析过程
怎么找到所有的on属性?
前端遍历BOM对象document的属性即可
1
2
3
4
5
6
7
8let results = []
for (let i in document){
if(i.startsWith("on")){
results.push(i)
}
}
console.log(results)
localStorage.onAttrs=JSON.stringify(results)因为results字符串非常长,会在chrome控制台会被截断,所以把它存到localStorage中,结果在 Chrome devtool -> Application -> Storage 中可以找到。
怎么判断哪个on属性没有被过滤?
用burpsuite的intruder爆破模块过一遍,发现有两个属性没有拦截:
1
2ontransitionstart
onbeforexrselect这两个属性我之前也没见过,那怎么利用这两个属性执行js呢?
怎么利用
ontransitionstart
属性?根据MDN-transitionstart文档构造出利用方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<div class="transition" ontransitionstart="alert(1)">Hover over me</div>
<style>
.transition {
width: 10000px;
height: 10000px;
background: rgba(255,0,0,1);
transition-property: transform, background;
transition-duration: 1s;
transition-delay: 1s;
}
.transition:hover {
transform: rotate(90deg);
background: rgba(255,0,0,0);
}
</style>虽然文档写的chrome和firefox都支持transitionstart事件,但是上面的利用payload实际测试结果:
firefox可以、chrome不行
chrome用addEventListener可以监听
transitionstart
事件,但不能用ontransitionstart
来监听事件。这个原因不知道为啥。怎么利用
onbeforexrselect
属性?根据onbeforexrselect文档来看,似乎
beforexrselect
事件还只是一个草案。也因为transitionstart事件已经能利用了,所以也没有再研究。
总结
从防守方来看,如果采用了on事件黑名单,就需要保证事件黑名单的全面。
chrome和firefox on属性有区别,或许可以作为一个区分浏览器的指纹特征(虽然感觉很不稳定)。
测试过程中,我还有一个疑问:不同元素之间的on属性是否会不同,比如div元素和document元素遍历出来的on属性是否会不同。有知道答案的读者可以后台告诉我。
PS
我个人把防火墙的绕过分为两个类别:
- 架构层面的绕过,这种绕过不太关心具体的漏洞类型是xss还是sql注入
- 漏洞类型相关的绕过
第一种架构层面的绕过姿势比较难找,这种较为通用的绕过姿势,从攻击队视角来看我觉得比较适合扫描器来绕过防火墙。这也是你的扫描器可以绕过防火墙么系列文章名称的由来。
后面就都写到这个”waf攻防实践”系列里来。