【渗透测试】XSS-Labs通关教程,超详细,小白也能看懂
一、为什么要学 XSS-Labs?
了解XSS漏洞的利用技巧和绕过技巧,是Web安全学习的核心能力之一。无论是面试中的XSS知识点还是真正的渗透测试中的漏洞,通过XSS-Labs的通关练习可以帮助你:
1、理解不同类型 XSS(反射型、存储型、DOM 型)的原理差异;
2、掌握 HTML 标签注入、事件触发、编码绕过等核心技巧;
3、建立 “输入过滤与输出编码” 的安全防护思维。
二、前置知识
2.1 W3C标准
W3C标准:网页主要由三部分构成
1、结构:HTML(简单掌握HTML,学会写常用标签、大体能看懂网站HTML源码即可)
2、表现:CSS(简单了解,知道作用就行)
3、行为:JavaScript(需要较深入了解,但具体的语法在练习中学习即可)
2.2 XSS 原理与分类
XSS(跨站脚本攻击)是指攻击者在网页中注入恶意 JavaScript 代码,当用户浏览时代码被执行,从而实现窃取 Cookie、劫持会话等攻击。
根据触发方式分为三类:
- 反射型 XSS:非持久化,需诱骗用户点击含恶意代码的链接(如搜索页 URL),常用于窃取 Cookie;
- 存储型 XSS:持久化,恶意代码存储在服务器(如评论区、个人资料),所有访问该页面的用户都会触发,危害更大;
- DOM 型 XSS:不经过后端,通过 URL 参数控制前端 DOM(文档对象模型)执行代码,本质属于反射型。
三、通关实战(Level1-20)
Level1:基础标签注入
本关主要考的是无过滤的 HTML 标签注入
当输入的内容直接嵌入 HTML 页面时,可通过<script>标签执行 JavaScript 代码。
<script> 和 </script>: 是HTML标签,用于定义JavaScript代码
alert() :是JavaScript内置函数,用于在浏览器中弹出警告对话框
当浏览器解析到这行代码时:会立即执行 alert("文本") 函数,弹出一个含有文本的警告对话框,用户需要点击"确定"按钮才能继续浏览页面

通过查看网站源码,可以发现get传参中name的值test插入了html的head,并且回显了payload长度,可以断定要通过name传入payload

大家可以可以试试在name=后面输入testtest,这时就会回显payload的长度为8
在url后的get传参处上payload
url?name=<script>alert()</script>

顺利进入level2
level2:闭合标签绕过
考点:输入被包裹在<input>的value属性中,需闭合标签才能执行代码。
<input name=keyword value=" ">
<input name=keyword value=" "> <script>alert()</script> <" ">
通过手动添加"> <"进行双引号闭合,进而使得<script>alert()</script>生效
这里搜索框的test和payload的长度有关,也可以修改搜索框中的文本长度来确定payload传输位置

那我们就和上一关一样在搜索框插入payload并提交
<script>alert()</script>

输入<script>alert()</script>测试,发现<和>被转义为<和>(HTML 实体化);

