
1.2.2 XSS Bypass技巧
1.判断输出点及其上下文
尝试插入正常的字符串如“xsstest”“111111”,确定字符串输出的位置。
当输出位置在标签的属性里时,可以看到输出位置位于input标签的value属性处,输出内容被引号包围,如图1-57所示。

图1-57 输出内容被引号包围
闭合value属性,写入一个新的属性并构造XSS Payload,比如我们可以通过HTML的事件对象来构造。一般在<、>被过滤时使用这种方法。
利用事件对象onclick语法执行JavaScript语句,当用户点击对象时调用其事件句柄。在浏览器中输入Payload:?name="onclick="alert(xss);,执行结果如图1-58所示。

图1-58 onclick弹框
这里列出一些常用的事件对象,如表1-2所示。
表1-2 常用的事件对象

闭合input标签,直接在页面里构造XSS Payload。这时候构造Payload的方法就很多了,部分代码如下。

执行结果如图1-59所示。

图1-59 闭合标签
输出位置在<script>标签的情况还是比较常见的。举个例子,我们输入的name字段会被拼接到<script>标签内,并且被一个函数的"和{}包裹,代码如下。

输入?name=1";}alert('xss');{"1,可以闭合"和{},执行结果如图1-60所示。

图1-60 绕过<script>标签
因为输出位置已经被script标签包裹,所以我们的输入会被当成JavaScript代码执行,开发者在做XSS防护的时候很容易忽略这一点。
将用户输入的内容直接输出在页面上,这种没有上下文的情况也比较常见,因为没有上下文干扰,所以我们可以直接写Payload。
2.构造Payload
下面介绍XSS靶场Prompt(1) to win中3个简单的关卡。Prompt(1) to win的最终目标是在页面上执行Prompt(1)。输出点位于input标签的value属性中,两边被"符号包裹,如图1-61所示。

图1-61 定位输出点
将input标签闭合,再写入prompt标签。输入"><script>prompt(1);</script>,执行结果如图1-62所示。

图1-62 执行成功
再来看一个例子,输出点位于article标签内,并且用正则表达式过滤了<内容>的标签格式,如图1-63所示。

图1-63 正则过滤
正则规则分析如图1-64所示。

图1-64 正则规则分析
我们直接利用<img src=x onerror="prompt(1)",不输入最后一个">",浏览器会自动往后寻找">"帮我们闭合img标签,如图1-65所示。

图1-65 自动闭合标签
接着进行下一关,过滤了=(,输出位置没有任何干扰,直接输出在页面上,如图1-66所示。

图1-66 过滤特殊符号
JavaScript里某些函数是支持用``代替()的,除了prompt()函数不支持。SVG标签会将XML实体解析后加入标签,我们可以利用其会解析编码的特性绕过一些符号的过滤,代码如下。

或者利用eval函数。在JavaScript里,eval函数能够接受十六进制的字符串。

执行结果如图1-67所示。

图1-67 成功绕过特殊符号