XS-Search/XS-Leaks
使用 Trickest 来轻松构建和自动化工作流,利用全球最先进的社区工具。 立即获取访问权限:
基本信息
XS-Search 是一种利用侧信道漏洞来提取跨源信息的方法。
参与此攻击的关键组件包括:
易受攻击的 Web: 意图提取信息的目标网站。
攻击者的 Web: 攻击者创建的恶意网站,受害者访问该网站,托管利用程序。
包含方法: 用于将易受攻击的 Web 包含到攻击者的 Web 中的技术(例如 window.open、iframe、fetch、带有 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 元素的汇编。
框架: 诸如 iframe、object 和 embed 等元素可以直接将 HTML 资源嵌入到攻击者的页面中。如果页面缺乏框架保护,JavaScript 可以通过 contentWindow 属性访问嵌入资源的 window 对象。
弹出窗口:
window.open
方法在新标签页或窗口中打开资源,为 JavaScript 提供一个遵循 SOP 后的方法和属性进行交互。弹出窗口通常用于单点登录,绕过目标资源的框架和 cookie 限制。然而,现代浏览器限制弹出窗口的创建到某些用户操作。JavaScript 请求: JavaScript 允许使用 XMLHttpRequests 或 Fetch API 直接请求目标资源。这些方法提供对请求的精确控制,例如选择是否跟随 HTTP 重定向。
泄漏技术
事件处理程序: 在 XS-Leaks 中的一个经典泄漏技术,事件处理程序如 onload 和 onerror 提供有关资源加载成功或失败的信息。
错误消息: JavaScript 异常或特殊错误页面可以提供泄漏信息,可以直接从错误消息中获取,也可以通过区分错误消息的存在与不存在来获取。
全局限制: 浏览器的物理限制,如内存容量或其他强制执行的浏览器限制,可以在达到阈值时发出信号,作为泄漏技术。
全局状态: 可以利用与浏览器的全局状态(例如 History 接口)的可检测交互。例如,浏览器历史记录中的条目数量可以提供有关跨源页面的线索。
性能 API: 此 API 提供当前页面的性能详细信息,包括文档和加载资源的网络时间,从而推断请求的资源。
可读属性: 一些 HTML 属性是可读取的跨源,可以用作泄漏技术。例如,
window.frame.length
属性允许 JavaScript 计算跨源网页中包含的帧数。
XSinator 工具与论文
XSinator 是一个自动工具,用于检查浏览器是否受到几种已知 XS-Leaks 的影响,其论文在此处解释:https://xsinator.com/paper.pdf
您可以在 https://xsinator.com/ 访问该工具。
排除的 XS-Leaks: 我们不得不排除依赖服务工作者的 XS-Leaks,因为它们会干扰 XSinator 中的其他泄漏。此外,我们选择排除依赖特定 Web 应用程序中的配置错误和漏洞的 XS-Leaks。例如,跨源资源共享(CORS)配置错误、postMessage 泄漏或跨站脚本。此外,我们排除了基于时间的 XS-Leaks,因为它们经常受到速度慢、嘈杂和不准确的影响。
使用 Trickest 来轻松构建和自动化工作流,利用全球最先进的社区工具。 立即获取访问权限:
基于时间的技术
以下一些技术将使用时间作为检测网页可能状态差异的过程的一部分。在Web浏览器中有不同的方法来测量时间。
时钟:performance.now() API允许开发人员获取高分辨率的时间测量。 攻击者可以滥用大量API来创建隐式时钟:Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS动画等。 更多信息:https://xsleaks.dev/docs/attacks/timing-attacks/clocks.
事件处理程序技术
Onload/Onerror
包含方法:Frames, HTML Elements
可检测的差异:状态码
摘要:如果尝试在onerror/onload事件中加载资源时,会触发资源成功/失败加载的事件,可以推断出状态码。
代码示例尝试从JS中加载脚本对象,但也可以使用其他标签,如objects、stylesheets、images、audios。此外,还可以直接注入标签,并在标签内部声明onload
和onerror
事件(而不是从JS中注入)。
这种攻击还有一个无需脚本的版本:
在这种情况下,如果未找到 example.com/404
,将加载 attacker.com/?error
。
载入时间
包含方法:HTML 元素
可检测差异:时间(通常由页面内容、状态码引起)
摘要:performance.now() API 可用于测量执行请求所需的时间。然而,也可以使用其他时钟,如PerformanceLongTaskTiming API,它可以识别运行时间超过 50 毫秒的任务。
载入时间 + 强制重任务
这种技术与前一种类似,但攻击者还将在答案为正或负时强制执行某些操作以花费相关的时间,并测量该时间。
pageperformance.now + Force heavy task卸载/beforeunload 时间
包含方法:框架
可检测差异:时间(通常由页面内容、状态码引起)
摘要:可以使用SharedArrayBuffer 时钟来测量执行请求所需的时间。也可以使用其他时钟。
通过利用unload
和beforeunload
事件,可以测量获取资源所需的时间。beforeunload
事件在浏览器即将导航到新页面时触发,而 unload
事件在实际导航发生时触发。可以计算这两个事件之间的时间差以确定浏览器获取资源所花费的时间。
沙箱框架时间 + 载入
包含方法:框架
可检测差异:时间(通常由页面内容、状态码引起)
摘要:performance.now() API 可用于测量执行请求所需的时间。也可以使用其他时钟。
观察到在缺乏框架保护的情况下,攻击者可以测量页面及其子资源通过网络加载所需的时间。这通常是可能的,因为仅当 iframe 的 onload
处理程序在资源加载和 JavaScript 执行完成后才会触发。为了绕过脚本执行引入的变化,攻击者可能会在 <iframe>
中使用 sandbox
属性。包含此属性限制了许多功能,特别是 JavaScript 的执行,从而促进主要受网络性能影响的测量。
#ID + error + onload
包含方法: 框架
可检测差异: 页面内容
更多信息:
摘要: 如果您可以使页面在访问正确内容时出现错误,并在访问任何内容时正确加载,那么您可以创建一个循环来提取所有信息,而无需测量时间。
代码示例:
假设您可以插入包含秘密内容的页面到一个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执行
包含方法: 框架
可检测差异: 页面内容
更多信息:
摘要: 如果页面返回敏感内容,或者用户可以控制的内容。用户可以在负面情况下设置有效的JS代码,并在**
<script>
标签内加载每次尝试,因此在负面情况下,攻击者的代码将被执行**,而在肯定情况下不会执行任何操作。代码示例:
CORB - Onerror
包含方法: HTML元素
可检测差异: 状态码和标头
摘要: 跨源读取阻止(CORB)是一项安全措施,用于防止网页加载某些敏感的跨源资源,以防范Spectre等攻击。然而,攻击者可以利用其保护行为。当受CORB约束的响应返回带有
nosniff
和2xx
状态码的_CORB受保护_Content-Type
时,CORB会剥离响应的主体和标头。观察到这一点的攻击者可以推断状态码(指示成功或错误)和Content-Type
(表示是否受CORB保护)的组合,从而导致潜在的信息泄漏。代码示例:
查看更多信息链接以获取有关攻击的更多信息。
onblur
包含方法: 框架
可检测差异: 页面内容
摘要: 从id或name属性中泄漏敏感数据。
可以加载一个页面到一个iframe中,并使用**#id_value
使页面聚焦在iframe中指定的元素上,然后如果触发了onblur
信号,则ID元素存在。
您可以使用portal
**标签执行相同的攻击。
postMessage广播
包含方法: 框架,弹出窗口
可检测差异: API使用
摘要: 从postMessage中收集敏感信息或使用postMessages的存在作为一个预言机来了解用户在页面中的状态
代码示例:
任何监听所有postMessages的代码。
应用程序经常使用postMessage
广播在不同源之间进行通信。然而,如果未正确指定targetOrigin
参数,此方法可能会无意中暴露敏感信息,允许任何窗口接收消息。此外,接收消息本身可以充当预言机;例如,某些消息可能仅发送给已登录的用户。因此,这些消息的存在或不存在可以揭示有关用户状态或身份的信息,例如他们是否已经认证。
使用Trickest可以轻松构建和自动化工作流程,使用全球最先进的社区工具。 立即获取访问权限:
全局限制技术
WebSocket API
包含方法: 框架,弹出窗口
可检测差异: API使用
更多信息: https://xsinator.com/paper.pdf (5.1)
摘要: 耗尽WebSocket连接限制会泄漏跨源页面的WebSocket连接数量。
可以确定目标页面使用多少WebSocket连接。这使得攻击者可以检测应用程序状态并泄漏与WebSocket连接数量相关的信息。
如果一个源使用了最大数量的WebSocket连接对象,无论它们的连接状态如何,创建新对象都会导致JavaScript异常。为执行此攻击,攻击者网站在弹出窗口或iframe中打开目标网站,然后在目标网站加载完成后,尝试创建尽可能多的WebSocket连接。抛出的异常数量就是目标网站窗口使用的WebSocket连接数量。
支付 API
包含方法: 框架,弹出窗口
可检测差异: API 使用
更多信息: https://xsinator.com/paper.pdf (5.1)
摘要: 检测支付请求,因为一次只能有一个处于活动状态。
这种 XS-Leak 使攻击者能够检测跨源页面发起支付请求。
因为一次只能有一个支付请求处于活动状态,如果目标网站正在使用支付请求 API,任何进一步尝试使用此 API 的尝试都将失败,并导致JavaScript 异常。攻击者可以通过定期尝试显示支付 API UI来利用这一点。如果一次尝试导致异常,表示目标网站当前正在使用它。攻击者可以在创建 UI 后立即关闭 UI,以隐藏这些定期尝试。
计时事件循环
包含方法:
可检测差异: 计时(通常由页面内容、状态码引起)
摘要: 测量滥用单线程 JS 事件循环的网页执行时间。
代码示例:
JavaScript 在单线程事件循环并发模型上运行,意味着一次只能执行一个任务。这个特性可以被利用来衡量来自不同源的代码执行所需的时间。攻击者可以通过连续分派具有固定属性的事件来测量他们自己代码在事件循环中的执行时间。这些事件将在事件池为空时被处理。如果其他源也将事件分派到相同的池中,攻击者可以通过观察自己任务执行的延迟来推断这些外部事件执行所需的时间。通过监视事件循环中的延迟来揭示来自不同源代码的执行时间的方法,可能会暴露敏感信息。
在执行计时中,可以消除 网络因素以获得更精确的测量。例如,在加载页面之前加载页面使用的资源。
繁忙事件循环
包含方法:
可检测差异: 计时(通常由页面内容、状态码引起)
摘要: 一种测量网页操作执行时间的方法是故意阻塞线程的事件循环,然后计时事件循环何时再次可用。通过在事件循环中插入阻塞操作(如长时间计算或同步 API 调用),并监视后续代码开始执行所需的时间,可以推断在阻塞期间在事件循环中执行的任务的持续时间。这种技术利用了 JavaScript 事件循环的单线程特性,其中任务按顺序执行,并可以提供关于共享线程的其他操作性能或行为的见解。
代码示例:
通过锁定事件循环来测量执行时间的技术的一个重要优势是其有可能规避站点隔离。站点隔离是一项安全功能,将不同网站分隔到单独的进程中,旨在防止恶意网站直接访问其他网站的敏感数据。然而,通过通过共享事件循环影响另一个源的执行时间,攻击者可以间接提取关于该源活动的信息。这种方法不依赖于直接访问其他源数据,而是观察其他源活动对共享事件循环的影响,从而规避了站点隔离建立的保护屏障。
在执行计时中,可以消除 网络因素以获得更精确的测量。例如,在加载页面之前加载页面使用的资源。
连接池
包含方法: JavaScript 请求
可检测差异: 计时(通常由页面内容、状态码引起)
摘要: 攻击者可以锁定除 1 之外的所有套接字,加载目标网页,同时加载另一页,直到最后一页开始加载的时间是目标页面加载所需的时间。
代码示例:
浏览器利用套接字进行服务器通信,但由于操作系统和硬件资源有限,浏览器被迫对并发套接字数量施加限制。攻击者可以通过以下步骤利用这种限制:
确定浏览器的套接字限制,例如,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 个请求将花费更长时间,我们可以检测到。
性能API技术
性能API
提供了对Web应用性能指标的洞察,通过资源定时API
进一步丰富。资源定时API使得监控详细的网络请求时间成为可能,比如请求的持续时间。值得注意的是,当服务器在响应中包含 Timing-Allow-Origin: *
头时,额外的数据如传输大小和域名查找时间就会变得可用。
这些丰富的数据可以通过诸如performance.getEntries
或performance.getEntriesByName
等方法检索,提供了性能相关信息的全面视图。此外,该API通过计算从performance.now()
获取的时间戳之间的差异,便于测量执行时间。然而,值得注意的是,对于Chrome等浏览器中的某些操作,performance.now()
的精度可能仅限于毫秒,这可能会影响时间测量的粒度。
除了时间测量之外,性能API还可以用于安全相关的洞察。例如,在Chrome中performance
对象中页面的存在或不存在可以指示X-Frame-Options
的应用。具体来说,如果由于X-Frame-Options
而阻止页面在框架中呈现,则该页面不会记录在performance
对象中,为页面的框架策略提供了微妙的线索。
错误泄漏
包含方法:框架,HTML元素
可检测差异:状态码
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:导致错误的请求不会创建资源定时条目。
可以区分HTTP响应状态码,因为导致错误的请求不会创建性能条目。
样式重新加载错误
包含方法:HTML元素
可检测差异:状态码
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:由于浏览器错误,导致错误的请求加载两次。
在先前的技术中,还确定了两种情况,即GC中的浏览器错误导致加载失败时资源加载两次。这将导致性能API中出现多个条目,因此可以检测到。
请求合并错误
包含方法:HTML元素
可检测差异:状态码
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:导致错误的请求无法合并。
在提到的论文中找到了这种技术,但没有找到关于该技术的描述。但是,您可以在https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak中找到检查它的源代码。
空白页面泄漏
包含方法:框架
可检测差异:页面内容
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:空白响应不会创建资源定时条目。
攻击者可以检测请求是否导致空的HTTP响应主体,因为某些浏览器中的空白页面不会创建性能条目。
XSS审计泄漏
包含方法:框架
可检测差异:页面内容
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:使用安全断言中的XSS审计器,攻击者可以通过观察当精心制作的有效负载触发审计器的过滤机制时响应中的变化,检测特定网页元素。
在安全断言(SA)中,XSS审计器最初旨在防止跨站脚本(XSS)攻击,但却可以被利用来泄漏敏感信息。尽管这一内置功能已从Google Chrome(GC)中移除,但仍存在于SA中。2013年,Braun和Heiderich证明XSS审计器可能会意外地阻止合法脚本,导致误报。基于此,研究人员开发了技术来提取信息并检测跨源页面上的特定内容,这是一种称为XS-Leaks的概念,最初由Terada报告,由Heyes在博客文章中详细说明。尽管这些技术特定于GC中的XSS审计器,但发现在SA中,被XSS审计器阻止的页面不会在性能API中生成条目,揭示了一种仍然可能泄漏敏感信息的方法。
X-Frame泄漏
包含方法:框架
可检测差异:头部
摘要:带有X-Frame-Options头的资源不会创建资源定时条目。
如果页面不允许在iframe中呈现,则不会创建性能条目。因此,攻击者可以检测响应头部**X-Frame-Options
。
如果使用嵌入** 标签,情况也是一样的。
下载检测
包含方法:框架
可检测差异:头部
更多信息:https://xsinator.com/paper.pdf (5.2)
摘要:下载不会在性能API中创建资源定时条目。
类似于所描述的XS-Leak,由于ContentDisposition头部而下载的资源也不会创建性能条目。这种技术适用于所有主流浏览器。
重定向开始泄漏
包含方法: 框架
可检测差异: 重定向
更多信息: https://xsinator.com/paper.pdf (5.2)
摘要: 资源时间记录泄漏了重定向的开始时间。
我们发现了一个滥用某些浏览器行为的 XS-Leak 实例,这些浏览器为跨源请求记录了过多信息。标准定义了一组应该为跨源资源设置为零的属性子集。然而,在 SA 中,可以通过查询 Performance API 并检查 redirectStart 时间数据 来检测用户是否被目标页面 重定向。
重定向持续时间泄漏
包含方法: Fetch API
可检测差异: 重定向
更多信息: https://xsinator.com/paper.pdf (5.2)
摘要: 当发生重定向时,时间记录的持续时间为负数。
在 GC 中,导致 重定向 的请求的 持续时间 为 负数,因此可以与不导致重定向的请求区分开来。
CORP 泄漏
包含方法: 框架
可检测差异: 头部
更多信息: https://xsinator.com/paper.pdf (5.2)
摘要: 使用 CORP 保护的资源不会创建资源时间记录。
在某些情况下,nextHopProtocol 记录 可以用作泄漏技术。在 GC 中,当设置了 CORP 头部 时,nextHopProtocol 将为空。请注意,对于启用 CORP 的资源,SA 将不会创建任何性能条目。
服务工作者
包含方法: 框架
可检测差异: API 使用
摘要: 检测特定来源是否注册了服务工作者。
代码示例:
服务工作者是在一个来源运行的事件驱动脚本上下文。它们在网页的后台运行,可以拦截、修改和 缓存资源 以创建离线网络应用程序。 如果通过 iframe 访问了由 服务工作者 缓存的 资源,则该资源将从服务工作者缓存中 加载。 要检测资源是否从服务工作者缓存中 加载,可以使用 Performance API。 这也可以通过定时攻击来实现(查看论文获取更多信息)。
缓存
包含方法: Fetch API
可检测差异: 时间
摘要: 可以检查资源是否存储在缓存中。
使用 Performance API 可以检查资源是否已缓存。
网络持续时间
包含方法: Fetch API
可检测差异: 页面内容
摘要: 可以从
performance
API 检索请求的网络持续时间。
错误消息技术
媒体错误
包含方法: HTML 元素(视频,音频)
可检测差异: 状态码
摘要: 在 Firefox 中可以准确泄漏跨源请求的状态码。
CORS错误
包含方法:Fetch API
可检测差异:标头
更多信息:https://xsinator.com/paper.pdf (5.3)
摘要:在安全断言(SA)中,CORS错误消息无意中暴露了重定向请求的完整URL。
这种技术使攻击者能够通过利用基于Webkit的浏览器处理CORS请求的方式,提取跨源站点重定向的目标。具体来说,当向发出基于用户状态的重定向的目标站点发送启用CORS的请求,并且浏览器随后拒绝该请求时,错误消息中会披露重定向目标的完整URL。这种漏洞不仅揭示了重定向的事实,还暴露了重定向的端点以及可能包含的任何敏感查询参数。
SRI错误
包含方法:Fetch API
可检测差异:标头
更多信息:https://xsinator.com/paper.pdf (5.3)
摘要:在安全断言(SA)中,CORS错误消息无意中暴露了重定向请求的完整URL。
攻击者可以利用冗长的错误消息推断跨源响应的大小。这是由于子资源完整性(SRI)的机制,它使用完整性属性验证通常从CDN获取的资源是否未被篡改。为了使SRI在跨源资源上工作,这些资源必须是启用CORS的;否则,它们不会受到完整性检查。在安全断言(SA)中,就像CORS错误XS-Leak一样,可以在带有完整性属性的fetch请求失败后捕获错误消息。攻击者可以通过为任何请求的完整性属性分配虚假哈希值来故意触发此错误。在SA中,由此产生的错误消息无意中揭示了所请求资源的内容长度。这种信息泄漏使攻击者能够辨别响应大小的变化,为复杂的XS-Leak攻击铺平道路。
CSP违规/检测
包含方法:弹出窗口
可检测差异:状态码
摘要:如果我们访问的受害者网站只允许CSP中的目标网站尝试重定向到不同的域,CSP将触发可检测的错误。
XS-Leak可以使用CSP检测跨源站点是否被重定向到不同的源。此泄漏可以检测重定向,但另外,重定向目标的域也会泄漏。这种攻击的基本思想是在攻击者站点上允许目标域。一旦向目标域发出请求,它重定向到一个跨源域。CSP阻止对其的访问并创建用作泄漏技术的违规报告。根据浏览器的不同,此报告可能会泄露重定向的目标位置。 现代浏览器不会指示重定向到的URL,但您仍然可以检测到触发了跨源重定向。
缓存
包含方法:框架,弹出窗口
可检测差异:页面内容
摘要:清除缓存中的文件。打开目标页面检查文件是否存在于缓存中。
代码示例:
浏览器可能为所有网站使用一个共享缓存。无论其来源如何,都可以推断目标页面是否请求了特定文件。
如果页面仅在用户登录时加载图像,您可以使资源无效(因此如果已缓存,则不再缓存,请参阅更多信息链接),执行可能加载该资源的请求,并尝试使用错误请求加载资源(例如使用过长的引用者标头)。如果资源加载没有触发任何错误,那是因为它被缓存了。
CSP指令
包含方法:框架
可检测差异:标头
摘要:CSP标头指令可以通过CSP iframe属性进行探测,以揭示策略细节。
Google Chrome(GC)中的一项新功能允许网页通过在iframe元素上设置属性来提出内容安全策略(CSP),并随HTTP请求传输策略指令。通常,嵌入内容必须通过HTTP标头授权,否则将显示错误页面。但是,如果iframe已经受CSP控制,并且新提出的策略不比原来更严格,页面将正常加载。这种机制为攻击者提供了一种途径,可以通过识别错误页面检测跨源页面的特定CSP指令。尽管此漏洞被标记为已修复,但我们的发现揭示了一种新的泄漏技术,能够检测错误页面,表明根本问题从未得到完全解决。
CORP
包含方法:Fetch API
可检测差异:标头
摘要:受到跨源资源策略(CORP)保护的资源在从不允许的来源获取时会抛出错误。
CORP标头是一个相对较新的Web平台安全功能,当设置时阻止不允许的来源的no-cors跨源请求访问给定资源。可以检测到标头的存在,因为受CORP保护的资源在获取时会抛出错误。
CORB
包含方法: HTML 元素
可检测差异: 头部
摘要: CORB 可以使攻击者检测到请求中是否存在
nosniff
头部。
查看链接以获取有关攻击的更多信息。
CORS 错误的 Origin Reflection 配置错误
包含方法: Fetch API
可检测差异: 头部
摘要: 如果 Origin 头部在
Access-Control-Allow-Origin
头部中反射,就可以检查资源是否已经在缓存中。
如果 Origin 头部 在 Access-Control-Allow-Origin
头部中 反射,攻击者可以利用这种行为尝试以 CORS 模式 获取 资源。如果 没有触发错误,这意味着它已经 正确从网络中检索,如果触发了错误,则是因为它是从缓存中访问的(错误出现是因为缓存保存了带有允许原始域而不是攻击者域的 CORS 头部的响应)。
请注意,如果 Origin 没有反射,而是使用通配符(Access-Control-Allow-Origin: *
),这种方法将不起作用。
可读属性技术
Fetch 重定向
包含方法: Fetch API
可检测差异: 状态码
摘要: 在重定向完成后,GC 和 SA 可以检查响应的类型(opaque-redirect)。
使用 Fetch API 提交请求时,可以使用 redirect: "manual"
和其他参数,以读取 response.type
属性,如果等于 opaqueredirect
,则响应是一个重定向。
COOP
包含方法: 弹出窗口
可检测差异: 头部
摘要: 由跨域打开策略(COOP)保护的页面阻止跨域交互访问。
攻击者能够推断跨域 HTTP 响应中是否存在跨域打开策略(COOP)头部。Web 应用程序使用 COOP 阻止外部站点获取任意窗口引用。尝试访问 contentWindow
引用 可以识别此头部的可见性。在条件应用 COOP 的情况下,opener
属性 成为一个显著的指标:当 COOP 激活时,它是 未定义 的,而在其缺席时是 已定义 的。
URL 最大长度 - 服务器端
包含方法: Fetch API, HTML 元素
可检测差异: 状态码 / 内容
摘要: 由于重定向响应长度可能过大,服务器可能会回复错误并生成警报,因此可以检测到响应中的差异。
如果服务器端重定向使用了 重定向中的用户输入 和 额外数据。可以检测到这种行为,因为通常 服务器 有一个 限制请求长度。如果 用户数据 达到了 长度 - 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 最大长度 - 客户端
包含方法: 弹出窗口
可检测差异: 状态码 / 内容
摘要: 由于重定向响应长度可能过大,可能会注意到请求的差异。
根据 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 中的 哈希 添加,因此它将在重定向中 使用。
最大重定向次数
包含方法:Fetch API, Frames
可检测差异:状态码
摘要:使用浏览器的重定向限制来确定 URL 重定向的发生。
如果浏览器的最大重定向次数为 20,攻击者可以尝试加载他的页面进行 19 次重定向,最终将受害者发送到被测试的页面。如果触发了错误,则页面试图重定向受害者。
历史记录长度
包含方法:Frames, Pop-ups
可检测差异:重定向
摘要:JavaScript 代码可以操纵浏览器历史记录,并且可以通过长度属性访问。
历史 API 允许 JavaScript 代码操纵浏览器历史记录,这保存了用户访问的页面。攻击者可以使用长度属性作为包含方法:检测 JavaScript 和 HTML 导航。
检查 history.length
,让用户导航到一个页面,将其改回同源,并检查 history.length
的新值。
具有相同 URL 的历史记录长度
包含方法:Frames, Pop-ups
可检测差异:如果 URL 与猜测的 URL 相同
摘要:可以通过滥用历史记录长度来猜测框架/弹出窗口的位置是否在特定 URL 中。
代码示例:如下
攻击者可以使用 JavaScript 代码将框架/弹出窗口位置操纵到一个猜测的位置,然后立即将其更改为 about:blank
。如果历史记录长度增加,这意味着 URL 是正确的,并且有时间增加,因为如果 URL 相同,则不会重新加载。如果长度没有增加,这意味着它尝试加载猜测的 URL,但因为我们立即加载了 about:blank
,当加载猜测的 URL 时,历史记录长度从未增加。
帧计数
包含方法: 框架,弹出窗口
可检测差异: 页面内容
摘要: 通过检查
window.length
属性评估 iframe 元素的数量。
通过 iframe
或 window.open
打开的 web 页面中的帧数 可能有助于识别 用户在该页面上的状态。
此外,如果页面始终具有相同数量的帧,连续 检查帧数可能有助于识别可能泄露信息的 模式。
这种技术的一个示例是,在 Chrome 中,可以通过 帧计数 检测到 PDF,因为内部使用了 embed
。存在一些 打开 URL 参数 可以控制内容,如 zoom
、view
、page
、toolbar
,其中这种技术可能很有趣。
HTMLElements
包含方法: HTML 元素
可检测差异: 页面内容
摘要: 读取泄露的值以区分 2 种可能的状态
通过 HTML 元素泄露信息是 Web 安全中的一个关注点,特别是当基于用户信息生成动态媒体文件或添加水印以更改媒体大小时。攻击者可以利用这一点,通过分析某些 HTML 元素暴露的信息来区分可能的状态。
HTML 元素泄露的信息
HTMLMediaElement: 此元素显示媒体的
duration
和buffered
时间,可以通过其 API 访问。了解更多关于 HTMLMediaElementHTMLVideoElement: 它公开
videoHeight
和videoWidth
。在某些浏览器中,还提供了额外的属性,如webkitVideoDecodedByteCount
、webkitAudioDecodedByteCount
和webkitDecodedFrameCount
,提供了有关媒体内容的更详细信息。了解更多关于 HTMLVideoElementgetVideoPlaybackQuality(): 此函数提供有关视频播放质量的详细信息,包括
totalVideoFrames
,可以指示处理的视频数据量。了解更多关于 getVideoPlaybackQuality()HTMLImageElement: 此元素泄露图像的
height
和width
。但是,如果图像无效,这些属性将返回 0,并且image.decode()
函数将被拒绝,表示未能正确加载图像。了解更多关于 HTMLImageElement
CSS 属性
包含方法: HTML 元素
可检测差异: 页面内容
摘要: 识别与用户状态或状态相关的网站样式变化。
Web 应用程序可能根据用户状态更改 网站样式。攻击者可以在攻击者页面上嵌入跨源 CSS 文件,使用 HTML link 元素,并将这些 规则 应用到攻击者页面上。如果页面动态更改这些规则,攻击者可以根据用户状态 检测 这些 差异。
作为一种泄漏技术,攻击者可以使用 window.getComputedStyle
方法来 读取 特定 HTML 元素的 CSS 属性。因此,如果已知受影响的元素和属性名称,攻击者可以读取任意 CSS 属性。
CSS 历史
包含方法: HTML 元素
可检测差异: 页面内容
摘要: 检测是否应用了
:visited
样式于 URL,指示其已被访问过
根据 此,在无头 Chrome 中无效。
CSS :visited
选择器用于在用户先前访问过的情况下以不同样式显示 URL。过去,getComputedStyle()
方法可用于识别这些样式差异。但是,现代浏览器已经实施了安全措施,防止此方法揭示链接状态。这些措施包括始终返回计算样式,就像链接已被访问一样,并限制可以使用 :visited
选择器应用的样式。
尽管存在这些限制,仍然可以间接地辨别链接的访问状态。一种技术涉及欺骗用户与受 CSS 影响的区域进行交互,特别是利用 mix-blend-mode
属性。此属性允许元素与其背景混合,根据用户交互可能显示已访问状态。
此外,可以通过利用链接的渲染时间来实现无需用户交互的检测。由于浏览器可能以不同方式呈现已访问和未访问的链接,这可能导致呈现中的时间差异。在 Chromium 缺陷报告中提到了一个概念验证 (PoC),演示了使用多个链接放大时间差异的技术,从而通过时间分析使已访问状态可检测。
有关这些属性和方法的更多详细信息,请访问它们的文档页面:
ContentDocument X-Frame Leak
包含方法: 框架
可检测差异: 头部
摘要: 在Google Chrome中,当由于X-Frame-Options限制而阻止页面嵌入到跨源站点时,会显示专用错误页面。
在Chrome中,如果页面的X-Frame-Options
头设置为"deny"或"same-origin"并作为对象嵌入,将出现错误页面。与在iframes或其他浏览器中不同,Chrome独特地为此对象的contentDocument
属性返回一个空文档对象(而不是null
)。攻击者可以利用这一点检测空文档,可能揭示有关用户状态的信息,特别是如果开发人员不一致地设置X-Frame-Options头,经常忽视错误页面。意识到并一致应用安全头部对于防止此类泄漏至关重要。
下载检测
包含方法: 框架,弹出窗口
可检测差异: 头部
摘要: 攻击者可以利用iframes来识别文件下载;iframe的持续可访问性意味着文件下载成功。
特别是Content-Disposition: attachment
头指示浏览器下载内容而不是内联显示。这种行为可以被利用来检测用户是否可以访问触发文件下载的页面。在基于Chromium的浏览器中,有一些技术可以检测这种下载行为:
下载栏监控:
当在基于Chromium的浏览器中下载文件时,下载栏会出现在浏览器窗口底部。
通过监控窗口高度的变化,攻击者可以推断下载栏的出现,表明已启动下载。
使用iframes进行下载导航:
当页面使用
Content-Disposition: attachment
头触发文件下载时,不会导致导航事件。通过在iframe中加载内容并监控导航事件,可以检查内容设置是否导致文件下载(无导航)。
不使用iframes进行下载导航:
类似于iframe技术,此方法涉及使用
window.open
而不是iframe。监控新打开窗口中的导航事件可以揭示文件下载是否被触发(无导航)或内容是否内联显示(发生导航)。
在只有已登录用户可以触发此类下载的情况下,这些技术可以用于间接推断用户的身份验证状态,根据浏览器对下载请求的响应。
分区HTTP缓存绕过
包含方法: 弹出窗口
可检测差异: 时间
摘要: 攻击者可以利用iframes来识别文件下载;iframe的持续可访问性意味着文件下载成功。
这就是这种技术有趣的原因: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)
,缓存键不同,因此无法共享缓存。您可以在这里找到更多详细信息:通过分区缓存获得安全性和隐私性
(来自这里)
如果网站example.com
包含来自*.example.com/resource
的资源,则该资源将与直接通过顶级导航请求资源具有相同的缓存键。这是因为缓存键由顶级_eTLD+1_和框架_eTLD+1_组成。
由于访问缓存比加载资源更快,可以尝试更改页面的位置并在停止后取消20毫秒(例如)后。如果停止后更改了来源,这意味着资源已被缓存。 或者只需向可能已缓存的页面发送一些fetch并测量加载所需的时间。
手动重定向
包含方法: Fetch API
可检测差异: 重定向
摘要: 可以查明对fetch请求的响应是否是重定向
代码示例:
使用AbortController的Fetch
包含方法: Fetch API
可检测差异: 时间
摘要: 可以尝试加载资源并在加载之前中止加载。根据触发错误与否,可以确定资源是否已缓存。
使用_fetch_和_setTimeout_与AbortController来检测资源是否已缓存,并从浏览器缓存中清除特定资源。此外,该过程在不缓存新内容的情况下进行。
脚本污染
包含方法: HTML 元素 (script)
可检测差异: 页面内容
摘要: 可以覆盖内置函数并读取它们的参数,即使来自跨源脚本(无法直接读取),这可能会泄露有价值的信息。
服务工作者
包含方法: 弹出窗口
可检测差异: 页面内容
摘要: 使用服务工作者测量网页的执行时间。
代码示例:
在给定的场景中,攻击者主动注册一个服务工作者在他们的一个域中,具体来说是"attacker.com"。接下来,攻击者从主文档中打开目标网站的一个新窗口,并指示服务工作者启动计时器。当新窗口开始加载时,攻击者导航到在前一步中获取的引用,该引用由服务工作者管理的页面。
在前一步发起的请求到达时,服务工作者以**204 (无内容)**状态码做出响应,有效地终止导航过程。此时,服务工作者从第二步中启动的计时器中捕获一个测量值。这个测量值受到导航过程中由 JavaScript 导致的延迟的影响。
在执行时间中,可以消除 网络因素以获得更精确的测量。例如,通过在加载页面之前加载页面使用的资源。
获取时间
包含方法: 获取 API
可检测差异: 时间(通常由页面内容、状态码引起)
摘要: 使用 performance.now() 来测量执行请求所需的时间。也可以使用其他时钟。
跨窗口时间
包含方法: 弹出窗口
可检测差异: 时间(通常由页面内容、状态码引起)
摘要: 使用 performance.now() 来测量使用
window.open
执行请求所需的时间。也可以使用其他时钟。
使用 Trickest 可以轻松构建和自动化工作流程,使用世界上最先进的社区工具。 立即获取访问权限:
使用 HTML 或重新注入
在这里,您可以找到从跨源 HTML 中注入 HTML 内容中提取信息的技术。在某些情况下,您可以注入 HTML 但无法注入 JS 代码,这些技术非常有趣。
悬空标记
pageDangling Markup - HTML scriptless injection图像延迟加载
如果您需要提取内容并且可以在秘密之前添加 HTML,您应该检查常见的悬空标记技术。 但是,如果出于任何原因您必须逐个字符执行(也许通信是通过缓存命中),您可以使用这个技巧。
在 HTML 中,图像有一个“loading”属性,其值可以是“lazy”。在这种情况下,图像将在查看时加载,而不是在页面加载时加载:
因此,你可以添加大量的无用字符(例如成千上万个"W")来填充网页,使其在秘密信息之前或之后添加类似于<br><canvas height="1850px"></canvas><br>
的内容。
因此,如果例如我们的注入出现在标志之前,那么图片将会加载,但如果出现在标志之后,标志和无用字符将阻止其加载(你需要调整添加多少无用字符)。这就是在这篇文章中发生的情况。
另一个选择是使用scroll-to-text-fragment(如果允许):
滚动到文本片段
然而,你可以让机器人访问页面,例如:
所以网页将是这样的:https://victim.com/post.html#:~:text=SECR
其中 post.html 包含攻击者的垃圾字符和延迟加载图像,然后机器人的秘密被添加。
这段文本的作用是让机器人访问页面中包含文本 SECR
的任何文本。由于该文本是秘密,而且它就在图像下方,只有在猜测的秘密正确时图像才会加载。因此,你有了逐个字符窃取秘密的 Oracle。
一些利用此漏洞的代码示例:https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
图像延迟加载基于时间
如果无法加载外部图像以指示攻击者图像已加载,另一个选择是尝试多次猜测字符并测量时间。如果加载了图像,所有请求将比未加载图像时花费更长的时间。这就是在此 writeup 的解决方案中使用的方法,在此概述:
pageEvent Loop Blocking + Lazy imagesReDoS
pageRegular expression Denial of Service - ReDoSCSS ReDoS
如果使用 jQuery(location.hash)
,可以通过时间判断某些 HTML 内容是否存在,这是因为如果选择器 main[id='site-main']
不匹配,则无需检查其余的选择器:
CSS注入
pageCSS Injection防御
建议在 https://xsinator.com/paper.pdf 中提供了缓解措施,每个部分的维基 https://xsleaks.dev/ 也有。查看更多关于如何防范这些技术的信息。
参考资料
使用 Trickest 可以轻松构建和自动化工作流程,使用世界上最先进的社区工具。 立即获取访问权限:
最后更新于