xss-labs通关技巧

level 1(script弹窗)

查看url:http://localhost/xss-labs-master/level1.php?name=1

显示页面如下:

image-20250104155428748

此时把name参数改为 <script>alert('hello')</script>

页面显示如下:

image-20250104155819491

level 1完成。

level 2(尖括号闭合绕过)

查看url: http://localhost/xss-labs-master/level2.php?keyword=test&submit=%E6%90%9C%E7%B4%A2

页面显示如下:

image-20250104160038542

先照常输入 <script>alert('hello')</script>

显示结果如下:

image-20250104162443394

此时查看网站源代码:

image-20250104162601101

发现输入的内容被嵌入value属性中,无法被正常解析,那么此时把前后的双引号闭合即可。

输入 "> <script>alert('hello')</script> <",显示结果如下:

image-20250104162858406

level 2完成。

level 3(单引号onfocus事件绕过)

我先在输入框中输入 sss

然后照常查看一下网站源码:

image-20250104163451105

发现value的双引号被换成了单引号,按照level 2的思路,我们输入 '> <scripr>alert('hello')</script> <'

页面显示如下:
image-20250104163701090

我们再次查看网站源码:

image-20250104163744372

发现输入的特殊符号被html实体化了,此时我们查看一下源码:

image-20250104164253744

发现我们输入的字符串被htmlspecialchars函数,这里补充一点:

htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。

预定义的字符是:&, ", ’ ,< ,>

由于<>都被实体化了,那么此时我们可以采用onfocus事件来进行绕过,此时我们输入 ' onfocus=javascript:alert('hello') ',然后再次点击输入框就可以触发:

image-20250104170204722

level 4(双引号onfocus事件绕过)

首先查看初始网页:

image-20250104201310860

然后查看网页源码:

image-20250104201518408

发现还是单引号,尝试在输入栏中输入 "> <script>alert('hello')</script> <",再次查看网源码:

image-20250104201731626

发现 <>被过滤,既然如此,那我们再次使用onfocus事件来绕过。在输入框中输入:" onfocus=javascript:alert('hello') "

image-20250104202151322

level 4完成。

level 5(a href标签法绕过)

按照level 4的思路,我们首先还是尝试利用onfocus事件来进行绕过,在输入框中输入 " onfocus=javascript:alert('hello') ",页面显示如下:

image-20250104202627456

查看网页源码,如下所示:

image-20250104202532235

发现onfocus被过滤,说明此时onfocus事件不可用来绕过,那么此时我们来查看一下此题的源代码:

image-20250104203330447

观察红框中的部分,发现在接受keyword参数传入的字符串之后,会把字符串中的 <script替换为 <scr_ipt、把字符串中的 on替换为 o_n,同时strtolower函数也会把输入的字符串全部转换为小写的,所以也无法使用大小写转换来绕过。那么我们此时使用另一种方法:a href标签法

相关知识点补充如下:

image-20250104204352905

由于是标签,所以我们需要闭合前面的标签,因此在输入框中输入 "> <a href="javascript:alert('hello')">xxx</a> <",显示页面如下:

image-20250104205523651

level 5成功完成。

level 6(大小写转换绕过)

同level 5一样,在输入框中输入 "> <a href="javascript:alert('hello')">xxx</a> <",页面显示如下:

image-20250104205724148

查看一下网页源码:

image-20250104210009287

观察页面源码发现href被过滤,由于不知道还过滤了哪些关键字,这里我直接查看源代码(实战情况下应该是看不了的):

image-20250104210555933

观察源代码发现过滤了 <script on src data href这几个关键字,由于源码中没有对大写进行过滤,所以我们尝试输入 "> <a hRef="javascript:alert('hello')">xxx</a> <",将 href转换为 hRef来尝试绕过:

image-20250104210911236

绕过成功,level 6成功完成。

level 7(双拼写绕过删除函数)

首先先查看网页的源码:

image-20250104211146034

拼接的符号是双引号的,那么先输入 "> <script>alert('hello')</script> <"看看,页面显示如下:

image-20250104211323338

应该是被过滤了,查看一下网页的源码:

image-20250104211411375

发现 script被替换为空了,在尝试一下大小写转换,输入 "> <sCript>alert('hello')</scRipt> <"看看,发现页面并没有变化,所以应该是都转换为小写了,既然如此,我们尝试双写绕过,在输入框中输入:"> <scrscriptipt>alert('hello')</scrscriptipt> <",页面显示如下:

