Search This Blog

Monday, June 3, 2019

Exploiting Java DeSerialization

Recently, in one of my pentesting adventures, I encountered a Java Server Faces site.  In JSF, the view for the user of the website is stored in a ViewState value.  Although there are both server side and client side configurations to store the ViewState, both are vulnerable to deserialization attacks (uh-oh).

If it is stored on the server side, the javax.faces.ViewState sends the id with the request.  This id is a serialized object concerning the view.  If it's on the client side, it still sends another serialized object (base64 url encoded).  It is important to know that the ViewStates must not be encrypted for this attack to occur so easily.  Today, these are mostly encrypted, but if the values for authentication and encryption gets leaked, all it takes is a simple encryption script (and some base64 re-encoding).  By default, the ViewState is encrypted with DES (padded with pkcs7 because web) and HMAC-SHA1 is used to authenticate the view state.

I will be using ysoserial to help create the POP gadgets (property oriented programming, the ROP equivalent for higher level languages) to create payloads (let us assume that encryption is not enabled.  Also, feel free to make your own custom POP gadgets if you have the time).  The java software for view states involves Common Collections 3.1 (this might change depending on the version, so check with wappalyzer or just guess and check your payloads or enumerate more), which for some reason is labeled as Common Collection 5 on ysoserial.
Then, a command like the following:
java -jar ysoserial.jar CommonsCollections5 'command' | base64
creates the base64 encoded payload you can send back by intercepting the request with a tool like Burp.  This gives you RCE capabilities!  Scary, right?

If the server runs on Windows, we can make the server download something like NiShang's reverse shell or netcat for Windows and save it to a location writeable by all users such as C:\windows\system32\spool\drivers\color\.  Then, another payload to execute the code will give you a reverse shell.  On Linux, we might even be able to execute netcat directly (or upload a reverse shell and do it in a similar fashion).  Once you get the shell, you can basically pwn the rest of the server now.