(tldr: scroll to the end of the article to see how to create an XML file that will trigger an reverse-shell from an REST server into an attacker's box)
I have to say that I was quite surprised that it was possible to execute Java code (and start processes) from XML files!
Abraham and Alvaro deserve all the credit for connecting the dots between XMLDecoder and REST.
Basically what happens is that the Java’s JDK has a feature called Long Term Persistence which can be used like this:
As you can see by the example shown above, the Xml provided to XMLDecoder API is able to create an instance of javax.swing.JButton and invoke its methods.
I can see why this is useful and why it was added to the JDK (since it allows for much better ‘Long Term Object Persistence’), BUT, in practice, what this means is that java payloads can be inserted in XML files/messages.
This is already dangerous in most situations (i.e. when was the last time that you actually thought that an XML file was able to trigger code execution on a server), BUT when you add REST to the mix, we basically have a ‘Remote Code/Command Execution’ vulnerability.
Awareness for this issue
Although there is some awareness out there of the dangers of XMLDecode, I don’t think there is enough understanding of what is possible to do with the XML provided to the XMLDecoder .
For example Is it safe to use XMLDecoder to read document files? asks:
... with the answer being spot on:
Unfortunately, one really has to look for those ‘alerts’, since the main XMLDecoder info/documentation doesn’t mention them.
For example the main links you get by searching for XMLDecoder:
... encourage its use:
...and provide no info on the ‘remote code execution’ feature of XMLDecoder.
Connecting the Dots: Using XmlDecoder on an REST API
There are two key scenarios where this ‘feature’ becomes a spectacular vulnerability:
- Server-side backend system that process attacker-controlled XML files using XMLDecoder
- REST APIs that uses XMLDecoder to create strongly type objects from the HTTP Request data
Note how the documentation page:
... makes no reference to the dangerous use of XMLDecoder (ironically, it doesn’t even mention XMLDecoder, just that it can parse data created by XMLEncoder)
How XMLDecoder is used in Restlet
In Restlet the ObjectRepresentation<T> class can be used on REST methods to create objects from the HTTP request body (which is an XML string) .
For example, on the PoC that we created for the DefCon presentation (based on one of RestLet source code example apps)
... I changed the code at Line 68 (which manually retrieved data from the HTTP Request data)
... into the code you can see below at line 72
... which uses ObjectRepresentation<T> to map the HTTP Request data into an object of type Item:
Note that this is exactly the capability that are provided by MVC Frameworks that automagically bind HTTP post data into Model objects. This 'feature' is the one that creates the the Model Binding Vulnerabilities which I have been talking about here, here, here, here, here, here, here and here. In fact, the XMLDecoder is is a ModelBinding Vulnerability (also called Over Posting, Mass Assignment or Auto Binding vulns) on steroids, since not only we can put data on that object, we can create completely new ones and invoke methods in them.
Before you read the exploits, remember that the change I made to the code (see below)
… is one that any developer could do if tasked with automatically casting the received REST XML data into Objects.
In order to develop the exploits and create PoCs, I quickly wrote an O2 Platform based tool, which you can get from here:
This tool:
… provided a gui where these XML exploits:
…could be easy sent to a running instance of the test RestLet app.
Multiple examples of what can be done using the XMLDecode meta-language
1 - create item (Simple).xml - normal object creation
2 - create item (using properties).xml - object creation and calling setters
3 - create item (from var).xml - creating and using an variable
4 - create item (and more).xml - creating/invoking a complete different class
5 - create item (and calc).xml - starting cacl.exe using Java's Runtime.getRuntime() . Note that this example is VERY STEALTH since there will be no casting error thrown by the XMLDecoder conversion (the first object created in the XML execution is the one returned, which in this case is the expected one (firstResource.Item))
6 - Process Builder - Start a Calc.xml - Create a complete different object (ProcessBuilder) which will throw an casting error ... after the process execution starts :)
7a - Creating a File.xml - in the target app we were using there was no webroot available with ability to render JSPs (it was a pure REST server with only REST routes). But if it there was one, and we could write to it, we could use the technique shown below to upload an JSPShell (like this one), and exploit the server from there.
7b - Creating a Class File.xml - since we can upload files, we can compile a class file locally and 'upload' it to the server
7d - execution class file - anotherExecute- calcl.xml - in this case the class file we uploaded had a method that could be used to start processes
8a - HttpResponse - return variable.xml - this is a cool technique where I found the Restlet equivalent of HttpServletresponse, so I was able to write content directly to the current browser
8b - HttpResponse - return variables.xml - which can be used to return data assigned to XMLDecoder created variables
8c - HttpResponse - return JavaProperties.xml - In this case the java.lang.getProperties values (but if this was a real app, we could use this to extract data from the database or in memory objects)
8d - Exploit - Create XSS.xml - another option is to trigger XSS on the current user (usefully if the first payload was delivered over CSRF to the victim)
8e - HttpResponse - execute process - read two lines.xml - here is a way to execute a process and get its output shown in the browser
9a - download NetCat.xml - here is how to trigger a http connection from the server into the attacker's box and download the NetCat tool
9b - Start NetCat reverse shell.xml - once NetCat is available on the server, we can use it to send a reverse-shell an external IP:Port
This is when I run out of time for writing more PoCs....
... but as you can see by the end, I was just about writing Java code, only thing I didn’t figure out how to do create loops and anonymous methods/classes (need to look at the Command Pattern).
I also hope that by now you see how dangerous the XMLDecoder capabilities are, and how its use must be VERY VERY carefully analysed and protected.
How to use XMLDecoder be safely?
I’m not entirely sure at the moment.
The Secure Coding Guidelines for the Java Programming Language, Version 4.0 have a note on 'Long Term Persistence of JavaBeans':
But the Long Term Persistence of JavaBeans Components: XML Schema article (which btw is the best resource out there on how to use the XmlDecoder), has no mention of Security.
Hopefully the presentation that we did at DefCon and blog posts like this, will raise the awareness of this issue and good solutions will emerge
Note that I’m not as good in Java as I am in .NET, so I’m sure there is something in Java or JDK that I’m missing.
Let me know what you think of this issue, if there are safe ways to use XmlDecoder and if you spot other dangerous uses of XmlDecoder.
UPDATE: Presentation slides
See this page for the presentation slides (hosted by SlideShare)