JAVA Object Serialization has been in use in many applications for a long time now. I find many enterprise applications that make use of JAVA Object Serialization to transfer objects from the client to sever and vice-versa. Testing such applications is a pain as it is not as straight forward as normal web applications that make use of simple parameter and value in HTTP POST data.
Some applications g-zip the serialized data before transferring it. Most common protocol for such applications is HTTP and RMI. There aren’t many easy techniques available today to test such applications and even if they do, they have certain shortcomings. At BlackHat EU this year, I discussed a technique that could be used to test such applications using currently available tools.
For testing web applications, the best tool available by far is Burp Proxy. It is one of my preferred tools to perform security assessments. You can refer to the whitepaper and the slides for details of the talk. In this blog post I will discuss the setup and a short introduction of how to carry out such assessments. The pre-requisites for using this technique are:
- Burp Proxy v.1.2.x
- JRuby v.1.4.x
- Buby v. 1.8.x
- Editor of your choice to edit the JRuby code
- Some knowledge of JAVA Object Serialization
First make sure that the usual 'JAVA_HOME' and 'PATH' environment variables are set for JAVA and JRuby. Once you have JAVA and JRuby setup properly, install the Buby gem. The details for installing Buby are given on its help page. Just make sure to copy the 'burp.jar' file in the JRuby load path. You can find the JRuby load path as follows in the IRB shell:
You can download the code that I released at BlackHat for the demo from here. It is a plug-in template that does three things:
- Injects an (J)IRB shell in the Burp Proxy
- Provides a method that de-serializes the JAVA Object stream (this can be modified to suit your needs e.g un-zip stream before de-serializing, etc.)
- Provides helper methods that use JAVA Reflection to access private variables and other useful methods
All the client-side jars should be placed in the lib folder provided by the plug-in. The plug-in will automatically import all the jars contained in this directory on startup. For the purpose of demonstration we would use a simple scenario where the JAVA serialized object is passed in a POST data of a HTTP request from the client to the server and vice-versa as shown in the figure below.
Once this sort of data is intercepted by Burp; our plug-in steps into action. Burp passes the entire message (headers + POST data) as a JAVA byte array to the plug-in which then splits the message into header and data and tries to de-serialize the JAVA Object. Once the JAVA Object is read, the plug-in spawns a (J)IRB shell exposing a variable obj which contains the JAVA Object. Now the pentester has the option of playing around with a complete development environment using the shell and editing the object at will. Once you are done modifying the object, you can use the helper methods to pack the object and create a new message (JAVA byte array) and return it to Burp to pass it to the application server.
For a more detailed demonstration watch the video