利用"闭合value属性,再插入新标签:
"> <script>alert()</script> <"
(注:<"用于抵消后续的闭合符号,避免语法错误)

Level3:事件触发绕过
考点:<和>被严格过滤,需用 HTML 事件属性执行代码。
onfocus事件在元素获得焦点时触发,最常与 <input>、<select> 和 <a>标签一起使用,onfocus事件就是当输入框被点击的时候,就会触发对应的函数,然后我们再配合javascript伪协议来执行javascript代码
比如<input type='text' onfocus="myFunction()">, 这里<input>标签是有输入框的,简单来说,onfocus事件就是当输入框被点击的时候,就会触发myFunction()函数
<input name=keyword value='' onfocus=javascript:alert() ''>
那这里就会使得点击input框时,执行alert函数,这里的javascript:alert()是JavaScript伪协议,相当于onfocus="alert()"

自然而然的想到上一关的解题方法,试一试

测试发现"被过滤,但'未被过滤,用'闭合value属性;

似乎和上一关没区别,来看看上一关的payload"> <script>alert()</script> <"哦哦,细心的同学已经发现了,上一关的闭合方式是"",而这一关的闭合方式是’',所以要把单引号改为双引号,相应的payload就是
'> <script>alert()</script> <'

还是不行,观察源码发现这题value部分的符号也被实体化了,那就无法通过<>符号闭合的方式进行注入,这里就可以利用onfocus事件进行绕过,构造出payload
' onfocus=javascript:alert() '

**💖 温馨提示:**这里注意,在搜索框输入完payload点击搜索后需要在点击一下文本框,保证触发onfocus
Level4:双引号闭合与事件复用
'被过滤,需用"闭合标签。就是从level3的单引号变为双引号

熟悉的页面,基本上xss就是通过输入数据的地方进行注入,所以这里就不再一步步通过上一关的答案进行试验了,直接查看源码

先通过"> <script>alert()</script> <"闭合,发现<>符号被过滤

那么自然而然就想到onfocus事件,构造payload
" onfocus=javascript:alert() "

**💖 温馨提示:**记得搜索后点击一下文本框,保证onfocus事件能被触发
Level5:a 标签 href 伪协议
a href标签法:href属性的意思是 当标签<a>被点击的时候,就会触发执行转跳,转跳到一个网站,也可以触发执行一段js代码
<a href="https://www.baidu.com"> </a>
当点击<a>标签的时候,就会跳转到百度的网站,很多跳转链接就是基于href标签完成
将"> <a href=javascript:alert()>xxx</a> <"和<input name=keyword value"">拼接起来得到<input name=keyword value" "> <a href=javascript:alert()>xxx</a> <"">

试试上一关的payload" onfocus=javascript:alert() "

发现无法通过,那就看看源码

很明显的看到过滤了js的标签还有onfocus事件,虽然str_replace不区分大小写,但是有小写字母转化函数,所以就不能用大小写法来绕过过滤了,只能新找一个方法进行xss注入,这里我们用`a href标签法,构造payload
"> <a href=javascript:alert()>xxx</a> <"

这时候点击xxx就会跳转到href标签并执行js代码,完成本关

Level6:大小写绕过
html标签代码不区分大小写
例如
<script></script>和<sCript></sCript>而言是相同的

还是先用上一关的payload试试

发现xxx部分显示不可以点击,那来看一下源码

发现href标签也被过滤了,那试试onfocus事件,发现也被过滤了,这时基础的办法就只有大小写绕过,构造payload(任选其一就好,这里我用的第三个)
"> <a hRef=javascript:alert()>x</a> <"
" Onfocus=javascript:alert() "
"> <sCript>alert()</sCript> <"
这样就完成了

Level7:双写绕过
双拼写绕过,代码可以检测关键字进行过滤,我们可以进行关键字中间插入关键字的办法进而进行注入
比如<scr script ipt>进行关键字script过滤后就会变成<script>(一般写为<scrscriptipt>不带空格的形式,我这里是为了大家看的更方便)

这里还是用常用的payload试试,我一般用上一关的,因为xss-labs是逐渐增加难度,和上一关一般有关联"> <sCript>alert()</sCript> <"

看源码

这里发现不仅检测出了script大小写,还进行了过滤,直接不显示了,但是没事,这时候就要举出另一个常用的知识点了,那就是双写绕过,构造payload
"> <sCrsCriptipt>alert()</sCrsCriptipt> <"

这样就完成了
Level8:Unicode 编码绕过
href的隐藏属性自动Unicode解码
当在href标签用Unicode符号时,点击href会自动进行Unicode解码
比如href="&quto" 会自动解析为href="("的Unicode编码为&quto)
还是拿上一关的payload试一试,再看源码

可以发现,添加了html实体转化函数还把双引号也给实体化了, 添加了小写转化函数,还有过滤掉了src、data、onfocus、href、script、"(双引号)
但是我们能利用href的隐藏属性自动Unicode解码,我们可以插入一段js伪协议
javascript:alert()
利用在线工具进行Unicode编码得到payload(编码工具浏览器搜一下就好了,这里就不打广告了)
javascript:alert()
将这些插入href中

再点击一下友情链接即可过关
Level9:注释符绕过内容校验
/*内容*/注释js代码
老套路,看看过滤了什么,用上一关的payloadjavascript:alert()试试

为啥不合法,这里需要看一下php源码

这里的意思是当false等于false的时候(就是传入的值没有http://)就会执行if,为了防止false===false,我们需要向传入的值里面添加http://并用注释符注释掉否则会执行不了无法弹窗,让函数strpos返回一个数字,构造payload
javascript:alert()/* http:// */
为什么还是过不了,来看一下网页源码

发现这里进行了过滤,自然而然的想到level8的解法,转成Unicode编码
构造payload
javascript:alert()/* http:// */

添加完成后点击一下友情链接触发代码
Level10:隐藏参数注入
type="hidden" 隐藏类型,在页面上不可见
常用于:
传递服务器端数据到客户端
表单安全令牌(CSRF token)
会话标识
页面状态信息
type="text" 表示文本输入框并且显示
<input name="t_sort" value=" ' ' " type="hidden">和" onfocus=javascript:alert() type="'text进行拼接得到<input name="t_sort" value="'" onfocus=javascript:alert() type="'text'" type="hidden">
发现这关没有输入框,别着急,观察一下

这时候就发现了payload需要再url中传入,那我们测试一下常用的关键字" sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j
构造的payload是
url?keyword=" sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j
这时候查看一下源码

居然都被实体化了,没法子,只能看一下这关的源码了

原来还有隐藏传参方法,学到了,这里是get传参t_sort,并过滤掉了<>号,不能闭合插入标签,但是我们还能用onfocus事件,因为这里输入框被隐藏了,需要添加type=“text”,构造payload
url?t_sort=" onfocus=javascript:alert() type="'text
记得传参后点击一下文本框进行触发
Leve11:Referer 头注入
Referer是 HTTP 请求头中的一个重要字段,用于表示当前请求的来源页面 URL
主要作用
1、流量来源分析
Referer: https://www.google.com/search?q=example 网站可以知道用户是从哪个网站跳转过来的
2、防盗链保护
3、SEO 分析
4、用户行为追踪
通过referer能记录信息进行注入
来看一下源码

<input>标签有四个值,都做了隐藏处理,不难看出,第四个名为t_ref的<input>标签是http头referer的参数(就是由哪个地址转跳到这里的,http头的referer会记录有)
那我们通过bp抓包注入referer头(burp suit的使用这里就不详细说了,请自行查阅文档)
构造payload
Referer: " onfocus=javascript:alert() type="text

考虑一下http头传值,本关是referer,但接下来也有可能是其他头,如Cookie等
Level12:User-Agent 头注入
UA头(User-Agent头)是 HTTP 请求头中的一个重要字段,用于标识客户端软件的信息
本意是想通过客户软件识别身份避免爬虫等,但是由于其可以向后端传递信息,所以依然可以作为攻击位置

太明显了,这肯定是User-Agent头了,再用burpsuite抓包一下,将User-Agent头修改为我们的测试代码,先用关键字测试一下
" sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j

看一下源码,那就确定用onfocus事件,构造payload
" onfocus=javascript:alert() type="text
将其传入

别忘了最后要点击一下文本框
Level13:Cookie 注入
Cookie 头是 HTTP 请求头中的一个重要字段,用于在客户端存储和发送会话状态信息
不需要了解太多,只需要知道它是一个维持会话的作用就行(比如登录一个网页退出,一天后还可以登录,那就是cookie的作用)
查看下源码

很明显就是用cookie注入的方式,还是注入一下常见的关键字看看效果
cookie界面可以通过点击F12进入源代码格式,在点击application(有的中文界面是存储/记忆)

传入常见的参数
" sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j" sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> j
点击选中value的值,右键选择edit(某些中文页面就是编辑),传入要注入的数据,刷新一下页面就好了
那我们构造payload并传输
" onclick=alert() type="text

再刷新一下,点击文本框就好了
Level14:Exif XSS(了解即可)
这关主要涉及的漏洞是exif xss漏洞。exif是可交换图像文件格式(英语:Exchangeable image file format,官方简称Exif),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。
我们右键图片选择属性,点击详细信息就可以看到exif的相关属性。
我们可以在这些属性里面添加XSS代码,然后上传图片实现弹窗。
由于目标URL无法访问我们也无法上传图片。

这题的网站崩了,只能跳过了(真不是作者划水啊)
Level15:ng-include 文件包含
ng-include指令就是文件包涵的意思,用来包涵外部的html文件,如果包涵的内容是地址,需要加引号
不用记住太复杂的东西,就记住可以包含地址进行跳转
这里不能包涵那些直接弹窗的东西如<script>,但是可以包涵那些标签的东西比如<a>、<input>、<img>、<p>标签等等,这些标签是能需要我们手动点击弹窗的
onmoouseover标签,表示鼠标移动上去时会触发事件
比如<img src=1 onmouseover=alert()>,当鼠标移动到1.img的时候,就会触发alert()函数弹窗
(相应的还有onmousedown属性,大家可以了解一下)
看眼源码

那就直接转到第一关最简单的一关呗
构造payload(这里注意要包含url所有地址,包括http/https)
?src='url/level1.php'
这样你就会惊奇的发现跳转到第一关了,嘿嘿

这时候大家可能就想说直接包含level1的payload就行了呗,很容易构造下面的payload
url?src='url/level1.php?name=<script>alert()</script>'
但是发现不行啊,注意,这里不能包涵那些直接弹窗的东西如<script>,但是可以包涵那些标签的东西比如<a>、<input>、<img>、<p>标签等等,这些标签是能需要我们手动点击弹窗的
那我们就讲一个新姿势吧onmoouseover
?src='url/level1.php?name=<img src=1 onmouseover=alert()>'
把payload输入并移动到图片就好了
Level16
对于html标签而言,空格和回车没有区别
比如代码<svg%0Aonload=alert(1)>
<svg
onload=alert(1)>
运行的结果是相同的

看一下get的传参test,是payload的输入部分,输入一下常见的关键字
?keyword=" ' sRc DaTa OnFocus OnmOuseOver OnMouseDoWn P <sCriPt> <a hReF=javascript:alert()> j
再看一下源码

这里先是将字母小写化了,再把script替换成空格,最后将空格给实体化,想尝试一下p标签<p οnmοusedοwn=alert()>abc</p>,谁知道也将/给替换成了空格
空格可以用回车来代替绕过,回车的url编码是%0a,再配合上不用/的<img>、<details>、<svg>等标签
将空格替换成回车的url编码(%0A),构造payload
?keyword=<svg%0Aonload=alert(1)>

Level17:Flash XSS(了解即可)
这些关卡依赖 Flash 插件(目前主流浏览器已不再支持),核心思路是通过 Flash 参数注入事件(如onclick)。实际测试中可忽略,重点掌握前 16 关的思路。

这题的解法很简单,首先得用一个支持flash插件的浏览器打开本关(打开后会有个图片出来的,不支持flash插件浏览器就没有),如果不想下载的话,自己去后端改一下也行,将后端第十七关的代码(level17.php)指向的swf文件改为index.png
看一下源码

有个embed标签的区域在,其实用不用swf文件都一样的,主要是区域,接着我们构造payload
?arg02= onclick=alert()
在url上插入就好了
Level18::Flash XSS(了解即可)
换个支持flash插件的浏览器,Cent Browser。
看一下源码
源码跟上关差别不大,就是换了个swf文件,我们直接测试一波过滤了啥,构建payload
?arg02=" ' sRc DaTa OnFocus OnmOuseOver OnMouseDoWn P <sCriPt> <a hReF=javascript:alert()>;

搞了个html实体化函数,也没过滤啥,感觉跟上关一样,用事件触发属性即可(如onmouse系列、onfocus、onclick等)直接上payload
?arg02= onmousedown=alert()
再点一下embed标签区域
四、总结
本文主要讲解了xss漏洞的各种绕过攻击的手法,另外提一嘴xss漏洞主要用于钓鱼攻击,在企业src漏洞挖掘的时候,xss漏洞有很多厂商是不收的,这取决于你怎么和厂商沟通,在我们的课程里也会讲解,或者关注我们后续的文章
五、🎯 网络安全学习资源推荐
觉得文章对你有帮助?想获取更多实战干货?
我们为你准备了一套 「从零到一的网络安全学习资料包」,包括:
- 🔥 红队攻防实战手册 - 内网渗透、漏洞利用、权限提升
- 📚 网络安全学习路线图 - 零基础入门到就业完整路径
- 💼 最新网络安全面试题 - 大厂真题+面试技巧
- 🛠️ 渗透测试工具包 - 常用工具+使用教程
- 🎯 靶场搭建全套方案 - DVWA、SQLi-Labs等实战环境
如何获取?
- 微信搜索公众号:
[智榜样网络安全学习中心] - 关注后回复关键词:「资料领取」
- 即可免费领取全套学习资料
💡 适合人群:网络安全初学者、转行人员、在校学生、想要提升实战能力的从业者
我们在网络安全培训领域深耕多年,专注红蓝对抗实战与就业指导,帮助数百名学员成功入行!

更多推荐
所有评论(0)