Insecure deserialization risks in the JAVA world
INTRODUCTION
OWASP Top 10 Application Security Risks – 2017 was just published at the end of last month! In which severe risks added to the previous 2013 version include: A4XML external entity injection risk, A8 insecure deserialization, and A10 insufficient logging and monitoring. In this column we will introduce A8 insecure deserialization. We will use the Java language to demonstrate the deserialization process, and use the vulnerabilities of executing the deserialization remote code of CVE2017-12149 JBOSS Application Server 5.X/6.X as the example.
What is DESERIALIZATION?
When we hear deserialization, it is obvious that we must first understand what “serialization” is.
We found this text description from a tutorial on the official website of Java:
To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object.
Now let us take a look at this simple sample code below:

What it means is to create a text string object, and then serialize it into the file “serialization.demo,” save it onto the hard drive, and then read the file back into the program, deserialize it and output the string. The execution process is as follows:

In which the key is to observe the “serialization.demo” file; since it is in the byteStream format, we will use xxd to convert the binary format into characters we can understand. We can see that the written string is indeed packed in the file.
In the next step, we will advance into “implementing” a serializable MyObject object and try to perform deserialization:

We implemented a MyObject object and printed the string serializable!!! When during readObject.The execution situation is as follows:

As expected, it first printed the string serializable!!! and then printed the string carried out by the object.
Did you notice that we base64 encoded the data again after every two outputs? What is interesting is that the deserialized objects in Java all have a rO0AB prefix; this is an important feature when executing penetration tests.
What is INSECURE DESERIALIZATION in Java?
After we looked at the simple principle of serialization, now it is time to get into our topic! Why is it that after deserialization is used as parameters and is modified by malicious attackers, it can easily achieve the attack effect of remote code execution?
We will use reverse causation and first use the thinking and program code of the ysoserial attack code generation tool ( https://github.com/frohoff/ysoserial ), which is a must-have for Java deserialization attacks right now, to quickly think about the deserialization problem.
From the instructions we can see that the Payload type must be entered, and each type of Payload has its corresponding Java library dependency with deserialization problems; so why do Payloads have dependency?

Let us use the fifth item in the most common CommonCollections series for our discussion on why deserialization occurs, and finally use a real case: The vulnerabilities of executing the deserialization remote code of CVE2017-12149 JBOSS Application Server 5.X/6.X as example.
In the CommonCollection5.Java source code of ysoserial, we can see that the comment part at the top was used to execute deserialization to achieve executing “Gadget Chain” with remote codes. The so-called “Gadget Chain” means using the reflective features of the Java language to combine the functions in the defined categories of the previous Dependency library, and forming a function chain that can bypass the Java mechanism and be executed by force, and then send the byteStream that was deserialized by this function chain to the server end to let the server achieve the remote code execution we want.

The writing technique of this Gadget Chain is to combine normal execution functions with the ChainedTransformer in the Apache CommonCollections using reflective methods; once the function transform() can be triggered, the InvokerTransformer in the chain can be connected and executed successfully. Now let us look at it again from the top layer; the trigger part relies on using AnnotationInvocationHandler that Java originally has as the initial key trigger element, in which the entrySet() is known as the magic method. It will trigger the invoke method in Map and then passed to the invoke method of the inner AnnotationInvocationHandler, and finally be wrapped in the LazyMap of CommonCollections; just place the previous ChainedTransformer inside and it can be executed successfully.

CVE2017-12149 JBOSS AS 5.X/6.X Insecure Deserialization to RCE

Now let’s perform a simple code review for JBOSS AS; this loophole occurs in URL path/invoker/readonly; after tracing, it was discovered that the actual program is located in the ReadOnlyAccessFilter of org.jboss.invocation.http.servlet, in which deserialization was performed to the inputted data.

Since the program-end was deserialized, let us start constructing our payload!
Since Runtime.getRuntime().exec() will be executed at the end, problems will occur when final parsing is added; that’s why we will use the following tool to quickly encode the execute statement ( http://jackson.thuraisamy.me/runtime-exec-payloads.html ) into base64 format:


Conclusion
Since attackers use the side-effects of Java’s reflect mechanism to execute all actions before the object was returned, it causes all Payloads to be executed before deserialization unpacks byteStream and shows errors. Once attackers learn which type of libraries there are in the backend program, they can combine the different functions in the libraries, call functions across different libraries and combine them into Gadget Chains, and then finally execute Runtime.getRuntime().exec() to execute any malicious codes.
Simply put, a user inserts an 110V electrical appliance into a 220V outlet; even though the outlet looks the same, but the user doesn’t know the voltage of the outlet; they only realize that the voltage doesn’t match after the outlet and appliance is electrified and the appliance burns. Similarly, deserialization also enters the system through byteStream containing remote code execution, and after the Payload was executed then it was discovered that the format of this byteStream has problems.