image-20250104212116091

level 7成功完成。

此时我们再查看一下源代码:

image-20250104211514691

与猜想的差不多,因此使用双写可以使得一个 script被置换回空,但是我们还有前后的字符拼接之后还会构成一个新的 script,因此能够成功绕过。

level 8(href属性自动解析unicode编码)

还是老样子,进入页面之后,我们首先常规方法测试一下,输入 "> <script>alert('hello')</script> <"

image-20250105155613436

发现并没有什么变化,此时我们查看一下网站源代码:

image-20250105155825489

发现一个a href标签,此时我们尝试直接输入 Javascript:alert('hello')尝试一下,然后再次查看页面的源代码,发现 javascript也被过滤了,后面尝试了一下大小写绕过也不行。此时没办法了,我们查看一下源代码:

image-20250105161249971

查看源码,发先之前可利用的方法全部都被过滤了,所以行不通了。这时我们尝试一个新方法,那就是href属性会自动解析unicode编码。对 javascript:alert('hello')进行unicode编码,结果为 &#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#104;&#101;&#108;&#108;&#111;&#39;&#41;,输入输入框中后,点击“友情链接”,即可触发。

image-20250105161736443

level 8成功完成。

level 9(利用javascript/**/注释饶过)

按照惯例,我们先输入 "> <script>alert('hello')</script> <"看看,页面显示如下:

image-20250105164021046

发现没啥反应,看看网站源代码,发现直接给我们提示链接不合法,我们尝试 javascript:alert('hello'),发现结果也是一样:

image-20250105164251634

此时没有思路了,我们再来看看源代码:

image-20250105164708423

查看源代码后发现,除了上半部分的常规的过滤之外,下半部分(红框中)还需要我们输入的字符串包含 http://才可以,那么我们此时输入 &#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#104;&#101;&#108;&#108;&#111;&#39;&#41;/* http:// */,把后面的http://注释掉,否则无法执行

image-20250105170823451

level 9成功完成。

level 10(隐藏参数及hidden的绕过)

查看页面,发现没有输入栏,所以直接在url栏进行输入,输入 " sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> &#106;测试一下过滤了哪些关键字。

image-20250105184810437

查看网站源代码:

image-20250105184855512

发现都被html实体化了,那我们这里再查看一下源码:

image-20250105185241248

这里可以看到其实get是有传递两个参数的,只是显示出来的只有keyword这个参数,还有一个t_sort参数需要我们手动输入,然后t_sort参数过滤了“>”和“<”参数,所以我们只需要闭合input标签,然后创建一个a href标签就可以了,由于标签被隐藏了,所以说要输入 type="text",尝试输入: " onfocus=javascript:alert('hello') type="text,注意这是t_sort参数的值。

为什么可以看见输入框?

浏览器会忽略第一个 type="text",因为第二个 type="hidden" 是最后一个生效的属性,所以下面这个 <input> 最终会被当作隐藏的输入框。

然而,由于存在 onfocus="javascript:alert('hello')",浏览器可能在尝试触发 onfocus 事件时,为了允许触发事件,临时将这个隐藏的输入框显示出来。

image-20250105190301897

level 10成功完成。

level 11(请求头referer传递)

进入页面没有思路,看一下网站源代码:

image-20250106090641981

发现名为t_ref标签传入的参数值为level 10的地址,那么猜测传递的就是http报文头中的referer字段。按理来说我们可以使用burpsuit抓包修改一下referer的值,为了验证我们的猜想,我们直接先看一下源代码:

image-20250106091000610

和我们猜想的一样,那么此时我们来对页面进行抓包,然后修改referer参数值为 " onfocus=javascript:alert('hello') type="text

image-20250106092207132

返回网站页面,触发弹窗成功:

image-20250106092335106

level 11成功完成。

level 12(请求头user-agent传递)

按照惯例,直接查看网站源代码:

image-20250106092659221

发现有一个值为浏览器数据的参数值,猜测应该和上一关类似,只不过这一关变成了修改ua参数值,那么我们此时来抓包看看,然后修改user-agent参数为我们需要的值,放包:

查看页面信息,弹窗成功:

image-20250106093229201

level 12成功完成。

level 13(请求头cookie传递)

查看网站源代码:

image-20250106093517106

发现都被隐藏了,不知道如何下手,这时我们查看一下源代码:

image-20250106093703480

可以发现,此时需要我们修改请求头中cookie的值来传递我们需要的值,还是一样,转包修改一下cookie的值,把其中user的值改为我们想要传递的值,放包:

