Level1
url中的内容会回显。
所以我们可以直接把test改为经典弹窗语句<script>alert('xss')</script>
接下来,页面就会执行此js语句,出现弹窗,显示进行下一关,表示我们通关成功。开不开心,意不意外,就是这么简单。
但我们不能骄傲,来,分析一下这一关的源代码
<!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>
这里重写了alert()
方法,所以会连通下一关。
echo "<h2 align=center>欢迎用户".$str."</h2>";
这里没有过滤直接输出接收到的字符串,那么用户恶意输入,当然也会执行,所以构成了xss漏洞。
Levle2
我们可以看到,输入经典语句之后,它直接输出到页面上,并没有弹窗。(可以看到url,仍然是get传参)
接下来,我们按F12查看下源代码
发现被htmlspecialchars()
函数做了特殊处理(htmlspecialchars()
函数的 功能是把HTML实体转换回字符),但是inout
标签中并没有被做处理。所以我们可以从这里入手。
构造闭合标签,并注释掉后边的,"> <script>alert('xss')</script> //
然后页面就又给我们乖乖弹窗了
分析下源代码
<!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.'">
<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>
`
```html
htmlspecialchars()
函数把预定义的字符转换为 HTML 实体。
预定义的字符是:
-
& (& 符号) &
-
” (双引号) ",除非设置了 ENT_NOQUOTES
-
’ (单引号) 设置了 ENT_QUOTES 后, ’ (如果是 ENT_HTML401) ,或者 ’ (如果是 ENT_XML1、
ENT_XHTML 或 ENT_HTML5)。 -
< (小于) <
-
(大于) >
如需把特殊的 HTML 实体转换回字符,请使用 htmlspecialchars_decode() 函数。
分析源码,果然把页面回显出的get接收到的字符串进行了实体化编码处理,而value处的是直接不做处理输出的,最终造成了xss漏洞。
level 3
输入测试语句之后,发现这关value处也被htmlspecialchars()
处理了。
我们输入' " < > /
,测试一下哪些被处理了,哪些没被处理。
发现双引号尖括号都被处理了,而单引号,斜杠没被处理。恰巧此处value
属性的闭合标签是单引号闭合,所以我们构造闭合。
xss' onclick='javascript:alert(/xss/)
,输入进行搜索,之后在输入框点击一下即可触发弹窗。
这里用到了javascript
伪协议,下面简单说明一下把。
javascript
:这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行。
将javascript代码添加到客户端的方法是把它放置在伪协议说明符javascript:后的URL中。这个特殊的协议类型声明了URL的主体是任意的javascript代码,它由javascript的解释器运行。如果javascript:URL中的javascript代码含有多个语句,必须使用分号将这些语句分隔开。
javascript URL还可以含有只执行动作,但不返回值的javascript语句。
javascript:alert("xss")
装载了这种URL时,浏览器仅执行其中的javascript代码,但由于没有作为新文档来显示的值,因此它并不改变当前显示的文档。
最后来看一波源码怎么写的。(只放php代码吧)
<?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>";
?>
<center><img src=level3.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
这里我们可以看到htmlspecialchars
默认是不处理单引号的。得设置相关参数才会处理。
所以我们才构造出了上述payload.