当前位置: 首页 > ai >正文

漏洞分析 | Kafka Connect 任意文件读取漏洞(CVE-2025-27817)

漏洞概述

Apache Kafka Connect是Apache Kafka生态系统的核心组件,负责实现Kafka与其他外部系统(如数据库、云服务)之间的可靠数据集成。
近期,网宿安全演武实验室监测到攻击者在未授权的情况下可以通过特定方式读取Kafka Connect服务器上的任意文件,从而造成信息泄露。(网宿评分:高危、CVSS 3.1 评分:7.5)

目前该漏洞POC状态已在互联网公开,建议客户尽快做好自查及防护。

受影响版本

3.1.0 <= Apache Kafka <= 3.9.0

漏洞分析

该漏洞源于Kafka Client在SASL/OAUTHBEARER认证配置中对以下参数的校验缺陷:

sasl.oauthbearer.token.endpoint.url
sasl.oauthbearer.jwks.endpoint.url

这里先简单梳理Kafka SASL/OAUTHBEARER认证流程:

客户端 → 获取Token → 连接Kafka → Broker验证 → 授权访问

具体细节详见:https://docs.confluent.io/platform/current/security/authentication/sasl/oauthbearer/overview.html

那么上述问题参数参与了哪部分流程?先看sasl.oauthbearer.token.endpoint.url,它出现在客户端获取Token阶段,其次是sasl.oauthbearer.jwks.endpoint.url,它出现在Broker验证Token阶段。正因这里未严格校验它们所指向的URL,才产生漏洞,至于具体的漏洞文件位置,我们对比一下新旧版本就可以清晰地发现:

clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/AccessTokenRetrieverFactory.java

clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/VerificationKeyResolverFactory.java

以sasl.oauthbearer.token.endpoint.url为例,对其相应的漏洞文件进行断点分析,代码如下:

public static AccessTokenRetriever create(Map<String, ?> configs, String saslMechanism, Map<String, Object> jaasConfig) {ConfigurationUtils cu = new ConfigurationUtils(configs, saslMechanism);URL tokenEndpointUrl = cu.validateUrl("sasl.oauthbearer.token.endpoint.url");if (tokenEndpointUrl.getProtocol().toLowerCase(Locale.ROOT).equals("file")) {return new FileTokenRetriever(cu.validateFile("sasl.oauthbearer.token.endpoint.url"));} else {JaasOptionsUtils jou = new JaasOptionsUtils(jaasConfig);String clientId = jou.validateString("clientId");String clientSecret = jou.validateString("clientSecret");String scope = jou.validateString("scope", false);SSLSocketFactory sslSocketFactory = null;if (jou.shouldCreateSSLSocketFactory(tokenEndpointUrl)) {sslSocketFactory = jou.createSSLSocketFactory();}boolean urlencodeHeader = validateUrlencodeHeader(cu);return new HttpAccessTokenRetriever(clientId, clientSecret, scope, sslSocketFactory, tokenEndpointUrl.toString(), cu.validateLong("sasl.login.retry.backoff.ms"), cu.validateLong("sasl.login.retry.backoff.max.ms"), cu.validateInteger("sasl.login.connect.timeout.ms", false), cu.validateInteger("sasl.login.read.timeout.ms", false), urlencodeHeader);}}

显然该方法动态选择了token的获取方式,那么攻击者想要窃取敏感文件,则需要使用file协议促使代码走本地文件读取token这一逻辑,跟进至
org.apache.kafka.common.security.oauthbearer.internals.secured.FileTokenRetriever

public class FileTokenRetriever implements AccessTokenRetriever {private final Path accessTokenFile;private String accessToken;public FileTokenRetriever(Path accessTokenFile) {this.accessTokenFile = accessTokenFile;}public void init() throws IOException {this.accessToken = Utils.readFileAsString(this.accessTokenFile.toFile().getPath());this.accessToken = this.accessToken.trim();}public String retrieve() throws IOException {if (this.accessToken == null) {throw new IllegalStateException("Access token is null; please call init() first");} else {return this.accessToken;}}}

不难发现,这里只接收保存了accessTokenFile参数,没用任何的路径校验或安全防护。而下面的retrieve()方法,也只是检查accessToken是否初始化,就直接返回原token字符串了。

