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

漏洞分析 | 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.dtcms.com/a/343933.html

相关文章:

  • selenium爬虫
  • 开源 vs 商业 DevOps 平台:如何选择最适合你的方案?
  • Elasticsearch高能指南
  • 学习:uniapp全栈微信小程序vue3后台(3)
  • 嵌入式Linux学习 -- 网络1
  • StarRocks启动失败——修复全流程
  • 姓名重名查询抖音快手微信小程序看广告流量主开源
  • 恢复性测试:定义、重要性及实施方法
  • Linux设备模型交互机制详细分析
  • 分段渲染加载页面
  • 第9课:本地功能集成
  • 宋红康 JVM 笔记 Day06|虚拟机栈
  • Seaborn数据可视化实战:Seaborn数据可视化基础-从内置数据集到外部数据集的应用
  • 学习游戏制作记录(合成表UI和技能树的UI)8.22
  • Python打卡Day49 CBAM注意力
  • 小迪安全v2023学习笔记(六十九讲)—— Java安全JWT攻防监控组件泄露接口
  • 北斗导航 | 基于MCMC粒子滤波的接收机自主完好性监测(RAIM)算法(附matlab代码)
  • 【C++组件】Elasticsearch 安装及使用
  • ODYSSEY:开放世界四足机器人的探索与操控,助力长范围任务
  • ref 简单讲解
  • 【前端教程】从基础到进阶:淘宝 HTML 界面“回到顶部”功能的交互升级实战
  • 刷题日记0822
  • Git 版本管理各模块知识点梳理
  • Logstash_Input插件
  • Chrome和Edge如何开启暗黑模式
  • 浏览器插件优化工具:bypass paywalls chrome
  • 【TrOCR】根据任务特性设计词表vocab.json
  • 今日科技热点 | NVIDIA AI芯片、5G加速与大数据平台演进——技术驱动未来
  • ESP32C5在espidf环境下报错5g bitmap contains only invalid channels= @xff
  • 龙虎榜——20250822