Log4j反序列化分析(CVE-2019-17571&CVE-2017-5645)
字数 1714 2025-08-26 22:11:45

Log4j反序列化漏洞深度分析(CVE-2019-17571 & CVE-2017-5645)

1. 漏洞概述

本文档将详细分析Log4j的两个反序列化漏洞:CVE-2019-17571(影响Log4j 1.2.x)和CVE-2017-5645(影响Log4j 2.x)。这两个漏洞的本质都是由于对从socket流中获取的数据没有进行过滤而直接进行反序列化操作,导致在特定条件下可实现远程代码执行。

2. CVE-2019-17571 (Log4j 1.2.x反序列化漏洞)

2.1 影响版本

  • Log4j 1.2.x <= 1.2.17

2.2 漏洞环境搭建

2.3 漏洞分析

2.3.1 漏洞原理

漏洞存在于SimpleSocketServer类中,该服务从socket流中获取数据后直接进行反序列化操作,没有对数据进行任何过滤或验证。如果环境中存在可利用的反序列化Gadget链(如commons-collections),攻击者可以构造恶意数据实现远程代码执行。

2.3.2 漏洞复现代码

// src/SocketDeserializeDemo.java
import org.apache.log4j.net.SimpleSocketServer;

public class SocketDeserializeDemo {
    public static void main(String[] args){
        System.out.println("INFO: Log4j Listening on port 8888");
        String[] arguments = {"8888", (new SocketDeserializeDemo()).getClass().getClassLoader().getResource("log4j.properties").getPath()};
        SimpleSocketServer.main(arguments);
        System.out.println("INFO: Log4j output successfuly.");
    }
}

2.3.3 配置文件示例

# src/resources/log4j.properties
log4j.rootCategory=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.threshold=DEBUG
log4j.appender.stdout.layout.ConversionPattern=[%d{yyy-MM-dd HH:mm:ss,SSS}]-[%p]-[MSG!:%m]-[%c\:%L]%n

2.3.4 关键代码分析

  1. SimpleSocketServer.main()方法调用了SocketNode
  2. SocketNode类实现了Runnable接口:
    • 构造方法从socket流中获取数据并封装为ObjectInputStream对象
    • run()方法中直接调用readObject()进行反序列化操作
  3. 由于没有数据过滤机制,导致反序列化漏洞

2.4 利用条件

  • 目标系统使用Log4j 1.2.x <= 1.2.17
  • 目标系统classpath中存在可利用的反序列化Gadget链(如commons-collections 3.1)

3. CVE-2017-5645 (Log4j 2.x反序列化漏洞)

3.1 影响版本

  • Log4j 2.x <= 2.8.1

3.2 漏洞环境搭建

3.3 漏洞分析

3.3.1 漏洞原理

与Log4j 1.x的漏洞类似,漏洞存在于TcpSocketServer类中,该服务接收到的数据会被转换为ObjectInputStream对象并直接进行反序列化操作,没有进行任何过滤或验证。

3.3.2 漏洞复现代码

// src/main/java/Log4jSocketServer.java
import org.apache.logging.log4j.core.net.server.ObjectInputStreamLogEventBridge;
import org.apache.logging.log4j.core.net.server.TcpSocketServer;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Log4jSocketServer {
    public static void main(String[] args){
        TcpSocketServer<ObjectInputStream> myServer = null;
        try {
            myServer = new TcpSocketServer<ObjectInputStream>(8888, new ObjectInputStreamLogEventBridge());
        } catch (IOException e){
            e.printStackTrace();
        }
        myServer.run();
    }
}

3.3.3 Maven依赖配置

<!-- maven文件pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>log4j-2.x-rce</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.8.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.8.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.1</version>
        </dependency>
    </dependencies>
</project>

3.3.4 关键代码分析

  1. 程序在8888端口监听,接收数据并转换为ObjectInputStream对象
  2. handler.start()中调用SocketHandler类的run方法
  3. ObjectInputStream对象被传入ObjectInputStreamLogEventBridge类的logEvents方法
  4. 反序列化操作发生在logEvents方法中

3.4 利用条件

  • 目标系统使用Log4j 2.x <= 2.8.1
  • 目标系统classpath中存在可利用的反序列化Gadget链(如commons-collections 3.1)

4. 漏洞修复建议

