XSS基础
XSS(跨站脚本攻击)基础
1. XSS的原理
- 通过攻击者向Web页面里插入恶意的Script代码,导致当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的,XSS是针对用户层面的攻击。
2. XSS的分类
- XSS分为存储型、反射型、DOM型三种。
2.1 存储型XSS
- 存储型XSS又叫持久型XSS,它是通过攻击者将恶意脚本存储到服务器中,之后的每一位用户(受害者),浏览到包含该内容的页面时,存储在数据库中的恶意代码将被数据库读取并返回到浏览器上执行。
- 如下图所示这里我们通过DVWA靶场简单难度(对我们用户输入没有任何的过滤)进行简单的测试。
- 这里可以看到,这个模块模拟的是一个留言板的功能,那对应到存储型XSS,因为一个网站所实现的留言或评论功能中,用户的留言是存储在数据库中的,在我们发布留言之后,网页就会出现弹窗,又因为留言是存储在数据库中的,所以当我们每次访问这个页面,弹窗也都会出现。
2.2 反射型XSS
- 反射型XSS又叫做非持久型XSS,它是通过攻击者构造恶意代码的URL,通过诱骗用户点击该URL,从而在用户的浏览器中执行服务器返回页面中包含的恶意代码。
- 如下图所示,查看源码。
- 这串代码 对攻击者的输入没有过滤导致攻击者可以构造恶意的URL,当用户访问后,代码中的echo将恶意的代码返回到用户的浏览器上。所以我么可以构造。
- 弹窗也随之出现。
2.3 DOM型XSS
- DOM型XSS不经过后端,是通过URL传入参数去控制触发的,它的操作其实与反射型大同小异。
- 如图,我们在 URL 中传入参数的值,然后客户端页面通过 js 脚本利用 DOM 的方法获得 URL 中参数的值,再通过 DOM 方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。所以,我们就可以在我们输入的参数上做手脚了。
2.4 详细对比
| 特性 | 反射型 XSS | 存储型 XSS | DOM型 XSS |
|---|---|---|---|
| 恶意代码存储位置 | URL参数、POST数据中,不存储在服务器 | 服务器数据库(如评论、帖子、用户名) | 不存储在服务器,可能存在于URL片段(#后面)或客户端本地 |
| 触发过程 | 1. 攻击者构造含恶意代码的URL 2. 诱骗用户点击该URL 3. 服务器返回的页面中包含该恶意代码 4. 用户浏览器执行 |
1. 攻击者将恶意代码提交到服务器并保存 2.用户正常浏览包含该内容的页面(如评论页) 3. 服务器从数据库读取恶意代码并返回 4. 用户浏览器执行 |
1. 攻击者构造一个特殊的URL(可能含恶意数据) 2. 诱骗用户点击 3. 用户浏览器接收到安全的页面(来自服务器) 4. 页面上的前端JS不安全地操作了DOM,将URL中的恶意数据作为代码执行 |
| 危害范围 | 较低,需要诱导用户点击特定链接 | 非常高,所有访问被感染页面的用户都会中招 | 中等,需要诱导用户点击特定链接 |
| 持久性 | 一次性,链接关闭即失效 | 持久,只要恶意数据还在服务器上,就一直有风险 | 一次性,通常链接关闭即失效 |
| 与服务器的交互 | 有交互。恶意代码经服务器“反射”回来 | 有交互。恶意代码存储在服务器,并由服务器下发 | 可能无交互。攻击流程完全不经过服务器处理(恶意负载在URL片段#中时,服务器收不到该部分) |
| 关键区别点 | 恶意代码由服务器直接返回在响应体中 | 恶意代码存储在服务器数据库中 | 恶意代码的执行是前端JS处理不当的结果,服务器响应可能是完全正常的 |
3. XSS的攻击Payload
- 所有标签的
>都可以用//代替,例如<script>alert("XSS")</script//。
3.1 利用常见HTML标签的事件处理器
- 这是最主流的一类。许多HTML标签支持事件属性(如
onclick,onerror,onload,onmouseover),当事件触发时即可执行JS。
3.1.1 <script>标签
他是XSS最直接的Payload,可以引入外部的JS代码也可以将JS代码插入到它中间。
1
<script>alert("XSS")</script>
- 弹出
XSS。
1
<script>alert(/XSS/)</script>
- 弹出
XSS。
1
<script>alert(1)</script>
- 弹出
1,数字可以不需要引号。
1
<script>alert(document.cookie)</script>
- 弹出cookie值。
1
<script src="x"></script>
- 引入外部的XSS,代指脚本地址。
- 弹出
3.1.2 <img>标签
Payload:
<img src="x" onerror="alert("XSS")">原理:将一个无效的URL
x赋值给src属性。当图片加载失败时,onerror事件被触发,执行其中的JS。
3.1.3 <svg>标签
Payload:
<svg onload="alert("XSS")"原理:SVG本身是基于XML的,浏览器会将其内容作为文档对象模型的一部分来解析,
onload事件在SVG加载完成后立即触发。
3.1.4 <body>标签
Payload:
<body onload="alert("XSS")"原理:如果能控制
<body>标签的属性(例如注入到模板中),可以利用其onload事件。
3.1.5 <input>标签
Payload:
<input type="text" onfocus="alert("XSS")" autofocus>原理: 利用
onfocus事件,当输入框获得焦点时触发。autofocus属性使其自动获得焦点。也可以结合onmouseover等事件。
3.1.6 <a>标签
Payload:
<a onmouseover="alert("XSS")">悬停在这里</a>原理: 利用
onmouseover事件,当用户将鼠标悬停在链接上时触发。
3.1.7 <details>标签
Payload:
<details open ontoggle="alert("XSS")">原理:
ontoggle事件在<details>元素打开或关闭时触发。open属性确保它一开始就是打开的,从而立即触发事件。
3.2 利用不需要用户交互的标签和属性
- 这类Payload在页面加载时自动触发,无需用户点击或悬停。
3.2.1 <iframe>标签
- Payload:
<iframe src="javascript:alert('XSS')">
- 原理:
iframe的src属性可以接受javascript:伪协议。
3.2.2 <embed>或 <object>标签
- Payload:
<embed src="javascript:alert('XSS')"> - 原理: 类似于
iframe,这些用于嵌入外部资源的标签也可以执行 JavaScript 协议。
3.2.3 <video>/ <audio>标签
- Payload:
<video><source onerror="alert('XSS')"></video>
- 原理: 和
img标签的onerror原理类似,当媒体资源加载失败时触发。
3.2.4 <form>标签
- Payload:
<form action="javascript:alert('XSS')"><input type="submit">
- 原理: 表单的
action属性可以设置为 JavaScript 协议。当用户点击提交按钮时触发。
3.2.5 <meta>标签(需要可注入到<head>中)
- Payload:
<meta http-equiv="refresh" content="0; url=javascript:alert('XSS')">
- 原理: 利用
meta标签进行重定向到 JavaScript 协议。
3.3 利用 javascript:伪协议
这种载荷主要用于可以设置URL的属性。
Payload:
<a href="javascript:alert('XSS')">点击我</a>原理: 当用户点击这个链接时,浏览器会执行
href属性中的 JavaScript 代码。
4. XSS可以插入在哪里
- 无论用户输入被放置在哪个HTML上下文中,攻击者的目标都是一致的:通过输入特定的闭合字符(如
">,-->,</style>等)来提前结束当前的上下文,然后紧接着注入可执行的JavaScript代码
4.1 用户输入作为<script>标签内容
示例:
1
<script>var input = "用户输入";</script>
攻击思路:逃逸出JS字符串的上下文,直接执行代码。
Payload:
"; alert("XSS"); //最终效果:
1
<script>var input = ""; alert("XSS"); //";</script>
攻击原理: 用
"闭合前引号,;结束原语句,然后注入恶意代码,//注释掉后续内容。
4.2 用户输入作为HTML注释的内容
示例:
1
<!-- 用户输入 --->
攻击思路:提前闭合注释符号,讲后续内容变为可以执行的HTML。
Payload:
---> <script>alert("XSS")</script> <!--最终效果:
1
<!-- ---> <script>alert("XSS")</script> <!-- --->
攻击原理:
-->闭合当前注释,注入恶意标签,<!--平衡掉页面原有的结束注释。
4.3 用户输入作为HTML标签的属性名
示例:
1
<div 用户输入="value">内容</div>
攻击思路:闭合当前标签,注入新的标签。
Payload:
> <script>alert("XSS")</script> <div a最终效果:
1
<div > <script>alert("XSS")</script> <div a="value">内容</div>
攻击原理:
>闭合当前标签,注入脚本,新增一个标签属性名以”吞掉”原页面后续的="value"。
4.4 用户输入作为HTML标签的属性值
示例:
1
<div id="用户输入">内容</div>
攻击思路: 逃逸出属性值上下文,闭合标签。
Payload:
"> <script>alert("XSS")</script> <div a="" onclick="alert('XSS')
最终效果1(闭合标签):
1
<div id=""> <script>alert("XSS")</script> <div a="">内容</div>
最终效果2(事件处理器):
1
<div id="" onclick="alert('XSS')">内容</div>
攻击原理:
- 方式1:用
">闭合属性值和当前标签,然后直接注入脚本。 - 方式2:用
"闭合属性值,然后添加一个带JS代码的事件属性(如onclick)。
4.5 用户输入最为HTML标签的名字
示例:
1
<用户输入 class="header">标题</用户输入>
攻击思路: 注入一个可执行脚本的标签,或闭合无效标签。
Payload:
script><script>alert("XSS")</script><b最终效果:
1
<script></script> <b class="header">标题 </script><script>alert("XSS")</script><b>
攻击原理: 输入一个合法的HTML标签(如
script)来执行代码,或者使用>闭合一个无效的开始标签<>,然后注入脚本。后续的<b用于平衡结构。






