Dando continuidade à série de postagens sobre desafios realizados, trago a documentação da máquina Amaterasu (nível Fácil/Easy), disponível gratuitamente no Proving Grounds Play.

Para quem não está familiarizado, os desafios do tipo Capture The Flag (CTF) envolvem máquinas vulneráveis que têm como objetivo testar as habilidades dos participantes em identificar e explorar essas falhas. Os competidores devem encontrar flags (bandeiras), que são provas de que conseguiram comprometer com sucesso os alvos designados.

Enumeração Link to heading

Para iniciar o processo de enumeração, realizei uma varredura de portas via nmap junto ao IP disponibilizado.

Resultado da execução do nmap

Comando: nmap -sV -p- --min-rate 10000 192.168.150.249

Parâmetros:

  • -sV permite a identificação dos serviços/versões que estão rodando nas portas que forem identificadas como abertas (open);
  • -p- permite o scan de todas as 65.535 portas TCP;
  • --min-rate 10000 informa ao nmap para tentar enviar no mínimo 10000 pacotes por segundo, como uma tentativa de acelerar a análise (pode impactar a precisão dos resultados).

A varredura com nmap retornou diversas portas abertas, destacando-se as portas 21, 33414 e 40080. Visando facilitar o processo de análise e exploração, adicionei o IP 192.168.150.249 no arquivo /etc/hosts da máquina do atacante, atribuindo o nome amaterasu.pg ao IP.

O serviço FTP (21) aceitou conexão como anonymous:anonymous, porém não foi possível listar os arquivos:

Acesso anônimo ao FTP

Ao acessar o servidor web rodando na porta 40080, é possível visualizar a seguinte imagem:

Acesso a 40080 via navegador

Na sequência, enumerei o servidor web através da ferramenta dirsearch, utilizando a wordlist padrão da ferramenta dirb big.txt.

Comando: dirsearch -w /usr/share/wordlists/dirb/big.txt -x 404 -u http://amaterasu.pg:40080

Parâmetros:

  • -w permite informar uma wordlist a ser utilizada para o processo de ataque de dicionário;
  • -x 404 exclui o status code 404, o que facilita a análise do output do comando;
  • -u permite a informação da URL a ser analisada.
Execução do dirsearch na 40080

A análise manual das pastas e do arquivo LICENSE identificados não retornou dados de interesse.

Em seguida, realizei uma comunicação com a porta 33414 através do telnet, onde foi possível confirmar que se trata de um servidor web:

Telnet na porta 33414

Na sequência rodei a ferramenta dirsearch no alvo.

Comando: dirsearch -w /usr/share/wordlists/dirb/big.txt -x 404 -u http://amaterasu.pg:33414

Parâmetros:

  • -w permite a informação de uma wordlist a ser utilizada para o processo de ataque de dicionário;
  • -x 404 exclui o status code 404, o que facilita a análise do output do comando;
  • -u permite a informação da URL a ser analisada.
Execução do dirsearch na 33414

Como resultado, foi possível identificar dois endpoints. Ao acessar o endpoint /info via navegador foi possível identificar que na porta 33414 roda um serviço chamado Python File Server REST API v2.5:

Acesso ao endpoint /info

Ao acessar o endpoint /help via navegador foi possível identificar os endpoints existentes no servidor e por quais métodos é possível fazer requisições:

Acesso ao endpoint /help

Exploração e acesso inicial Link to heading

Ao realizar uma requisição para o endpoint /file-upload utilizando o método POST, complementando com o parâmetro -i para visualizar o cabeçalho de resposta, foi possível perceber a falta do parâmetro file, indicado pela mensagem de erro exibida:

Curl ao endpoint /file-upload

Ao efetuar uma nova requisição, dessa vez efetuando o upload de um arquivo de testes através do parâmetro -F, que permite o envio de dados de formulário (adicionando o formato multipart/form-data ao request), foi possível identificar a falta do parâmetro filename:

Curl de tentativa de upload

