Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Spring-Kafka-POC-CVE-2023-34040 — Spring Kafka 反序列化漏洞 CVE-2023-34040 的 POC | Kitploit
工具/GitHubGitHub/contrast-security-oss/spring-kafka-poc-cve-2023-34040
漏洞分析漏洞利用Web应用程序漏洞利用Payload 开发
GitHubcontrast-security-oss/spring-kafka-poc-cve-2023-34040

Spring-Kafka-POC-CVE-2023-34040

Spring Kafka 反序列化漏洞 CVE-2023-34040 的 POC

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
45514个月前Kitploit 审核通过
分享

Spring Kafka 反序列化 POC

要求

  • Java 11
  • Maven
  • Docker(或 Kafka)

用法

首先启动 Dockerized Kafka 实例。这将启动 Kafka 并在端口 29092 上可用。

root@kitploit:~
docker-compose up

启动消费者应用程序。

root@kitploit:~
cd spring-kafka-consumer
mvn clean install
mvn spring-boot:run

这将构建并启动消费者应用程序。消费者将等待消息最长 10 分钟,然后关闭。

生产者

root@kitploit:~
cd spring-kafka-producer
mvn clean install
mvn spring-boot:run

这将构建并启动生产者应用程序。生产者将向 Kafka 队列发送一条消息,然后关闭。

Spring-Kafka-Consumer 配置

要使此漏洞成功,需要在消费者上启用以下一个或两个标志: CheckDeserExWhenValueNull CheckDeserExWhenKeyNull 这在消费者应用程序的 KafkaConsumerConfig.greetingKafkaListenerContainerFactory() 中完成。

Payload

有两个可以触发的 payload,默认使用 RCE payload。

拒绝服务(DoS)

要启用 DoS payload,请修改方法 KafkaApplication.sendGreetingMessage(),将作为 header 添加的 payload 改为 dosPayload,然后重新构建并运行生产者。 注意:由于 DoS 发生在消息读取时,且读取永远不会完成,因此消息仍保留在队列中,直到手动删除或消息保留时间到期。这增加了 DoS 的威力,因为它会使该队列无法使用,直到手动干预或保留时间到期。可能导致在 DoS 消息之后立即发送的消息丢失。

远程代码执行(RCE)

要启用 DoS payload,请修改方法 KafkaApplication.sendGreetingMessage(),将作为 header 添加的 payload 改为 rcePayload,然后重新构建并运行生产者。默认运行的命令是 touch /tmp/newfile,要查看攻击是否成功,请在 /tmp 目录下查找名为 newfile 的文件。如果在 Windows 上运行,可以将命令字符串修改为更合适的命令。这个 Gadget 只是一个 POC。要在现实世界中实现 RCE,需要在消费者的类路径上存在一个 gadget 类。

工作原理

拒绝服务攻击不需要消费者的类路径上存在任何特定的 gadget 类。它依赖于生成一个包含 Object 的 org.springframework.kafka.support.serializer.DeserializationException 类的修改版本。这使得我们可以轻松地将任何我们想要的 payload 添加到序列化对象中。这个修改后的类名为 xrg.springframework.kafka.support.serializer.DeserializationException(注意包名开头的 x)。一旦 payload 被注入,在本例中使用 java.util.Set 和 java.lang.Object 的 billion laughs 风格的攻击,它就会被序列化。然后修改二进制数据,将 x 改为 o,以匹配消费者期望的类名。

这个序列化的异常类随后被添加到消息头部的 springDeserializerExceptionValue 和 springDeserializerExceptionKey 中。如果键或消息为空,消费者就会读取它们。之后只需确保键或消息为空,消费者就会读取它。

Spring-Kafka 中有一些反序列化保护。在 ListenerUtils 中:

root@kitploit:~
public static DeserializationException byteArrayToDeserializationException(LogAccessor logger, byte[] value) {
    try {
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(value)) {

            boolean first = true;

            @Override
            protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                if (this.first) {
                    this.first = false;
                    Assert.state(desc.getName().equals(DeserializationException.class.getName()),
                            "Header does not contain a DeserializationException");
                }
                return super.resolveClass(desc);
            }


        };
        return (DeserializationException) ois.readObject();
    }
    catch (IOException | ClassNotFoundException | ClassCastException e) {
        logger.error(e, "Failed to deserialize a deserialization exception");
        return null;
    }
}

可以看到有一个检查,确保顶层类是 org.springframework.kafka.support.serializer.DeserializationException。但注意只检查了顶层类,而且只检查了类名(攻击者可以修改)。所以任何该层以下的 payload 都会被反序列化。

下载工具