漏洞简介
Apache Kafka是一个分布式数据流处理平台,可以实时发布、订阅、存储和处理数据流。Kafka Connect是一种用于在kafka和其他系统之间可扩展、可靠的流式传输数据的工具。攻击者可以利用基于SASLJAAS 配置和SASL 协议的任意Kafka客户端,对Kafka Connect worker 创建或修改连接器时,通过构造特殊的配置,进行JNDI 注入来实现远程代码执行。
影响版本
2.4.0<=Apache kafka<=3.3.2
修复方案
更新Apache Kafka至官方最新版本
环境搭建
通过https://github.com/vulhub/vulhub搭建
漏洞复现
exp可参考:
https://github.com/projectdiscovery/nuclei-templates/blob/5d90e8275084b0ae9166ec38cacd22e5a5a94fb8/http/vulnerabilities/apache/apache-druid-kafka-connect-rce.yaml
发起攻击请求:
构造payload ,执行新建/tmp/test.txt文件
验证漏洞存在,文件新建成功
开启RASP后发起攻击:
在业务优先模式下,RASP会出现JNDI注入的告警,拦截最终的命令执行
堆栈信息为
在防护模式下将直接在JNDI注入处被拦截
堆栈信息为
漏洞分析
org
.apache
.kafka
.clients
.producer
.KafkaProducer
#KafkaProducer
(
java
.util
.Properties
)
跟进到
org
.apache
.kafka
.clients
.producer
.KafkaProducer
#KafkaProducer
(
java
.util
.Properties
org
.apache
.kafka
.common
.serialization
.Serializer
<
K
>,
org
.apache
.kafka
.common
.serialization
.Serializer
<
V
>)
调用
org
.apache
.kafka
.common
.utils
.Utils
#propsToMap
对传入对象进行处理
将map型的对象传入
org
.apache
.kafka
.clients
.producer
.KafkaProducer
#KafkaProducer
(
java
.util
.Map
<
java
.lang
.String
,
java
.lang
.Object
>
org
.apache
.kafka
.common
.serialization
.Serializer
<
K
>
org
.apache
.kafka
.common
.serialization
.Serializer
<
V
>)
之后调用
org
.apache
.kafka
.clients
.producer
.ProducerConfig
#appendSerializerToConfig
将返回的newConfigs传入
org
.apache
.kafka
.clients
.producer
.ProducerConfig
#ProducerConfig
(
java
.util
.Map
<
java
.lang
.String
,
java
.lang
.Object
>)
将配置参数传入
org
.apache
.kafka
.clients
.producer
.KafkaProducer
#KafkaProducer
(
org
.apache
.kafka
.clients
.producer
.ProducerConfig
,
org
.apache
.kafka
.common
.serialization
.Serializer
<
K
>
org
.apache
.kafka
.common
.serialization
.Serializer
<
V
>
org
.apache
.kafka
.clients
.producer
.internals
.ProducerMetadata
,
org
.apache
.kafka
.clients
.KafkaClient
org
.apache
.kafka
.clients
.producer
.internals
.ProducerInterceptors
<
K
,
V
>
org
.apache
.kafka
.common
.utils
.Time
)
org
.apache
.kafka
.clients
.producer
.KafkaProducer
#newSender
调用到
org
.apache
.kafka
.clients
.ClientUtils
#createChannelBuilder
赋值后调用
org
.apache
.kafka
.common
.network
.ChannelBuilders
#clientChannelBuilder
这里对值做了一个判断后调用
org
.apache
.kafka
.common
.network
.ChannelBuilders
#create
Create方法中得到map型的configs后进行switch,得到SaslChannelBuilder类型channelBuilder的对象,switch结束后调用了
org
.apache
.kafka
.common
.network
.SaslChannelBuilder
#configure
org
.apache
.kafka
.common
.network
.SaslChannelBuilder
#configure
进入循环后到
org
.apache
.kafka
.common
.security
.authenticator
.LoginManager
#acquireLoginManager
判断值后到
org
.apache
.kafka
.common
.security
.authenticator
.LoginManager
#LoginManager
跟进到
org
.apache
.kafka
.common
.security
.authenticator
.AbstractLogin
#login
调用
javax
.security
.auth
.login
.LoginContext
#login
调用
javax
.security
.auth
.login
.LoginContext
#invokePriv
调用
javax
.security
.auth
.login
.LoginContext
#invoke
进行逻辑判断后调用initialize方法
Initialize中得到userProvider
user.provider.url通过jndi提供
调用
com
.sun
.security
.auth
.module
.JndiLoginModule
#login
调用
com
.sun
.security
.auth
.module
.JndiLoginModule
#attemptAuthentication
通过
javax
.naming
.InitialContext
#lookup
(
java
.lang
.String
)
执行userProvider的值
由于RASP对javax.naming.InitialContext.lookup调用做了防护策略检测,所以会在此处拦截。
Reference
- https://github.com/luelueking/Java-CVE-Lists#cve-2023-25194
- https://blog.snert.cn/index.php/2023/04/04/cve-2023-25194-kafka-jndi-injection-%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/
原文始发于微信公众号(悬镜安全说):【高危】 Apache Kafka 远程代码执行漏洞复现及攻击拦截 (CVE-2023-25194)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论