image-20250106093926484

此时查看页面,成功弹窗:

image-20250106093958111

level 13成功完成。

level 14(exif xss漏洞)

exif xss漏洞,由于网站本身的问题,这里不做过多阐述,知道是啥漏洞就好。

level 15 (ng-include文件包含,无视html实体化)

进入15关,查看页面信息:

image-20250107173230195

查看页面源代码:

然后看到了一个我们陌生的东西:ng-include,这里补充一下:

ng-include 指令用于包含外部的 HTML 文件。

包含的内容将作为指定元素的子节点。

ng-include 属性的值可以是一个表达式,返回一个文件名。

默认情况下,包含的文件需要包含在同一个域名下。

如果包涵的内容是地址,需要加引号

我们尝试包含一下level 1的内容,输入 ?src='level1.php',返回页面如下:

image-20250107174143379

这里再次查看一下过滤了哪些内容

?src=" ' sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> &#106;

image-20250107174453003

发现特殊符号还是被html实体化了,没有删掉东西,所以不影响我们接下来的操作,我们可以包涵第一关并让第一关弹窗(注意,这里不能包涵那些直接弹窗的东西如<script>,但是可以包涵那些标签的东西比如<a>、<input>、<img>、<p>标签等等,这些标签是能需要我们手动点击弹窗的),这里我们使用img标签。

输入内容:?src='level1.php?name=<img src=1 onmouseover=alert('hello')>',返回页面如下(鼠标放在图片上方时):

为什么这时候html实体化不管用了呢?

因为htmlspecialchars() 只对标签内容进行转义,对于嵌入在标签属性中的 JavaScript 代码并没有特别的处理。它的目标是转义 <>&"' 等字符,但如果攻击者将恶意代码嵌入事件属性中(例如 onclick="alert('XSS')"),这些属性的值并不会被转义为安全的内容。

image-20250107175419020

最后,我们来看一下源代码,此时的htmlspecialchars()就没有用处了:

image-20250107192433704

level 15成功完成。

level 16(回车替代空格绕过)

按照惯例,这里查看一下过滤了哪些内容:?keyword=" ' sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> &#106;

查看页面源码:

image-20250107193809525

查看页面:

image-20250107193836878

大概就是把空格实体化了,然后全部都转换为小写的字母,然后把script给替换成空格了,那我这边尝试一下直接插入一个新的标签试一下:<img src=1 onmouseover="alert('hello')">,发现还是不行,没办法了,看一下源码:

image-20250107194619909

既然空格都被过滤掉了,那么这里我尝试使用回车来尝试绕过,由于url栏中无法直接输入回车,那么我使用url编码 %0a来代替回车符号,那么此时我这里输入 <img%0asrc=1%0aonmouseover="alert('hello')">尝试一下,页面显示如下:

image-20250107195049729

level 16成功完成。

level 17(浅浅了解一下.swf文件)

还是老样子,输入 " ' sRc DaTa OnFocus <sCriPt> <a hReF=javascript:alert()> &#106;看一下过滤了哪些:

image-20250107195656455

发现还是进行了实体化操作,由于我的浏览器不支持.swf后缀的文件(flash插件文件),所以我修改为 index.png来查看原来的页面:

image-20250107200352323

由于只是被html实体化了,所以这里我直接尝试输入 ?arg02= onmouseover=alert('hello') ,显示成功:

image-20250107201058196

level 17成功通过。

level 18(浅浅了解一下.swf文件)

尝试一下过滤了哪些,还是输入: " ' sRc DaTa OnFocus OnmOuseOver OnMouseDoWn P <sCriPt> <a hReF=javascript:alert()>;,发现还是进行了html实体化:

image-20250107202242441

不多说了,和上一关一样,就是换了一个.swf文件:

image-20250107202528406

level 18成功完成。

level 19(了解Flash xss)

查看网站源码,与前两个不同的是多了一对双引号,由于被实体化了,导致无法像前两关一样执行:

image-20250107203643772

本题涉及到url的反编译,就不过多阐述了,这里直接上payload:

?arg01=version&arg02=<a href="javascript:alert()">here</a>

level 20(了解Flash xss)

这边也是类似,反编译,直接上payload:

?arg01=id&arg02=xss\"))}catch(e){alert(1)}//%26width=123%26height=123

对于level 19和level 20,有需要的可以看一下这位大佬的文章:flash xss