介绍
很高兴见到你。我是来自 Richerka Security 的辻佐藤聪 (Satoki Tsuji)。在工作中,我进行Web漏洞诊断和新的Web攻击方法的研究。
本文解释了AVTOKYO2024 上公布的“ Mozilla Firefox 信息泄露 0day 漏洞(CVE-2024-9398、CVE-2024-5690) ”。本文描述的漏洞允许 URL 协议处理程序设置(通常应由浏览器隐藏)的存在或不存在通过页面泄露。因此,攻击者可以确定目标用户计算机上安装的各种应用程序。
Mozilla Firefox 0day:浏览器侧通道攻击泄露已安装的应用程序
https://www.avtokyo.org/avtokyo2024/speakers#h.qgm2v519vpgj
⚠注意此
漏洞的解释是在 Mozilla 许可下发布的。本文旨在用于安全研究和教育,对于因不当使用本文信息而造成的任何损害,我们不承担任何责任。
什么是 URL 协议处理程序?
URL 协议处理程序是一种定义浏览器或操作系统如何根据特定协议方案(例如 http、ftp、mailto)处理 URL 的机制。用于确定访问 URL 时启动哪个应用程序。例如,mailto:[email protected]当您单击类似 的链接时,您的默认电子邮件客户端将打开,mailto因为 URL 协议处理程序配置为处理方案中的 URL。
常见方案已向 IANA 注册,也有由应用程序设置的自定义方案。下面显示了一个示例方案。
方案 | 功能概述 |
---|---|
http | 使用HTTP协议访问网页 |
javascript | 在网页中执行 JavaScript |
file | 访问文件系统 |
steam | 调用Steam平台内的特定功能 |
zoommtg | 在 Zoom 上开始或加入会议 |
example例子 | 用于说明该方案 |
当使用该方案启动应用程序时,将显示一个对话框,要求用户确认。下面steam显示了打开该方案的示例。
应用程序可以为 URL 协议处理程序设置自己的自定义方案。我不会详细介绍,但在 Windows 中,URL Protocol您可以通过在注册表中注册密钥、可执行文件路径和执行参数来使用自定义方案。
URL 协议处理程序泄漏的风险
如果 URL 协议处理程序设置的存在或不存在泄露给攻击者,会带来哪些风险?FortiGuard 实验室威胁研究报告将违规造成的影响总结如下:
-
识别通信渠道:通过列出处理程序,攻击者可以获得他可能使用哪些平台来联系目标用户的提示,例如,检测可能使用 Slack、Skype、WhatsApp 或 Telegram 等社交应用程序与目标进行通信。
-
一般侦察:当今多种应用程序都使用自定义 URL 处理程序,并且可以使用此漏洞进行检测,例如:音乐播放器、IDE、办公应用程序、加密挖掘、浏览器、邮件应用程序、防病毒、视频会议、虚拟化、数据库客户端。、版本控制客户端、聊天客户端、语音会议应用程序、共享存储
-
预利用检测:漏洞利用工具包可以利用此信息来识别是否存在潜在易受攻击的应用程序,而无需暴露漏洞本身。
-
检测安全解决方案:许多安全解决方案(例如 AV 产品)都会注册协议处理程序,这些协议处理程序的存在可以通过利用漏洞来暴露,因为它们安装了自定义协议处理程序,攻击者可能会使用它来进一步自定义其攻击,以便能够绕过由其设置的任何保护机制。那些安全解决方案。
-
用户指纹识别:读取系统上存在的协议处理程序也可用于改进浏览器/用户指纹识别算法。
如果 URL 协议处理程序设置是否存在被泄露,攻击者就可以枚举现有的处理程序。结果,您可以看到目标用户计算机上安装的各种应用程序。具体来说,slack如果存在方案,则安装Slack;skype如果存在方案,则安装Skype。
如果暴露是否安装了特定应用程序,会带来哪些风险?如果目标用户日常使用的通讯工具已知,攻击者就可以调查该帐户并联系目标用户。目标属性可以从已安装应用程序的类型推断出来。了解金融应用程序将有助于提高网络钓鱼的准确性。当跟踪网站内的目标时,它还可以用于指纹识别。
它还可能识别目标用户安装的安全软件,并将其用作下次攻击的垫脚石,例如逃避检测。下面是一个对攻击者有用的自定义方案示例,由FortiGuard 实验室的Rotem Kerner报告。由于这是 2020 年的报告,因此当前的支持状态未知。
方案 | 供应商名称 |
---|---|
GDataGDATAToast新闻 | 通用数据 |
malwarebytes | MalwareBytes |
avastpam | Avast |
vizorwebs, tmtb, 钛, vizorweb | 趋势科技 |
BD启动 | BitDefender |
img 标签大小 oracle 的已知漏洞
在低于 82 版本的 Mozilla Firefox 中,Rotem Kerner 报告了 URL 协议处理程序泄漏漏洞。该漏洞的编号为 CVE-2020-15680,Mozilla 基金会安全公告中列出的影响为中等。
CVE-2020-15680:可以通过图像标签确定外部协议处理程序的存在
-
https://www.mozilla.org/en-US/security/advisories/mfsa2020-45/#CVE-2020-15680
在 img 标签的 src 中指定自定义方案时,他发现了行为上的差异。准备两个img标签,如下所示。
<img src="ms-settings://satoki">
<img src="satoki://satoki">
ms-settings该方案设置为启动 Windows 设置应用程序,并且satoki该方案中未设置任何内容。打开开发者工具,查看每个img标签的大小。
ms-settings://satoki img 标签
satoki://satoki 的 img 标签
两者都无法作为图像加载,但您可以看到样式具有不同的大小。如果 Firefox 无法正确加载图像,则会显示损坏的图像图标。该图标的大小为 24×24。ms-settings图标显示在方案中。另一方面,satoki在没有设置处理程序的方案中,例如方案,不显示图标,因此大小为0x0。
通过使用这个大小差异作为预言(可以用作推断未知事物的线索的已知信息),攻击者可以确定是否设置了 URL 协议处理程序。通过使用 JavaScript 生成大量 img 标签并验证每种样式的宽度是否匹配 24,站点操作员可以了解访问者计算机上设置的 URL 协议处理程序。
使用 window.open 错误作为 oracle 的方法 (CVE-2024-9398)
这是作者发现的第一个漏洞。利用该漏洞,可以通过将访问window.open的返回值时发生的错误的有无作为oracle来获取URL协议处理程序设置的有无。它的危险性较小,因为目标用户必须允许弹出窗口。
CVE-2024-9398:可以通过弹出窗口枚举外部协议处理程序
在进行漏洞研究时,我们发现当使用window.open打开自定义方案时,会显示不同的页面。打开开发人员工具控制台并运行以下 JavaScript。
open01 = window.open("ms-settings://satoki");
open02 = window.open("satoki://satoki");
如果允许弹出窗口,将打开两个新页面,如下所示。
页面打开于 ms-settings://satoki
页面打开于 satoki://satoki
ms-settings该方案显示一个对话框,提示用户确认打开应用程序。另一方面,satoki没有配置处理程序的方案(例如Scheme)会显示页面加载错误。发生这种情况是因为没有要打开的应用程序。有可能知道这个区别吗?
让我们返回到执行 window.open 的开发者工具控制台并访问返回的文档对象。
对导致页面加载错误的页面的文档对象的访问被拒绝并发生错误。此行为open02[0]与数组访问(如 .通过捕获此错误,您可以将其用作预言机。使用该差异的其他frames预言机也是可能的,如下所示。
在允许弹出窗口的情况下,攻击者使用window.open打开大量自定义方案并验证访问每个文档对象是否会导致错误。此结果允许攻击者确定是否配置了 URL 协议处理程序。不自然打开的页面可以通过最后使用 window.close 关闭所有页面来处理。
使用 window.history 中的更改作为预言机的方法
尽管与之前使用错误作为预言机的方法没有什么区别,但我们还发现了一种利用历史有趣行为的方法。我们将应用CTF等中众所周知的通过History Length获取用户信息的技术。此方法包含在使用 oracle 处理 window.open 错误的方法 (CVE-2024-9398)中。在使用 window.open 打开之前都是一样的,但是当 window.location 更新时,它会使用 window.history 中的更改。
ms-settings://satoki在 window.open with handler set后,ms-settings://satoki#satoki将 window.location 更改为 withfragment,然后about:blank再次更改 window.location。那么window.history.length1将会是。当 window.location 更新时,历史记录似乎不会增加。
另一方面,更改方案satoki://satoki window.open 和 window.location satoki://satoki#satoki两次,并且不设置任何处理程序。about:blank然后,您可以访问 window.history.length,并且 window.history.length 2变为 。看来历史在这里会增加。
总结这些行为,当更新 window.location 时,历史记录仅在未设置处理程序的方案中增加。使用 window.history 中的此更改作为预言机,攻击者可以确定是否设置了 URL 协议处理程序。
使用 iframe.contentWindow.history.length 错误作为oracle的方法
使用 window.open 打开新页面需要弹出权限。弹出窗口必须由目标用户有意允许,从而使它们不那么隐蔽,因为它们需要用户操作。我们还发现了一种不需要目标用户允许弹出窗口的方法,并且我们已将其报告为使用 Oracle 解决 window.open 错误的方法 (CVE-2024-9398) 。为了提高隐蔽性,此方法为每个自定义方案创建一个 iframe,并在访问 iframe.contentWindow.history.length 时使用是否存在错误。
创建两个 iframe,一个带有处理程序ms-settings://satoki,另一个不带有处理程序。satoki://satoki打开开发人员工具控制台并运行以下 JavaScript。请注意,Firefox 有一个限制,即不能连续打开 iframe,除非它们之间有一定的间隔。
iframe01 = document.createElement("iframe");
document.body.appendChild(iframe01);
iframe01.sandbox="";
iframe01.src = "ms-settings://satoki";
// sleep 10~20s
iframe02 = document.createElement("iframe");
document.body.appendChild(iframe02);
iframe02.sandbox="";
iframe02.src = "satoki://satoki";
然后,将打开两个新的 iframe,如下所示。这里,我们还采用了一种技术,利用沙箱属性,不显示提示用户确认的对话框。
ms-settings如果像方案中那样设置处理程序,则显示空白页面,satoki如果没有像方案中那样设置处理程序,则显示页面加载错误。这类似于window.open。现在让我们访问每个 iframe 的 contentWindow.history.length。
satoki访问方案中的 contentWindow.history.length 被拒绝并导致错误。about:blank通过在创建 iframe 后指定 src 会发生此行为。通过捕获此错误,您可以将其用作预言机。
攻击者以指定的时间间隔在 iframe 中打开自定义方案,并验证访问 contentWindow.history.length 是否会导致错误。结果允许攻击者确定是否配置了 URL 协议处理程序。而且,它是比 window.open 更强大的方法,因为它允许在至少允许弹出一次的情况下连续打开 iframe。
使用 oracle 计算 img 标签 onerror 触发时间的方法 (CVE-2024-5690)
这是作者发现的第二个漏洞。利用此漏洞,可以通过使用从生成 img 标签到触发读取错误事件 (onerror) 的时间作为预言机来获取 URL 协议处理程序设置是否存在。目标用户无需执行任何操作。
CVE-2024-5690:外部协议处理程序因定时攻击而泄露
-
https://www.mozilla.org/en-US/security/advisories/mfsa2024-25/#CVE-2024-5690
在进行漏洞研究时,我们验证了在 img 标签中设置自定义方案时事件的触发。可以在 img 标签中设置事件,如下所示。
<img src="ms-settings://satoki" onerror="alert('ms-settings')">
<img src="satoki://satoki" onerror="alert('satoki')">
幸运的是,我们发现无论是否设置处理程序都会触发该事件。因此,我决定测量事件触发所需的时间。打开开发人员工具控制台并创建以下 JavaScript 函数。
async function measureLoadTime(ph, numberOfTrials) {
let totalTime = 0;
for (let i = 0; i < numberOfTrials; i++) {
const startTime = performance.now();
await new Promise(resolve => {
const img = document.createElement("img");
document.body.appendChild(img);
img.onload = img.onerror = function() {
const endTime = performance.now();
totalTime += endTime - startTime;
img.parentNode.removeChild(img);
resolve();
};
img.src = ph;
});
}
return totalTime;
}
该函数首先生成一个img标签。接下来,将传递的第一个参数设置为 img 标签的 src。之后,测量触发 onload 事件(加载完成)或 onerror 事件(加载失败)之前的时间。此外,这一系列测量将重复第二个参数指定的次数,并返回累积时间。换句话说measureLoadTime(“satoki://satoki”, 10000);,当您调用时,satoki://satoki它会测量 onerror 事件触发 10000 次之前的时间并返回累积时间。使用此函数执行下面的 JavaScript 并测量 10,000 个自定义方案的时间。
measureLoadTime("ms-settings://satoki", 10000).then(time => console.log(time));
measureLoadTime("satoki://satoki", 10000).then(time => console.log(time));
更改顺序并多次执行后,结果如下。
ms-settingssatoki您可以看到方案事件的触发速度大约是方案事件触发时间的两倍。在测试了各种自定义方案后,我们发现设置处理程序的方案会延迟事件触发。这种延迟可以用作预言机。
攻击者使用 JavaScript 生成大量 img 标签,并测量每个标签触发事件所需的时间。尽管速度因环境而异,但可以通过存储预先未设置处理程序的方案的值并进行比较来确定是否设置 URL 协议处理程序。
使用 CSP report-uri 指令请求作为 oracle 的方法(CVE-2024-5690:重复)
这是作者发现的第三个漏洞。这是在使用 oracle 获取 img 标签的 onerror 触发时间的方法 (CVE-2024-5690)之前报告的,但由于修复是在同一位置完成的,因此更改为 DUPLICATE。我觉得如果我调整一下时间,汇报得好的话,我就可以通过认证了。该漏洞利用了 CSP(内容安全策略)阻止加载 img 标签时的行为。您可以通过使用对 CSP report-uri 指令中设置的 URL 的请求作为 oracle 来获取 URL 协议处理程序设置是否存在。目标用户无需执行任何操作。
在进行漏洞研究时,我们验证了使用 CSP 阻止 img 标签时的行为。如果设置CSP的页面上被屏蔽的img标签样式有差异img-src ‘self’,可以使用。由于自定义方案不是自我的,因此我希望所有内容都被统一阻止。创建并研究如下所示的 HTML。
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="img-src 'self';">
</head>
<body>
<img src="ms-settings://satoki">
<img src="satoki://satoki">
</body>
</html>
在研究开发人员工具中的 img 标签样式等时,我注意到控制台中出现奇怪的显示,如下所示。
虽然它包含两个img标签,ms-settings但只有该方案被CSP阻止。即使我改变了 img 标签的顺序也是一样的。换句话说,设置了处理程序的方案将被 CSP 阻止加载资源,但未设置处理程序的方案将被视为不作为资源本身加载。由于负载本身没有发生,因此它不会被 CSP 阻止。是否可以像这样从外部观察CSP中是否存在块?
report-uri此时,我记得CSP 有一个报告违规(阻止)的指令,但它是可配置的。Content-Security-Policy: report-uri <http://localhost>;通过这样的设置,当页面内容发生CSP违规时,浏览器http://localhost会以JSON形式POST违规内容。report-uri无法用元标记指定,因此准备一个简单的服务器程序,如下所示。
from flask import Flask, request, make_response
app = Flask(__name__)
@app.route("/")
def index():
response = make_response(
f"""\\
<html>
<body>
<img src="ms-settings://satoki">
<img src="satoki://satoki">
</body>
</html>
"""
)
response.headers["Content-Security-Policy"] = (
f"img-src 'self'; report-uri <http://localhost:5555/recv;">
)
return response
@app.route("/recv", methods=["POST"])
def recv():
print(request.get_data().decode("utf-8"))
return "OK"
if __name__ == "__main__":
app.run(debug=False, host="0.0.0.0", port=5555)
这个简单的服务器程序侦听端口 5555 上的访问并显示两个 img 标签。img 标签img-src ‘self’;仅限于 CSP。它还report-uri <http://localhost:5555/recv;指定了向何处举报违反 CSP 的行为。接收报告的路径/recv打印收到的 CSP 违规报告。打开此服务器页面时打印的 JSON 如下。>
{
"csp-report": {
"blocked-uri": "ms-settings",
"column-number": 1,
"disposition": "enforce",
"document-uri": "<http://localhost:5555/>",
"effective-directive": "img-src",
"original-policy": "img-src 'self'; report-uri <http://localhost:5555/recv>",
"referrer": "",
"status-code": 200,
"violated-directive": "img-src"
}
}
blocked-urims-settings可以看到显示了被阻止的方案。您可以将此请求用作预言机。类似地,script-src当脚本标签受指令限制时的请求,或者media-src当音频或视频标签受指令限制时的请求,也可以用作预言机。
攻击者提前准备了一个带有大量img标签的页面。该页面的CSP必须阻止img标签并report-uri在指令中设置攻击者自己的服务器。攻击者blocked-uri可以根据收到的CSP违规报告的内容确定是否配置了URL协议处理程序。
更正
CVE-2024-9398
如果有协议处理程序设置,则会显示一个带有 about:blank 的弹出窗口,如果没有协议处理程序设置,则会显示网络错误页面。这种差异是由是否存在财产访问违规造成的。即使没有协议处理程序设置,也可以通过使用 about:blank 来消除差异。
CVE-2024-5690
原因是在包括 CSP 在内的安全检查之前执行了协议处理程序设置是否存在的检查。因此,触发错误事件所需的时间存在差异。已进行修复以消除在未设置协议处理程序时提前返回的功能。此外,导致 DUPLICATE 的漏洞已通过相同的修复得到解决。
结论
在本文中,我们解释了一个漏洞,该漏洞会通过页面泄露 URL 协议处理程序设置的存在或不存在。即使是乍一看似乎无害的 URL 协议处理程序配置信息,从攻击者的角度来看也可能是可利用的。行为差异通常是由于实现的差异而发生的,例如浏览器优化。安全工程师必须始终采取进攻性的观点,并对看似无害的信息保持怀疑。
在Richerka Security,我们每天研究网络领域的未知攻击,并利用它为我们的客户提供解决方案。除了报告发现的漏洞外,我们还有演示支持系统,支持外部演示,例如将演示材料的准备计入工作时间,以及给予平日演示特别假等。
我们有很多工作想留给年轻人才,比如研发,包括著名软件的0day漏洞研究。如果您在阅读本文后对我们的努力感兴趣,请申请临时采访。
感谢您抽出
.
.
来阅读本文
点它,分享点赞在看都在这里
原文始发于微信公众号(Ots安全):Mozilla Firefox 0-day:URL 协议处理程序泄漏 [CVE-2024-9398、CVE-2024-5690]