Author: h0we777
Disclaimer: This article is only for study and research. It is strictly prohibited to engage in illegal activities. Any consequences shall be borne by the user himself.
The deserialization vulnerability is based on serialization and deserialization operations.
0x01 serializationSerialization is often used to store the object state of the program in the file system in binary form, and then deserialize the serialized object state data in another program to recover the object. Simply put, program objects can be passed in two programs in real time based on serialized data.
0x02 java deserializationThe process of converting java objects into sub section sequences is stored in memory or files to realize cross platform communication and persistent storage. The writeObject() method of ObjectOutputStream class can realize serialization. Deserialization refers to the process of restoring the sequence of child sections to java objects. Accordingly, the readObject() method of ObjectInputStream class is used for deserialization. The following is the example code for serializing a string object, storing it in a local file, and then recovering it through deserialization:
public static void main(String args[]) throws Exception { String obj = "hello world!"; // Writes the serialized object to the file object.db FileOutputStream fos = new FileOutputStream("object.db"); ObjectOutputStream os = new ObjectOutputStream(fos); os.writeObject(obj); os.close(); // Read data from the file object.db FileInputStream fis = new FileInputStream("object.db"); ObjectInputStream ois = new ObjectInputStream(fis); // Recover the object through deserialization obj String obj2 = (String)ois.readObject(); ois.close(); }
The problem is that if a java application deserializes user input, that is, untrusted data, an attacker can construct malicious input to make the deserialization generate unexpected objects, which may lead to arbitrary code execution in the generation process. Therefore, the root of this problem is that the class ObjectInputStream does not limit the type of generated object during deserialization; If deserialization can set the white list of java types, the impact of the problem is much smaller.
0x03 causeIf a java application deserializes user input, that is, untrusted data, an attacker can construct malicious input to make the deserialization generate unexpected objects, which may lead to arbitrary code execution in the generation process.
Overriding detection in the resolveClass method of an ObjectInputStream object can be bypassed.
Use third-party classes for blacklist control. It is easy to slip through the net. If new functions are added later, new vulnerability utilization methods may be introduced.
Unsafe base library used:
commons-fileupload 1.3.1 commons-io 2.4 commons-collections 3.1 commons-logging 1.2 commons-beanutils 1.9.2 org.slf4j:slf4j-api 1.7.21 com.mchange:mchange-commons-java 0.2.11 org.apache.commons:commons-collections 4.0 com.mchange:c3p0 0.9.5.2 org.beanshell:bsh 2.0b5 org.codehaus.groovy:groovy 2.3.9 org.springframework:spring-aop 4.1.4.RELEASE0x04 principle
public class test{ public static void main(String args[])throws Exception{ //Define obj object String obj="hello world!"; //Create an "object" data file containing information about the deserialization of objects FileOutputStream fos=new FileOutputStream("object"); ObjectOutputStream os=new ObjectOutputStream(fos); //The writeObject() method writes the object object to the object file os.writeObject(obj); os.close(); //Deserialize obj objects from files FileInputStream fis=new FileInputStream("object"); ObjectInputStream ois=new ObjectInputStream(fis); //Recovery object String obj2=(String)ois.readObject(); System.out.print(obj2); ois.close(); } }0x05 purpose
Save the byte sequence of the object to the hard disk forever, usually in a file;
A sequence of bytes that transfers objects over a network.
0x06 application scenarioGenerally speaking, after the server is started, it will not be closed again. However, if it is forced to restart and the user session is still performing corresponding operations, it is necessary to use serialization to save the session information on the hard disk. After the server is restarted, it will be loaded again. This ensures that the user information is not lost and realizes permanent storage.
In many applications, some objects need to be serialized to leave the memory space and live in the physical hard disk, so as to reduce the memory pressure or facilitate long-term storage.
For example, the most common is the session object in the web server. When 100000 users access concurrently, 100000 session objects may appear, and the memory may not be enough. Therefore, the web container will serialize some seesion s to the hard disk first, and then restore the objects saved in the hard disk to the memory when they need to be used.
http parameters, cookie s, seesion and storage methods may be base64(rO0), compressed base64(H4sl), MII, etc.
The protocols included in Servlets HTTP, Sockets and Session manager include JMX, RMI, JMS, JNDI, etc. (\ xac\xed)
xml Xstream, xmlcoder, etc. (HTTP body: content type: application / XML)
json(Jackson, fastjson) is included in the HTTP request.
0x07 detection processDeserialization is generally used in business scenarios such as importing template files, network communication, data transmission, log format storage or DB storage. Therefore, the audit process focuses on these functional modules.
After finding the corresponding function module, retrieve the call to the deserialization function in the source code to statically find the input point of deserialization, such as the following function:
ObjectInputStream.readObject ObjectInputStream.readUnshared XMLDecoder.readObject Yaml.load XStream.fromXML ObjectMapper.readValue JSON.parseObject
After determining the deserialization input point, check whether the Class Path of the application contains Apache Commons Collections and other dangerous libraries (other libraries supported by ysoserial can also be included). If it does not contain dangerous libraries, check some code areas involving command and code execution to prevent the programmer's code from being lax and causing bug s. If there is a dangerous library, use ysoserial to attack.
0x07 API implementation in Java
Location: java.io.objectoutputstream
Serialization: ObjectOutputStream class - > writeobject()
Note: this method serializes the obj object specified by the parameter, writes the sub section sequence to a target output stream, and gives the file a. ser extension according to the standard convention of java
Deserialization: objectInputStream class - > readObject ()
Note: this method reads the sequence of sub sections from a source input stream, deserializes them into an object, and returns them.
0x08 object serialization of serializable and Externalizable interface classesOnly objects of classes that implement Serializable and Externalizable interfaces can be serialized.
The Externalizable interface inherits from the Serializable interface. The classes that implement the Externalizable interface completely control the serialization behavior, while the classes that only implement the Serializable interface can adopt the default serialization method.
Object serialization includes the following steps:
1. Create an object output stream, which can wrap another type of target output stream, such as file output stream;
2. Write the object through the writeObject() method of the object output stream.
Object deserialization steps are as follows:
1. Create an object input stream, which can wrap another type of source input stream, such as file input stream;
2. Read the object through the readObject() method of the object input stream.
0x09 Apache Commons Collections9.1 introduction
Apache Commons Collections is a third-party basic library that extends the Collection structure in the java standard library. It contains many jar toolkits. It provides many powerful data structures and implements various Collection tool classes.
org.apache.commons.collections provides a class package to extend and add the standard java collection framework, that is, these extensions also belong to the basic concept of collection, but have different functions. Collection in java can be understood as a group of objects, and the objects in collection are called collection objects. Concrete collections are set, list, queue, etc., which are collection types. In other words, collection is an abstraction of set, list and queue.
As an important component of Apache open source project, commons collections is widely used in the development of various java applications. It is precisely because of the implementation of these classes and method calls in a large number of web applications that lead to the universality and severity of deserialization vulnerabilities.
9.2 project address
Official website: http://commons.apache.org/proper/commons-collections/ Github: https://github.com/apache/commons-collections
9.3 POC structure
Construct an object——> Deserialization——> Submit data
Map class - > transformedmap
The Map class is a data structure that stores key value pairs. Apache Commons Collections implements transformaedmap. When an element is added / deleted / modified (i.e. key or value: the data storage form in the collection is an index corresponding to a value, just like the relationship between ID card and person), this class will call the transform method to automatically perform specific modification and transformation. The specific change logic is defined by the Transformer class. In other words, when the data in the TransformedMap class changes, you can automatically make some special changes to it, such as changing it back when the data is modified; Or when the data changes, perform some operations set in advance. As for what kind of operation or transformation will be performed, this is set in advance by the user. This is called transform. Obtain a TransformedMap through the TransformedMap. Modify() method:
TransformedMap.decorate method,The expectation is right Map Class. The method has three parameters. The first parameter is to be converted Map object The second parameter is Map Within object key The conversion method to go through (can be a single method, chain or empty) The third parameter is Map Within object value Conversion method to go through
Transformer interface
Defines a functor interface implemented by classes that transform one object into another. Function: interface to Transformer All classes have the ability to convert one object into another
1)Construct a Map And a program that can execute code ChainedTransformer, 2)Generate a TransformedMap example 3)utilize MapEntry of setValue()Function pair TransformedMap Modify the key value in 4)Trigger our previously constructed chain Transforme(Namely ChainedTransformer)Automatic conversion
Annotationinvocationhandler class
This class has a member variable memberValues yes Map type AnnotationInvocationHandler of readObject()Pair in function memberValues Each item of the called setValue()Function pair value Values.
1)First construct a Map And a program that can execute code ChainedTransformer, 2)Generate a TransformedMap example 3)instantiation AnnotationInvocationHandler,And serialize it, 4)When triggered readObject()During deserialization, command execution can be realized. POC The execution process is TransformedMap->AnnotationInvocationHandler.readObject()->setValue()- The vulnerability was successfully triggered0x10 vulnerability mining
1.Vulnerability trigger scenario stay java Written web Application and web Between servers java A large number of serialized objects are usually sent, such as the following scenarios: 1)HTTP Parameters in the request, cookies as well as Parameters. 2)RMI Protocol, widely used RMI The protocol is based entirely on serialization 4)JMX Also used to handle serialized objects 5)The custom protocol is used to receive and send the original java object 2. Vulnerability mining (1)Determine the deserialization input point First, find out readObject Method call. After finding it, carry out the next injection operation. Generally, you can find it by the following methods: 1)Source code audit: find the "target" that can be used, that is, determine to call the deserialization function readObject Where to call. 2)Capture the network behavior of the application and look for serialized data, such as wireshark,tcpdump etc. Note: java Serialized data is generally marked with( ac ed 00 05)start, base64 The coded features are rO0AB. (2)Review the application of Class Path Does it contain Apache Commons Collections library (3)Generate deserialized payload (4)Submit our payload data0x11 hazards
-
Perform logical control (e.g. variable modification, login bypass)
-
Code execution
-
Command execution
-
Denial of service
-
Remote code injection
Authentication and signature
Authentication is used to prevent applications from accepting the attacker's abnormal input. You should know that many serialized and deserialized services are not provided to users, but to the service itself. For example, storing an object to the hard disk and sending an object to another service. These services are protected by adding signatures. For example, for stored objects The data is signed to verify the identity of the calling source. As long as the attacker cannot obtain the key information, it cannot send data to the service interface for deserialization, and there is no way to launch a deserialization attack.
Restrict serialized and deserialized classes
In anti serialization vulnerabilities, attackers need to build invocation chains, and invocation chains are constructed based on the default method of classes. However, most of the classes have very few default logic methods and can not be linked into complete call chains. Therefore, in the invocation chain, unconventional classes are usually involved.
In the configuration file of Fastjson, a blacklist is maintained, including many method classes that may execute code. These classes are some tool classes that are usually used but will not be serialized. Therefore, they can be included in the blacklist. It is not allowed to deserialize these classes (in the latest version, they have been changed to hashcode).
RASP detection
RASP (runtime application self protection). RASP adds a rule detection in the call of these key functions through hook and other methods. This rule will judge that the application demonstration executes the logic that is not the application itself, and can intercept the deserialization vulnerability attack without modifying the code.
0x13 summaryIf there is any mistake, please correct it.
0x14 learn more about safetyWelcome to pay attention to our safety official account, learn more safety knowledge!!!
Welcome to pay attention to our safety official account, learn more safety knowledge!!!
Welcome to pay attention to our safety official account, learn more safety knowledge!!!