那么接下来就需要考虑,如何将敏感文件的内容带出来?回顾漏洞描述,触发点其实就在认证环节,查看核心登录模块:
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule

其中就有提取token的方法:

private void identifyToken() throws LoginException {OAuthBearerTokenCallback tokenCallback = new OAuthBearerTokenCallback();try {this.callbackHandler.handle(new Callback[]{tokenCallback});} catch (UnsupportedCallbackException | IOException var3) {log.error(var3.getMessage(), var3);throw new LoginException("An internal error occurred while retrieving token from callback handler");}this.tokenRequiringCommit = tokenCallback.token();if (tokenCallback.errorCode() != null) {log.info("Login failed: {} : {} (URI={})", new Object[]{tokenCallback.errorCode(), tokenCallback.errorDescription(), tokenCallback.errorUri()});throw new LoginException(tokenCallback.errorDescription());}}

跟进查看处理逻辑:
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginCallbackHandler#handleTokenCallback

private void handleTokenCallback(OAuthBearerTokenCallback callback) throws IOException {this.checkInitialized();String accessToken = this.accessTokenRetriever.retrieve();try {OAuthBearerToken token = this.accessTokenValidator.validate(accessToken);callback.token(token);} catch (ValidateException var4) {log.warn(var4.getMessage(), var4);callback.error("invalid_token", var4.getMessage(), (String)null);}}

只要token内容不满足jwt结构,则会被展示在报错信息中。验证token有效性的逻辑详见:
org.apache.kafka.common.security.oauthbearer.internals.secured.LoginAccessTokenValidator#validate

public OAuthBearerToken validate(String accessToken) throws ValidateException {SerializedJwt serializedJwt = new SerializedJwt(accessToken);...}

测试一下,成功读取win.ini

漏洞复现

修复方案

目前官方已有可更新版本,建议受影响用户升级至最新版本:

https://github.com/apache/kafka/releases/tag/3.9.1

产品支持

网宿全站防护-WAF模块已支持对该漏洞利用攻击的防护,并持续挖掘分析其他变种攻击方式和各类组件漏洞,第一时间上线防护规则,缩短防护“空窗期”。

http://www.xdnf.cn/news/18380.html

相关文章:

  • 如何使用AI大语言模型解决生活中的实际小事情?
  • 【Protues仿真】基于AT89C52单片机的LCD液晶显示屏显示控制
  • 如何在 Axios 中处理多个 baseURL 而不造成混乱
  • portainer-ce汉化版下载
  • 从零开始的云计算生活——第四十九天,长路漫漫,kubernetes模块之持久化存储
  • 拆解本地组策略编辑器 (gpedit.msc) 的界面和功能
  • Kafka消息丢失的场景有哪些
  • ThingsBoard运行linux应用版本
  • FPGA设计中的信号完整性量化与优化:探索高速数字系统的关键路径
  • CVPR 2025 | 哈工大港大DeCLIP:解耦CLIP注意力实现开放词汇感知!
  • 车载中控:汽车的数字大脑与交互核心
  • 【RA-Eco-RA4E2-64PIN-V1.0 开发板】步进电机驱动
  • CISP-PTE之路--14文
  • JavaEE 初阶第二十期:网络编程“通关记”(二)
  • 数字隔离器:新能源系统的安全与效能革命
  • 【GM3568JHF】FPGA+ARM异构开发板 测试命令
  • 从零搭建 React 工程化项目
  • 深入解析鸿蒙 ArkTS 中的 @Local 装饰器
  • 【解决办法】wps的word文档编辑时字体的下方出现灰色的底色如何删除
  • CAM可视化卷积神经网络
  • 深度学习:入门简介
  • AI推理革命:从Sequential Thinking到Agentic AI的演进之路——揭秘大语言模型思维进化的四重奏
  • 上海人工智能实验室开源基于Intern-S1同等技术的轻量化开源多模态推理模型
  • logback-spring.xml 文件
  • 车载 GPS 与手机导航的终极对决:谁在复杂路况下更胜一筹?
  • UE5 将纯蓝图项目转为 C++ 项目
  • MongoDB 完整指南
  • 安全运维过程文档体系规范
  • 如何轻松永久删除 Android 手机上的短信
  • Android音频学习(十四)——加载音频设备