Tuesday, September 7, 2010

Re-visiting JAVA De-serialization: It can't get any simpler than this !!


Well it's been a while since I have blogged. Been quite busy with work lately. Also I guess Lava is better at blogging stuff so I'll leave that to him :)

After my talk at BH EU earlier this year, there has been quite a lot of other really cool stuff been published on penetration testing of JAVA Thick/Smart clients. Check out Javasnoop especially. It has some pretty good features you would like to use. Many people that I spoke to recently said to me that modifying objects programatically using the IRB shell in DSer would be difficult and it would require the penetration tester to have indepth knowledge of the application's source code. Well; in the first place, penetration testing is a skill and it does require hard work, so understanding the application's internals is part and parcel of the job. But that being said DSer allows you to play around with JAVA objects using an interactive shell with some helper methods and is completely extensible. It was meant to be a template, to add your own stuff and extend it's capabilities.

In this post I will show you a technique which will alow us to extend DSer and simplify the processing of modifying JAVA Objects. Before we start I would like to thank my colleague Chilik Tamir for introducing me to the XStream library and helping with this idea. XStream is a library to serialize JAVA objects to XML and back. Now getting back to the topic. Let's assume that we have a complex object that we encounter in our request or response packet as follows:

HashMap = { key1 = String[], key2 = HashMap }

I have chosen internally available JAVA objects for simplicity, but they can be any custom objects you like. Now modifying this in via HEX bytes would be a difficult task as we will see later. For demostration purposes, i'll make use of the following app:
Fig. 1: Demo app to generate complex JAVA objects
This application will use the inputs we supply in the 3 text fields and create a HashMap similar to the one showed above when the "Both" button is pressed and send it to the backend server for processing. Once we capture this request in Burp, it would give an output similar to this:
Fig. 2: Request showing raw serialized data captured in Burp
Which will be de-serialized and rendered in the DSer shell as follows:

{ keyTwo = [Ljava.lang.String;@70ac2b, 
  keyOne = { hmKey1=Manish,
             hmKey3=Andlabs,
             hmKey2=Saindane
           }
}

We can see that the HashMap has 2 keys (ie. keyOne and keyTwo) with values as a String Array and a HashMap. Now I have added a few custom functions to DSer that will make use of the XStream library and convert the above mentioned JAVA serialized object to XML, save it as a temp file and open it in any XML editor of your choice for further editing. The resulting XML will look as follows:
Fig. 3: XML generated from the JAVA serialized object
Notice how nicely XStream has rendered the XML from the given JAVA object. We can clearly see the <string-array> and the <map> elements (highlighted above) with the individual entries. We can edit the entries and modify it as we want. Let's modify the XML as follows:
Fig. 4: XML after modification
We have removed the "Andlabs" entry from the String Array and added two extra entries (ie. "Lavakumar" and "Kuppan"). Also the "hmKey3" entry has been removed from the inner HashMap (highlighted above). Now as soon as we save this XML and close the editor, the code in DSer will convert this XML back to a JAVA object which will look similar to this:


{ keyTwo = [Ljava.lang.String;@9568c, 
  keyOne = { hmKey1=Manish,,
             hmKey2=Saindane
           }
}

The custom functions will then take care of serializing this object, editing the "Content-Length" header and preparing a new "message" to be sent to the application server. You can observe the modified data in Burp from the history tab.

Fig. 5: Edited request as shown in the Burp
So using this technique, modification of the JAVA objects becomes trivial and anyone with no prior knowledge of programming can edit the objects (as long as he/she knows  how to edit text or XML ;)). The screenshot shows the modified data being successfully passed to the server and rendered back to the output.
Fig 6: Modified data processed by the application
DSer is not just restricted to JAVA serialized objects, but (almost) any binary protocol that you can think of. So do not restrict your thinking and be creative. In this post I just showed you how you can extend DSer's capabilities and simplify the process of editing JAVA objects. You can do the same with any other protocol. All you need is some basic understanding of how the protocol works.

I'll add the the above mentioned custom methods to DSer and release it soon. Just need to clean up the code and make a few changes here and there. If anyone need's to try it out in the mean time, just ping me and I'll give you the source code. So until next time, Happy hacking !!