- https://ctftime.org/task/6205, source code can be found at the end of post.
- Analyze CVE-2013-2165 to find Java Deserialization entry point
- Make custom gadget chain based on source code to form RCE
- Analyze CVE-2015-0279 for straight-up EL Injection
I made this challenge based on a pentest scenario I encountered recently. Both of the CVEs don’t have a publicly usable PoCs, so you will need some 1-day analyzing skills.
First off I intentionally gave away the environment settings to save you some time fuzzing the webapp. Click “Change Book Again!” until the counter reaches 5, it will gives an url to the .war source code.
Inspect the file, you’ll find that the server is utilizing Richfaces 4.3.2. There are a couple of ways to know this:
- Go through
- Find a leftover pom.xml in META-INF, in this case located at
Richfaces 4.3.2 is vulnerable to both CVE-2013-2165 and CVE-2015-0279. In this writeup, I’m gonna cover the CVE-2013-2165 Java arbitrary deserialization, however the two CVEs are equal in difficulty to analyze and exploit. (IMO CVE-2015-0279 is much more fun and exciting, but it’ll take much more time to understand it thoroughly)
1. Info gathering
Getting some info about the CVE through the Richfaces developer’s blog at http://www.bleathem.ca/blog/richfaces-security-advisory-cve-2013-2165/ and see that the bug is fixed in Richfaces 4.3.3.
Make a diff between the two Richfaces 4.3.3 and 4.3.2 to find the vulnerable code. We could see that the only difference in the diff is a code change fixing deserialization issue, via adding a new
LookAheadObjectInputStream class and using it instead of the usual ObjectInputStream for deserialization’s readObject(). If you have had previous experiences with Java deserialization, you should already know that this is in fact a technique to prevent Java Arbitrary Deserialization, namely Look-ahead Deserialization. So now we’ve found our entry point, which is the line
2. Making a PoC
Build a sample Richfaces webapp, or you can just deploy my source .war on your local environment, download the necessary 3rd-party lib’s source for debugging and we’re ready. Now normally during a 1-day analysis we can just put a breakpoint at the vulnerable code line, and hope for the best waiting until a request reaches that point. That’s boring and not applicable in this case, no normal requests from my .war will hit the vulnerable code. So now to build the request ourselves, trace up the code (e.g. continuously analyze and find method’s usage) until you find
org.richfaces.resource.ResourceHandlerImpl#handleResourceRequest. Put a breakpoint in this method here and notice that all Richfaces resource request will route through that method. Analyze the code from there line by line, fulfill the conditions needed to reach the Deserialization point. After a while you’ll figure out that the conditions are:
- The request must starts with /rfRes
- The URI after /rfRes needs to be a resource existing on the server (You can just use a default Richfaces resource, e.g.
- The request needs a param named ln pointing to an existent resource library (Again, just use the Richfaces default, e.g.
- The request needs a param named do and it needs to be encoded using
The data in param do will eventually be passed to the Deserialization point.
So now we have figured out the “source”. Time to find the “sink”.
Exploiting this vulnerability into RCE is not that straightforward like usual. I intentionally made this so that there are no exploit chains available in the tool Ysoserial that could work. You have to customize your own gadget chain based on the source code I gave.
First to confirm the deserialization exists, you could use the URLDNS gadget chain to make the web server make a DNS resolve request toward your designated server. The tool I would recommend for this is http://requestbin.net/dns (Props to @mxcxvn).
Now onto RCE. Decompile and inspect the .class source code, you’ll find that there is an easily noticable dangerous method that use
If you have understood Java deserialization by now, you should be able to figure out that what we need to do is to make a custom gadget chain that goes from
BookHolder.hashCode(). Skimming through the example exploit chains in Ysoserial, you’ll notice that many of them goes through an object’s hashCode function.
You could make up any gadget as you seem fit. Here’s mine:
Implement a custom class in Ysoserial to make use of the gadget chain. My sample code could be found in the attachments.
And the flag.
Here’s the .war source code, a PoC request to reach the Deserialization entry point and the code for Ysoserial custom gadget chain: ctf_wutfaces_resources.zip
I’ll keep the server at http://wutfaces.ctf.tint0.com/ up for some more time for anyone interested in further testing.
That’s it. Happy hacking.
P/s: There was a bug in my webapp, which is a wrong jsf library dependency making the webapp sometimes return 500 error code. However since it didn’t affect the exploits and I didn’t want to alter the codes during contest, I left it untouched. Sorry for that :)