Skip to main content

HTB - Seal

alt

Basic Nmap scan

Nmap Command: nmap -Pn -n -sC -sV -oN 10.10.10.250-d-scan 10.10.10.250
Nmap scan report for 10.10.10.250
Host is up (0.15s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 4b894739673d07315e3f4c27411ff967 (RSA)
| 256 04a74f399565c5b08dd5492ed8440036 (ECDSA)
|_ 256 b45e8393c54249de7125927123b18554 (ED25519)
443/tcp open ssl/http nginx 1.18.0 (Ubuntu)
| tls-alpn:
|_ http/1.1
|_http-server-header: nginx/1.18.0 (Ubuntu)
| tls-nextprotoneg:
|_ http/1.1
|_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
|_ssl-date: TLS randomness does not represent time
8080/tcp open http-proxy
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Server returned status 401 but no WWW-Authenticate header.
|_http-title: Site doesn't have a title (text/html;charset=utf-8).
| fingerprint-strings:
| FourOhFourRequest:
| HTTP/1.1 401 Unauthorized
| Date: Thu, 20 Oct 2022 04:12:15 GMT
| Set-Cookie: JSESSIONID=node01sqwxjtfptte1ar3carw6raxd2.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Content-Length: 0
| GetRequest:
| HTTP/1.1 401 Unauthorized
| Date: Thu, 20 Oct 2022 04:12:13 GMT
| Set-Cookie: JSESSIONID=node0137rclvnco4znpxjpee5lk4e60.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Content-Length: 0
| HTTPOptions:
| HTTP/1.1 200 OK
| Date: Thu, 20 Oct 2022 04:12:14 GMT
| Set-Cookie: JSESSIONID=node03dc6v9slx69a1dlrz9m5pweia1.node0; Path=/; HttpOnly
| Expires: Thu, 01 Jan 1970 00:00:00 GMT
| Content-Type: text/html;charset=utf-8
| Allow: GET,HEAD,POST,OPTIONS
| Content-Length: 0
| RPCCheck:
| HTTP/1.1 400 Illegal character OTEXT=0x80
| Content-Type: text/html;charset=iso-8859-1
| Content-Length: 71
| Connection: close
| <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
| RTSPRequest:
| HTTP/1.1 505 Unknown Version
| Content-Type: text/html;charset=iso-8859-1
| Content-Length: 58
| Connection: close
| <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
| Socks4:
| HTTP/1.1 400 Illegal character CNTL=0x4
| Content-Type: text/html;charset=iso-8859-1
| Content-Length: 69
| Connection: close
| <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x4</pre>
| Socks5:
| HTTP/1.1 400 Illegal character CNTL=0x5
| Content-Type: text/html;charset=iso-8859-1
| Content-Length: 69
| Connection: close
|_ <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x5</pre>
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 :
SF-Port8080-TCP:V=7.93%I=7%D=10/20%Time=6350CA9E%P=x86_64-unknown-linux-gn
SF:u%r(GetRequest,F4,"HTTP/1\.1\x20401\x20Unauthorized\r\nDate:\x20Thu,\x2
SF:020\x20Oct\x202022\x2004:12:13\x20GMT\r\nSet-Cookie:\x20JSESSIONID=node
SF:0137rclvnco4znpxjpee5lk4e60\.node0;\x20Path=/;\x20HttpOnly\r\nExpires:\
SF:x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\nContent-Type:\x20tex
SF:t/html;charset=utf-8\r\nContent-Length:\x200\r\n\r\n")%r(HTTPOptions,10
SF:8,"HTTP/1\.1\x20200\x20OK\r\nDate:\x20Thu,\x2020\x20Oct\x202022\x2004:1
SF:2:14\x20GMT\r\nSet-Cookie:\x20JSESSIONID=node03dc6v9slx69a1dlrz9m5pweia
SF:1\.node0;\x20Path=/;\x20HttpOnly\r\nExpires:\x20Thu,\x2001\x20Jan\x2019
SF:70\x2000:00:00\x20GMT\r\nContent-Type:\x20text/html;charset=utf-8\r\nAl
SF:low:\x20GET,HEAD,POST,OPTIONS\r\nContent-Length:\x200\r\n\r\n")%r(RTSPR
SF:equest,AD,"HTTP/1\.1\x20505\x20Unknown\x20Version\r\nContent-Type:\x20t
SF:ext/html;charset=iso-8859-1\r\nContent-Length:\x2058\r\nConnection:\x20
SF:close\r\n\r\n<h1>Bad\x20Message\x20505</h1><pre>reason:\x20Unknown\x20V
SF:ersion</pre>")%r(FourOhFourRequest,F4,"HTTP/1\.1\x20401\x20Unauthorized
SF:\r\nDate:\x20Thu,\x2020\x20Oct\x202022\x2004:12:15\x20GMT\r\nSet-Cookie
SF::\x20JSESSIONID=node01sqwxjtfptte1ar3carw6raxd2\.node0;\x20Path=/;\x20H
SF:ttpOnly\r\nExpires:\x20Thu,\x2001\x20Jan\x201970\x2000:00:00\x20GMT\r\n
SF:Content-Type:\x20text/html;charset=utf-8\r\nContent-Length:\x200\r\n\r\
SF:n")%r(Socks5,C3,"HTTP/1\.1\x20400\x20Illegal\x20character\x20CNTL=0x5\r
SF:\nContent-Type:\x20text/html;charset=iso-8859-1\r\nContent-Length:\x206
SF:9\r\nConnection:\x20close\r\n\r\n<h1>Bad\x20Message\x20400</h1><pre>rea
SF:son:\x20Illegal\x20character\x20CNTL=0x5</pre>")%r(Socks4,C3,"HTTP/1\.1
SF:\x20400\x20Illegal\x20character\x20CNTL=0x4\r\nContent-Type:\x20text/ht
SF:ml;charset=iso-8859-1\r\nContent-Length:\x2069\r\nConnection:\x20close\
SF:r\n\r\n<h1>Bad\x20Message\x20400</h1><pre>reason:\x20Illegal\x20charact
SF:er\x20CNTL=0x4</pre>")%r(RPCCheck,C7,"HTTP/1\.1\x20400\x20Illegal\x20ch
SF:aracter\x20OTEXT=0x80\r\nContent-Type:\x20text/html;charset=iso-8859-1\
SF:r\nContent-Length:\x2071\r\nConnection:\x20close\r\n\r\n<h1>Bad\x20Mess
SF:age\x20400</h1><pre>reason:\x20Illegal\x20character\x20OTEXT=0x80</pre>
SF:");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Open ports : 22,443,8080

PORTSERVICEPRODUCTVERSIONEXTRAINFO
22sshOpenSSH8.2p1 Ubuntu 4ubuntu0.2Ubuntu Linux; protocol 2.0
443httpnginx1.18.0Ubuntu
8080http-proxy

Enum 443

alt

Investigating the certificate we find the hostname info as seal.htb

alt

Enum 8080

alt

There is an option to create an account in Gitbucket.

alt

Created an Gitbucket account sammy/Passw0rd

alt

Discover tomcat creds

Upon exploring the gitbucket repository we found credentials for tomcat user in the tomcat-user.xml file.

alt

gobuster discovery

gobuster has found few folder with a 302 status. It has found admin and server is redirecting to admin/. This redirection is happening either nginx or at tomcat.

alt

nginx enum

The configuration file in nginx sites-enabled/default file points to few more urls /manager/html and /admin/dashboard

alt

Trying to access /admin/dashboard is blocked by nginx

alt

but when trying to access /admin we get an error from tomcat.

alt

Looks like nginx is blocking the url before reaching tomcat. We need break the parser to reach the tomcat.

nginx - breaking parser logic Exploit

reference to Breaking parser logic - pdf

alt

updating /admin/dashboard to /admin;name=orange/dashboard in request and we are able to successfully bypass nginx filter.

alt

Not much information is on this url, lets check /manager/html

alt

using the tomcat credentials found earlier we will attempt to login and we able to successfully login.

alt

Now, we can generate a reverse shell war file and upload it.

Reverse shell

alt

uploading the war file and catch the reverse shell.

alt

got a 403 error. Let investigate with burpsuite. Most likely it could be the url parsing issue.

alt

Inspecting the request in the burpsuite show that when deploy button is clicked. The request is sent to the default upload url as show below

alt

Updating the request with /;name=orange logic, we are able to successfully upload the file and deploy.

alt

Deployed shell

alt

Accessing the reverse shell.

alt

Privilege escalation

Downloading our monitoring script and executing the script for running processes

alt

alt

ansible exploitation

Looks like there a cron job running every minute. It is an ansible playbook executing rum.yml file.

alt

alt

Analyzing run.yml file, we identify that there is back files are created from the source file /var/lib/tomcat9/webapps/ROOT/admin/dashboard to the destination /opt/backups/files and also links in the source folder are copied. But critical loophole is, the symbolic links are copied as items into the archived file. We shell exploit this loophole by creating a symbolic link to ssh file of the luis user in the writable folder of source.

Symbolic file create

creating the symbolic the file to ssh file in the writable folder

alt

the backup file in the archives folder

alt

The cron job should create a backup file

alt

Move the backup file and extract the backup file. This extracted folder should contain the ssh file.

alt

alt

ssh file for luis

alt

Luis ssh

alt

user flag

alt

escalating to root

Exploiting the sudo privileges. luis has sudo privileges to execute ansible playbook.

alt

Create playbook to return a reverse shell.

alt

Execute the playbook

alt

alt

root flag

alt