Na sequência, presumindo que o parâmetro filename diz respeito ao destino do upload, informei o diretório /var/www/html/, onde obtive um erro de código 500. Entretanto, ao informar o diretório /tmp/, a requisição retornou no parâmetro message que o upload teve sucesso:

Curl de upload com sucesso

Ao acessar o endereço http://amaterasu.pg:33414/file-list?dir=/tmp, para visualizar os arquivos do diretório /tmp/, foi possível identificar que o arquivo teste.txt realmente sofreu upload:

Visualização dos arquivos em /tmp

Como tenho capacidade de visualizar diretórios, efetuei a visualização do diretório /home o que me possibilitou enumerar o usuário alfredo:

Enumeração do usuário alfredo

Também efetuei a enumeração dos diretórios e arquivos do usuário alfredo, onde pude visualizar o diretório /home/alfredo/.ssh, indicando que o usuário pode autenticar via ssh:

Enumeração dos diretórios do user alfredo

Ao tentar realizar o upload da minha chave pública de SSH para o diretório /home/alfredo/.ssh, pude notar que o servidor só aceita arquivos com extensão txt, pdf, png, jpg, jpeg ou gif:

Tentativa de upload da id_rsa.pub

Para contornar essa limitação, efetuei uma cópia do id_rsa.pub, dando a nomenclatura id_rsa.txt, onde por fim consegui efetuar o upload do arquivo em um arquivo denominado authorized_keys. Esse arquivo permite o armazenamento das chaves públicas autorizadas a se conectar via SSH.

Tentativa de upload da id_rsa.pub

Por fim, efetuei o acesso via SSH como alfredo:

Acesso via SSH

Uma vez com acesso à máquina, iniciei o processo de análise manual do sistema de arquivos em busca de artefatos que possam contribuir com a minha exploração.

Dentro do diretório /home/alfredo foi possível localizar o arquivo local.txt, contendo a flag de usuário:

Leitura da flag de usuário

Escalonamento de Privilégios Link to heading

Iniciando a análise de vetores de escalonamento de privilégios, analisei o arquivo /etc/crontab, responsável pela configuração do agendador de tarefas cron, onde foi possível identificar uma entrada onde o arquivo /usr/local/bin/backup-flask.sh roda a cada minuto com privilégios de root:

Leitura da flag de usuário

Ao analisar as permissões que o usuário alfredo tem sobre o arquivo, bem como seu conteúdo, foi possível identificar que o script executa algumas ações:

Permissões e conteúdo do arquivo backup-flask.sh

A última linha do arquivo chama atenção por realizar a compactação de todos os arquivos no diretório /home/alfredo/restapi, criando o arquivo /tmp/flask.tar.gz. Como o asterisco representa um wildcard, podemos utilizar essa falta de especificação de destino/arquivos a serem compactados para escalonar privilégios.

Para tal, inicialmente criei um arquivo chamado privesc.sh dentro do caminho (PATH) /home/alfredo/restapi, contendo um comando para escrever no arquivo /etc/sudoers uma regra que dá permissão ao usuário alfredo em todo ambiente (ALL), possibilitando que ele execute comandos como root, sem fornecer senha (NOPASSWD), sem qualquer tipo de restrição (ALL).

Comando: echo 'alfredo ALL=(root) NOPASSWD: ALL' > /etc/sudoers

Criação do arquivo a ser executado

Na sequência, escrevi uma string vazia em dois arquivos, --checkpoint=1 e --checkpoint-action=sh privesc.sh, fazendo com que a ferramenta tar execute-os como parâmetro:

Criação dos arquivos para a manipulação do comportamento do tar

Como resultado, foi possível escalar privilégios para o usuário root:

Criação do arquivo a ser executado

Ao acessar o diretório /root foi possível localizar o arquivo proof.txt, contendo a flag de root:

Leitura da flag de root

Conclusão Link to heading

No desafio amaterasu pude aprender como realizar o escalonamento de privilégios através da manipulação de wildcard junto à ferramenta tar, onde destaco mais uma vez a importância de atenção aos detalhes, pois apenas uma análise correta do arquivo backup-flask.sh permite o escalonamento com sucesso.