PortSwigger靶场之将反射型 XSS 注入到带有尖括号和双引号的 JavaScript 字符串中,并使用 HTML 编码和单引号进行转义通关秘籍
一、题目分析
该实验室包含搜索查询跟踪功能中的反射型跨站点脚本漏洞,其中尖括号和双引号是 HTML 编码的,而单引号则被转义。
- 尖括号 (
< >
) 被HTML编码: 这意味着我们不能使用</script>
来闭合script标签。我们必须在当前的<script>
块内完成所有操作。 - 双引号 (
"
) 被HTML编码: 这条限制影响不大,因为字符串是用单引号包裹的。 - 单引号 (
'
) 被转义: 这是最关键的限制。服务器会将我们输入的任何一个单引号'
替换为\'
。这导致我们无法通过简单地输入'
来闭合字符串。
综合来看,我们被困在了一个JavaScript字符串里,并且无法使用常规方法(闭合标签或闭合引号)来逃逸。
但是我们可以通过找到 '
,然后把它变成 \'
。因为服务器并没有考虑如果我们自己先输入一个反斜杠 \
会怎么样。我们可以利用这一点来“欺骗”JavaScript的解析器。
核心思想是:注入我们自己的反斜杠 \
,用它来转义掉服务器为我们添加的用于转义的反斜杠 \
。
二、攻击过程
1、构造payload
\'-alert(1)//
2、攻击流程
第一步:我们输入 Payload 我们向服务器提交的搜索词是
\'-alert(1)//
。第二步:服务器进行转义 服务器的程序会扫描这个字符串,找到其中的单引号
'
,并在它的前面加上一个反斜杠\
。原始输入:
\'-alert(1)//
转义之后:
\\'-alert(1)//
(注意,现在有两个反斜杠了)
第三步:浏览器解析最终的JavaScript代码 最终,页面中的JavaScript代码会变成这样:
var searchTerms = '\\'-alert(1)//';
现在,我们来看看JavaScript是如何解析这行代码的:
引擎首先看到第一个
'
,开始解析一个字符串。紧接着它看到了
\\
。在JavaScript中,两个反斜杠\\
是一个转义序列,代表一个字面意义上的反斜杠\
。然后,它看到了一个
'
。因为这个单引号前面没有反斜杠了(\\
已经被消耗掉了),所以JavaScript引擎认为这个单引号就是字符串的结束符!至此,
var searchTerms = '\\'
这部分代码被成功执行。变量searchTerms
的值就是一个反斜杠\
。接下来,引擎继续向后解析,它看到了
-alert(1)
。在alert(1)
前面加上-
是一种防御性编程思想,它能有效地将我们的代码与上下文分离开,确保我们的函数调用被当作一个独立的、新的表达式来执行,从而大大提高了Payload在各种未知环境下的成功率。这是一个合法的JavaScript表达式(alert(1)
会先执行,返回undefined
,然后进行一个无效的减法运算),最重要的alert(1)
被成功执行了!最后,引擎看到了
//
。这是JavaScript的单行注释符。它会将代码行中剩余的所有内容(包括原来代码中用于闭合的'
和;
)全部注释掉,从而避免了语法错误。