XSS攻击, XSS分类, 测试方法, 防御方法
对于所有类型的XSS渗透测试,确保您有适当的权限进行测试,以避免非法或不受欢迎的行为。
此外,渗透测试工具和框架,如Burp Suite
或OWASP ZAP
,可以帮助自动化一些测试任务并识别潜在的漏洞点。
一, XSS分类
1. 反射型XSS:
恶意脚本不会被存储在目标网站上,而是通过URL或其他方式传递。
受害者通常会点击一个恶意链接,该链接会引导他们到目标网站,并在URL中传递恶意脚本。
由于目标网站不正确地处理输入,恶意脚本会被执行。
2. 存储型XSS:
恶意脚本被存储在目标服务器上(例如,数据库中),当其他用户访问某些页面时,脚本会被加载并执行。
例如,如果一个论坛的帖子内容没有经过适当的过滤和转义,攻击者可以发布一个带有恶意脚本的帖子,当其他用户查看该帖子时,恶意脚本会在他们的浏览器中执行。
3. DOM型XSS:
这是一种更加高级的XSS攻击,涉及到网页的DOM操作。
攻击者利用网页脚本未正确处理用户输入的事实,通过DOM操作来注入并执行脚本。
二, 测试方法
对于XSS的不同类型,使用的渗透测试方法可能会有所不同。以下是针对反射型、存储型和DOM型XSS的基本渗透测试方法:
-
反射型XSS:
-
找寻目标:首先,您需要找到应用程序中所有接受用户输入并在响应中反映这些输入的地方。这通常包括URL参数、POST数据和其他输入向量。
-
测试注入 :尝试插入各种恶意脚本载荷,看看它们是否在响应中原样反映出来。例如,尝试插入
<script>alert(1)</script>
或简单的HTML标签,如<b>test</b>
来查看它们是否有效。 -
绕过过滤器:如果应用程序具有某种输入过滤或转义机制,尝试使用不同的编码、大小写或其他技巧来绕过它们。
-
-
存储型XSS:
-
找寻目标:查找应用程序中的所有地方,可以提交数据并在其他地方再次显示这些数据,例如评论、论坛帖子、用户资料等。
-
测试注入:与反射型XSS相似,尝试插入恶意载荷,但在这里,您希望这些载荷能够被存储并在后续的请求中再次呈现给用户。
-
检查后端:存储型XSS通常涉及到后端数据库或其他存储机制。了解后端如何处理和存储数据可以帮助您更好地定制攻击。
-
-
DOM型XSS:
-
分析JavaScript:此类型的XSS与前端JavaScript代码直接相关。检查代码中如何处理用户输入和如何将数据动态地插入到DOM中。
-
测试注入:找到应用程序接受但不发送到服务器的输入向量,例如URL的hash部分、localStorage或其他客户端存储。尝试修改这些值并观察应用程序如何响应。
假设一个网页有以下JavaScript:
jsvar input = document.getElementById('userInput').value; document.getElementById('outputDiv').innerHTML = input;
上面的代码简单地获取一个输入框的值,并将其作为HTML插入到一个div中。这就创建了一个DOM型XSS的机会。
如果攻击者可以诱使用户在输入框中输入恶意内容,例如:
js<img src=x onerror=alert('XSS')>
当该输入被赋值给
outputDiv
的innerHTML
属性时,会触发onerror事件,执行alert('XSS')。- 使用开发者工具:浏览器的开发者工具,特别是JavaScript控制台,对于测试和识别DOM型XSS非常有用。
-
三, 防御方法
1. 适当地转义输出:
当将数据插入HTML、JavaScript、CSS或其他Web上下文时,确保数据被适当地转义。
对于HTML内容,使用HTML实体转义特殊字符,如 < > &
"等.
当你从用户那里接收到输入,并且打算在HTML中显示该输入时,使用 htmlspecialchars()
可以帮助确保内容安全地显示,而不会触发XSS攻击。
对于JavaScript内容,确保所有动态数据在插入脚本之前都被适当地转义或编码。
使用开发框架或库提供的安全方法来插入动态内容。
以下是htmlspecialchars()
如何转换一些特殊字符的示例:
html
< 转换为 <
> 转换为 >
" 转换为 "
& 转换为 &
php
$user_input = $_GET['input'];
safe_output = htmlspecialchars($user_input, ENT_QUOTES, 'UTF-8');
echo "<div>" . $safe_output . "</div>";
2. 验证和过滤输入:
所有从用户、第三方API或其他不受信任的来源接收的数据都应该进行严格的验证。
使用白名单方法验证输入,而不是黑名单方法。这意味着只允许预期的输入,而拒绝所有其他输入。
3. 采用开发框架和库的安全功能:
许多现代的Web开发框架和库,如React Vue.js Angular
,都提供了内置的XSS防护机制。
确保您了解并正确使用这些功能,同时保持框架和库的版本是最新的。
4. 使用内容安全策略(CSP):
CSP
是一种浏览器特性,允许服务器指定哪些内容可以执行和加载。
通过限制只允许从受信任的来源加载脚本,可以有效地减少XSS的风险。
使用非常严格的CSP策略,例如禁止内联脚本,并仅从可信的源加载外部脚本。
四, 绕过方法
1. 大小写绕过
某些过滤器可能只检查小写版本的危险字符串,如<script>
。攻击者可以通过使用大写或大小写混合,如<ScRiPt>
,来绕过这些过滤器。
2. html实体绕过
HTML实体是一种表示某些字符的方式,这些字符在HTML中有特殊的意义。
例如,< 和 > 用于定义标签,但它们也可以使用HTML实体 <
和 >
来表示。
除了使用已命名的实体(如<
代表 <
)外,还可以使用数值来表示字符,这些数值可以是十进制或十六进制。这种数值表示的方法通常被称为字符实体引用
或数值实体引用
。
十进制实体编码:使用基于10的数值系统,以 &#
开始,然后是字符的十进制码,最后以 ;
结束。
例如: <
的十进制ASCII值是60
。因此,它的十进制实体编码是<
十六进制实体编码:使用基于16的数值系统,以 &#x(注意小写的x)
开始,然后是字符的十六进制码,最后以 ;
结束。
例如: <
的十六进制ASCII值是3C
。因此,它的十六进制实体编码是<
。
2.1 基本实体绕过
假设一个应用过滤或转义了 < 和 > 字符,但没有处理对应的HTML实体:
js
<script>alert(1)</script>
如果浏览器解析了这些实体,并执行了其中的脚本,那么XSS攻击就成功了。
2.2 十进制和十六进制实体编码
除了基本的实体外,攻击者还可以尝试使用十进制或十六进制实体编码来绕过过滤:
js
<script>alert(1)</script>
2.3 利用浏览器的解析行为
某些浏览器在解析不完整的HTML实体时可能会产生不可预测的行为。例如,某些浏览器可能解析以下代码:
js
<script>alert(1)</script
3. 利用DOM事件
即使<script>
标签被过滤,攻击者仍可能尝试使用事件处理器,如 onmouseover、onload、onerror等,插入恶意代码。
4. 使用 data:URL
data: URI方案允许你直接在URL中嵌入数据。
对于XSS攻击,这可能会被用作<img>, <script>, <iframe>
等标签的src
属性值,以执行JavaScript。
html
<iframe src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'
onload='alert(1)'></svg>"></iframe>
在上面的示例中,一个SVG图像数据被嵌入到 <iframe>
标签的src属性中,并且当SVG加载时,它会触发onload事件执行JavaScript。
5. SVG 标签
SVG (Scalable Vector Graphics) 是一个XML格式,用于描述二维图形。
由于它基于XML,可以包含事件处理程序或其他交互性元素,如JavaScript。
html
<svg onload="alert('XSS')"></svg>
在上述示例中,SVG图形包含一个onload事件,当SVG元素加载到页面中时,会执行alert('XSS')代码。