In what situation is a Java reverse shell useful?
Reverse shells can be written in a lot of different programming and scripting languages. Being able to use reverse shells written in different languages can enable you to adjust to different situations.
To execute a reverse shell you need to find a way to do remote code execution. For web servers that use PHP, a PHP reverse shell could work. But it’s always useful to know how to use reverse shells written in different programming languages because sometimes web applications use Java or Ruby for example.
Reverse shell in Java
The code for the reverse shell is from Github but it doesn’t work when you just copy and paste it.
Here it gets obvious that I’m a real Java newbie because I needed quite some time to figure out how to set up the reverse shell. There were a lot of errors because I didn’t know how to structure the code and which part to put in the main method. For example I put the main method before the reverse shell method instead of after, which didn’t work. But then I put it after and I got new errors.
In the end I removed the method and put the code inside the main method and added the Exception and it worked. Then the public class needed to have the same name as the file, and finally “/bin/sh” needed to be changed to cmd.exe to make it a Windows reverse shell instead of Linux reverse shell.
This reverse shell in Java has more possibilities than some simple Python reverse shells because it really lets you use cmd.exe on the remote computer.
Explanation of the code
Now I will try to explain what I understand of the code.
Firstly the following Java packages are imported:
- Inputstream: this makes it possible to receive information in a stream of bytes
- Outputstream: to send information in a stream of bytes
- Socket: this is what is needed to create a connection on a specific port
- IOException: an exception that is thrown when there is an error that has to do with input or output.
After this, the variables for the ip address, the port and cmd.exe are created. On line 12 the Process builder prepares the cmd and on line 13 the socket is created. Then the input stream and the output stream are set up, but there isn’t a connection yet.
The connection starts from line 16 inside the while loop. While there is a connection, all the information that comes in is read and the response is sent back. The flush method used in line 23 and 24 is used to send the data through the output stream.
The Thread.sleep() method is the same as time.sleep() in Python and it is used to pause execution for 50 seconds.
I think the p.exitValue() is used to stop the process whenever the user types CTRL-C. When this happens the process is stopped with p.destroy() and the socket is closed with s.close().
Demonstration
I will run the compiled Java code on my Windows PC pretending that my Kali VM is the attacker. The Kali VM is listening on port 1234 with netcat.
We have a shell now! The shell is interactive. You can use it to move between directories, create and delete files, and so on.
If you thought this was interesting, you can also check out: Making a Python ping sweep script.
Sources
- https://www.w3schools.com/java/java_try_catch.asp
- https://www.geeksforgeeks.org/ways-to-read-input-from-console-in-java/