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 成功绕过特殊符号