NetSPI Blog

Pentesting Java Thick Applications with Burp JDSer

Khai Tran
October 8th, 2012

Recently I stumbled upon a Java Rich Client pentest project. Fortunately, the communication was made via HTTP, so it was possible to manipulate requests and response with our favorite tool, Burp.

Unfortunately, the app has been transmitting data in serialized Java format. So the intercepted requests and responses look like this:

After a little bit of Google searching, I came across this very well-written article about Java serialization and tried out his tool: BurpDSer. After scratching my head off for a few hours, installing dependencies, and still not getting it to work (there’s some problem with IRB Shell not popping up), I began searching for alternative solutions. Luckily I found this excellent SANS blog which outlined high level steps to make a Burp Deserialization plugin. So I put together a simple implementation of that idea. I hope it will be helpful for pentesters as well as developers in dealing with serialized Java applications.

In this blog post, I will cover following information:

  1. Setup Burp proxy
  2. Inspect Java client
  3. Run BurpJDSer
  4. Fuzz for server errors
  5. Bypass client side controls
  6. Remediation path
  7. Introduction

Introduction

BurpJDSer is a Burp plugin that will deserialize/serialize Java request and response to and from XML with the help of Xtream library. BurpJDSer utilizes native Java technology to deserialize/serialize Java request, thus no additional software is required.

Let’s consider this dummy Java app that communicates with a servlet via HTTP. It’s a very simple search box which sends SearchObject to a server. Server responses with a SearchResult object back. If it indicates that client has admin privilege, the gray text will become red.


Figure 1: Sample Client

Step 1: Set up Burp proxy

  • If the program is started from the command line (java –jar client.jar), add the following flags:Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=<Burp port>
  • If the program is started from browser (Java Web Applet), make sure JVM set to use browser proxy settings (Windows Control Panel > Java > Network Settings) or explicitly set to use Burp proxy.

    Figure 2: Configure Java Network Settings on Windows

  • If the program communicates via HTTPS, import PortSwigger Root Certificate to your favorite browser.

Also consider these instructions from Burp author if the above method fails to intercept HTTP traffic:
http://blog.portswigger.net/2009/04/intercepting-thick-client.html

Step 2: Download and Inspect Client jar

  • Download the Java client to your computer. This can be done viewing HTML response from the page that loads Java applet. A sample applet tag that reveals location of the client jar file: <applet code=”com.example.client” archive=”SerializedClient.jar”>
  • Use any Java decompiler to decompile the target jar file. My favorite is JD-GUI from http://java.decompiler.free.fr/
  • What to look for: any hardcoded passwords, backdoors, communication methods, SQL queries,etc.

Step 3: Run the BurpJDSer plugin

Step 4: Inspecting traffic

  • When setup properly, we should see some traffic captured by Burp.
  • Essentially, what the plugin does is to convert serialized request to XML for you to modify, than convert back from XML to serialized object before sending to the server

  • Similarly for the response, the plugin will deserialize to XML and then serialize back to Java object so that it won’t break the client.

    In this example, SSN is included in the response, but not shown in the client.

Step 5: Fuzzing for server error with Repeater and Intruder

  • This plugin will also perform conversion of Java object when processed in Burp Repeater/Intruder for your convenience
  • Fuzz for server vulnerabilities such as SQL Injection, Command Injection, Authorization Bypass, etc.

Step 6: Test for client-side authorization bypass

The plugin also has support for serializing requests/responses from XML to Java format. This may come in handy in case you need to bypass client check or enable hidden features of the client. Below is an example of how to do this

  • Intercept server response
  • Find and modify hidden parameter to access hidden priviledges. In this example, I set isAdmin parameter to “true” in order to bypass client-side restriction.

Remediation path

  • Don’t rely on Java serialization as a method of encryption
  • Don’t include redundant data in the response, even if it’s not displayed on client GUI
  • Obfuscate your code: choose a obfuscator that also encrypts String constants such as ZelixClassMaster
  • Validate input serialized data
  • Consider sealing and signing serialized objects with javax.crypto.SealedObject

References

The source code and executable are available at: https://github.com/khai-tran/BurpJDSer.
Feel free to leave comments there. Thanks to Scott and Antti for your feedback on the tool.

You may also want to check out other tools of the same category:
JAVA Snoop
BurpDSer
http://xstream.codehaus.org/
http://pen-testing.sans.org/blog/2011/10/18/tips-for-fat-client-web-app-and-mobile-pen-testing-serialized-object-communication-using-the-burp-suite
http://www.ibm.com/developerworks/java/library/j-5things1/index.html

Happy hacking!

9
Leave a Reply

avatar
4 Comment threads
5 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Dave TaylorJayAadiKhai TranAaditya Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest
Notify of
Aaditya
Guest
Aaditya

Hi Khai,

On executing the commands on step 3, nothing is happening.

The cursor just blinks.

Please help

Regards,
Aadi

Jay
Guest
Jay

I have a few doubts as am not able to get this command executed properly. Below is the error that I am getting. D:\jar>java -classpath burp.jar;burpjdser.jar;xstream-1.4.2.jar;”D :\jar/*” burp.StartBurp Exception in thread “main” java.lang.UnsupportedClassVersi : burp/IHttpReq uestResponse : Unsupported major.minor version 51.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(Unknown Source) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$000(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at burp.o7.(Unknown Source) at burp.ue.(Unknown Source) at burp.nxb.b(Unknown Source) at burp.nxb.a(Unknown Source) at burp.nxb.(Unknown Source) at burp.kpb.(Unknown Source) at burp.wnb.p(Unknown Source) at burp.xf.a(Unknown… Read more »

Jay
Guest
Jay

Hi Khai,

I was able to start Burp using the commands and was able to intercept traffic as well but the problem is I am still not able to see de serialized data in burp.

Need help.

Also, my content type; unlike yours; says:

Content-type: application/octet-stream

Could this mean that this method that you have described here is not going to work on my app?

Thanks in advance
Jay

Dave Taylor
Guest
Dave Taylor

Hi Khai,

Do you have any plans to get your tool added to the Burp’s BApp Store?

Regards,
Dave