4.1 CVE-2019-17571修复方案

  • 升级到Log4j 1.2.18或更高版本
  • 如果无法升级,应避免使用SimpleSocketServer功能
  • 在反序列化前添加数据验证机制

4.2 CVE-2017-5645修复方案

  • 升级到Log4j 2.8.2或更高版本
  • 如果无法升级,应避免使用TcpSocketServer功能
  • 在反序列化前添加数据验证机制

5. 总结

这两个Log4j反序列化漏洞(CVE-2019-17571和CVE-2017-5645)都源于对socket流数据的不安全反序列化操作。漏洞利用的关键在于目标系统classpath中存在可利用的反序列化Gadget链。开发人员应及时升级受影响版本,或采取其他缓解措施防止漏洞被利用。

Log4j反序列化漏洞深度分析(CVE-2019-17571 & CVE-2017-5645) 1. 漏洞概述 本文档将详细分析Log4j的两个反序列化漏洞:CVE-2019-17571(影响Log4j 1.2.x)和CVE-2017-5645(影响Log4j 2.x)。这两个漏洞的本质都是由于对从socket流中获取的数据没有进行过滤而直接进行反序列化操作,导致在特定条件下可实现远程代码执行。 2. CVE-2019-17571 (Log4j 1.2.x反序列化漏洞) 2.1 影响版本 Log4j 1.2.x <= 1.2.17 2.2 漏洞环境搭建 Log4j 1.2.17 Debian系统 JDK 1.7 下载地址: Apache Log4j 1.2.17 2.3 漏洞分析 2.3.1 漏洞原理 漏洞存在于 SimpleSocketServer 类中,该服务从socket流中获取数据后直接进行反序列化操作,没有对数据进行任何过滤或验证。如果环境中存在可利用的反序列化Gadget链(如commons-collections),攻击者可以构造恶意数据实现远程代码执行。 2.3.2 漏洞复现代码 2.3.3 配置文件示例 2.3.4 关键代码分析 SimpleSocketServer.main() 方法调用了 SocketNode 类 SocketNode 类实现了 Runnable 接口: 构造方法从socket流中获取数据并封装为 ObjectInputStream 对象 run() 方法中直接调用 readObject() 进行反序列化操作 由于没有数据过滤机制,导致反序列化漏洞 2.4 利用条件 目标系统使用Log4j 1.2.x <= 1.2.17 目标系统classpath中存在可利用的反序列化Gadget链(如commons-collections 3.1) 3. CVE-2017-5645 (Log4j 2.x反序列化漏洞) 3.1 影响版本 Log4j 2.x <= 2.8.1 3.2 漏洞环境搭建 Log4j 2.8.1 Debian系统 JDK 1.7 下载地址: Apache Log4j 2.8.1 3.3 漏洞分析 3.3.1 漏洞原理 与Log4j 1.x的漏洞类似,漏洞存在于 TcpSocketServer 类中,该服务接收到的数据会被转换为 ObjectInputStream 对象并直接进行反序列化操作,没有进行任何过滤或验证。 3.3.2 漏洞复现代码 3.3.3 Maven依赖配置 3.3.4 关键代码分析 程序在8888端口监听,接收数据并转换为 ObjectInputStream 对象 在 handler.start() 中调用 SocketHandler 类的 run 方法 ObjectInputStream 对象被传入 ObjectInputStreamLogEventBridge 类的 logEvents 方法 反序列化操作发生在 logEvents 方法中 3.4 利用条件 目标系统使用Log4j 2.x <= 2.8.1 目标系统classpath中存在可利用的反序列化Gadget链(如commons-collections 3.1) 4. 漏洞修复建议 4.1 CVE-2019-17571修复方案 升级到Log4j 1.2.18或更高版本 如果无法升级,应避免使用 SimpleSocketServer 功能 在反序列化前添加数据验证机制 4.2 CVE-2017-5645修复方案 升级到Log4j 2.8.2或更高版本 如果无法升级,应避免使用 TcpSocketServer 功能 在反序列化前添加数据验证机制 5. 总结 这两个Log4j反序列化漏洞(CVE-2019-17571和CVE-2017-5645)都源于对socket流数据的不安全反序列化操作。漏洞利用的关键在于目标系统classpath中存在可利用的反序列化Gadget链。开发人员应及时升级受影响版本,或采取其他缓解措施防止漏洞被利用。