Começando no Bug Bounty: File Upload – Mais do que Apenas uma Imagem
Um guia completo para iniciantes sobre como encontrar vulnerabilidades de file upload em programas de bug bounty. Explora desde os fundamentos do multipart/form-data até técnicas avançadas como race conditions e zip slip, com exemplos práticos e dicas de ferramentas.
MundiX News·13 de abril de 2026·15 min de leitura·👁 3 views
Começando no Bug Bounty: File Upload – Mais do que Apenas uma Imagem
Olá, Habr! (referência à plataforma onde o artigo foi originalmente publicado)
Este material foi preparado em conjunto com Dmitry Prokhorov, um pentester da PT SWARM (conhecido no mundo do bug bounty como ratel_xx). Vamos falar sobre a busca de vulnerabilidades através do upload de arquivos.
Você aprenderá como funciona o mecanismo multipart/form-data, quais mecanismos de proteção os desenvolvedores implementam e como contorná-los. Mostraremos na prática o que pode ser feito com extensões de arquivos, Content-Type, magic bytes e também abordaremos exploits como race condition, zip-slip e vetores não padronizados, como o upload de .htaccess. Este artigo é adequado para bug hunters iniciantes, então, mesmo que você tenha pouca experiência, continue lendo!
O artigo é exclusivamente informativo e educacional e não é uma instrução ou um apelo para cometer atos ilegais. Os materiais descritos destinam-se a aumentar a conscientização sobre possíveis vulnerabilidades e métodos para preveni-las. Qualquer teste de segurança é permitido apenas com a permissão explícita do detentor dos direitos autorais dos recursos relevantes ou como parte de um programa oficial de bug bounty. Ações não autorizadas podem violar a lei. O autor do artigo não incentiva ou apoia o uso indevido das informações apresentadas e não é responsável por seu uso para fins ilegais. Lembre-se de prestar atenção à proteção de seus dados e usar as informações do artigo exclusivamente para fins legais.
Se você está dando os primeiros passos no bug hunting, recomendamos ver como os membros da comunidade Standoff Bug Bounty começaram.
👾 Para aqueles que já estão se aproximando das recompensas, o artigo sobre como encontrar vulnerabilidades SSRF com muitas links para recursos e ferramentas úteis será útil.
👾 Recomendamos também a leitura sobre Broken Access Control – um dos tipos de vulnerabilidade mais comuns.
👾 E também não perca o top 10 de ferramentas para começar no bug bounty.
Por que File Upload é um Ímã de Bounty
Formulários de upload de arquivos são encontrados em todos os lugares. Feedback, importação de dados, upload de documentos financeiros, avatares de usuários – todos esses são pontos de entrada potenciais. Onde há upload, há oportunidades para um invasor.
E não se trata apenas da prevalência, mas também do potencial – o upload de arquivos geralmente leva a consequências críticas. Execução remota de código (RCE), path traversal para sobrescrever arquivos de configuração, negação de serviço (DoS) – tudo isso torna o upload particularmente atraente para bug hunters.
Aqui está um exemplo de uma vulnerabilidade massiva em um popular plugin do WordPress – um erro colocou milhares de sites em risco.
A história com o Telegram, quando um erro de sintaxe permitia o upload de arquivos que eram executados ao abrir um chat, confirma mais uma vez que mesmo grandes desenvolvedores não estão imunes.
Nos principais relatórios do HackerOne, você pode encontrar exemplos em que os bypasses eram ridiculamente simples. Por exemplo, bastava adicionar um espaço na extensão do arquivo e a proteção caía. Falaremos sobre essas técnicas ao analisar as técnicas básicas, mas por enquanto vamos começar com a teoria.
Como Funciona o Upload de Arquivos
Para entender onde procurar vulnerabilidades, você precisa primeiro entender como o upload de arquivos realmente acontece do ponto de vista do protocolo e dos padrões. Vamos examinar o mecanismo multipart/form-data em que ele é construído, dar uma olhada no RFC 7578 e ver exatamente o que o servidor presta atenção quando recebe um arquivo.
Mecânica Multipart/Form-Data
Quando você carrega um arquivo através de um formulário da web, o navegador envia uma solicitação para o servidor no formato multipart/form-data. Este mecanismo permite transmitir campos de texto e dados binários – os próprios arquivos – em uma única solicitação. A solicitação possui um campo oculto com o nome do formulário e o próprio arquivo. O código do cliente não pode ser confiável, portanto, você precisa verificar a solicitação enviada ao servidor.
No entanto, os desenvolvedores geralmente confiam em bibliotecas padrão e não pensam em como essa solicitação é analisada. E existem divergências com o padrão na implementação dos parsers. São essas divergências, por exemplo, o tratamento incorreto de limites ou a ignorância de caracteres de terminação, que levam a vulnerabilidades. Ao entender a estrutura multipart, você pode encontrar esses erros onde outros veem um formulário de upload comum.
Para ver a solicitação bruta e entender o que exatamente está sendo enviado para o servidor, as ferramentas de proxy são usadas. O mais popular no bug hunting é o Burp Suite. Ele intercepta o tráfego entre o navegador e o servidor, mostra a estrutura da solicitação e permite alterar qualquer uma de suas partes em tempo real.
Padrão RFC 7578
O formato multipart/form-data para upload de arquivos é descrito no padrão RFC 7578. Este documento descreve as regras para formar limites (boundary), cabeçalhos e o corpo da solicitação. Os limites são separadores exclusivos que são gerados no lado do cliente e não devem ser repetidos dentro do conteúdo. O servidor procura esses limites para entender onde cada parte do formulário começa e termina.
Pode parecer um detalhe puramente técnico, mas os desvios do RFC são um terreno fértil para vulnerabilidades. Um desenvolvedor usa uma biblioteca que segue estritamente o padrão. Outro escreve seu próprio parser e corta cantos. Um terceiro nem suspeita que seu colega inventou a roda. Como resultado, diferentes componentes do sistema interpretam a mesma solicitação de forma diferente.
Um exemplo clássico é uma vulnerabilidade na popular biblioteca Node.js Multer. O parser esperava que o último limite na solicitação terminasse com dois hífens, conforme exigido pelo RFC. Se não houvesse hífens, o servidor entrava em uma espera infinita pela próxima parte. Um par extra ou ausente de caracteres – e o DoS está pronto.
Em 2025, foi publicado um grande estudo onde os autores mutaram os limites, cabeçalhos e a estrutura das solicitações multipart, sem tocar no próprio payload. Como resultado, eles encontraram mais de mil maneiras de contornar AWS, Cloudflare, Google Cloud Armor, Azure e ModSecurity. O problema é mais profundo do que parece: os parsers WAF e de aplicativos web divergem em detalhes e quase sempre é possível transformar isso em um ataque.
Para Onde o Servidor Olha
Portanto, descobrimos como uma solicitação multipart é estruturada e por que o padrão é importante. Agora vamos ver exatamente o que o servidor presta atenção quando recebe um arquivo.
O servidor presta atenção em três coisas.
Nome do arquivo (filename) – o servidor usa a extensão dele para entender com que tipo de arquivo está lidando. Se o desenvolvedor verificar apenas a extensão, esse já é um motivo para dar uma olhada mais de perto.
Content-Type – o tipo MIME que veio do cliente. O problema é que ele é gerado no lado do navegador e pode ser facilmente substituído através de um proxy.
Corpo do arquivo, ou melhor, seu início – aqui estão os chamados magic bytes – assinaturas de bytes exclusivas que determinam o tipo real de conteúdo, independentemente da extensão. Por exemplo, um arquivo PNG sempre tem os primeiros bytes 89 50 4E 47 0D 0A 1A 0A. Se o desenvolvedor confiar apenas nos cabeçalhos e extensões, mas não verificar as assinaturas, esse é um caminho direto para o bypass.
Ataques Básicos: Como Contornar a Proteção Simples
Quando chegamos a um formulário de upload de arquivos, a primeira coisa que fazemos é tentar carregar algo malicioso: um shell PHP, JavaScript para XSS, SVG com código injetado. Em resposta, os desenvolvedores implementam mecanismos de proteção. As principais técnicas que ajudam a contorná-los: enumeração de extensões (.php5, .phtml, .phps), caracteres especiais (espaços, pontos, null-byte), substituição de maiúsculas e minúsculas (no Linux), recursos de normalização de nomes (no Windows), substituição de Content-Type, injeção de magic bytes, concatenação de arquivos e uso de extensões duplas.
Vamos começar com o cenário mais simples, quando não há proteção no servidor – todos os arquivos são aceitos e salvos em um diretório acessível pela web. Preparamos um shell simples com uma chamada para o comando id, carregamos uma imagem normal, interceptamos a solicitação no Burp e observamos sua estrutura. No corpo do arquivo, em vez da imagem, inserimos nosso código PHP, alteramos a extensão para .php. O servidor responde que o arquivo foi salvo. Seguimos o link – em vez da imagem, vemos o resultado da execução do comando.
Claro, em programas reais, esse cenário simples é raro. Na maioria das vezes, os desenvolvedores verificam algo: proíbem certas extensões, olham para o Content-Type ou até mesmo para o conteúdo do arquivo. E aqui técnicas um pouco mais complexas entram em jogo.
Uma das mais interessantes é o bypass através de magic bytes. O servidor aceita apenas imagens e olha para os primeiros bytes do arquivo. Substituir o Content-Type não ajuda – é necessário que o arquivo comece com a assinatura correta. Para esses casos, o Burp Suite tem a extensão Magic Bytes Selector. Ele permite que você substitua a assinatura do formato desejado no início do arquivo com um clique – GIF, PNG, JPEG e outros.
Se você quiser ver mais exemplos reais de bypass – do simples ao não óbvio – confira uma seleção de técnicas com exemplos de bug bounty no Briskinfosec.
Você Não Passará – Prática Avançada
Analisamos as técnicas básicas, mas os bugs reais geralmente se escondem mais profundamente. Para encontrá-los, você precisa entender como o arquivo carregado é processado após ser salvo – e é aqui que entram as características dos servidores, linguagens de programação e bibliotecas de terceiros. Antes de passar para técnicas específicas, vamos adicionar um pouco de teoria.
Características do Processamento de Arquivos – Linguagens de Programação, Servidores e Buracos nas Configurações
Quando falamos sobre upload de arquivos, não basta pensar apenas em extensões e magic bytes. O arquivo carregado entra em um ecossistema – servidor web, linguagem de programação, framework, bibliotecas de terceiros. Cada um desses componentes adiciona suas próprias nuances e, às vezes, vetores prontos para um ataque.
Servidores Web: Apache
O principal risco no Apache está associado ao arquivo .htaccess. Se o servidor permitir que ele seja carregado em uma pasta com arquivos de usuário, um invasor pode carregar seu próprio .htaccess com a diretiva AddHandler, que fará com que o Apache execute qualquer arquivo (por exemplo, com a extensão .evil) como PHP.
Além disso, o Apache às vezes é configurado para processar arquivos que contêm a substring .php no nome – então shell.php.jpg se tornará executável, mesmo que a extensão seja formalmente .jpg.
Servidores Web: Nginx + PHP-FPM
Em conjunto com o nginx e o PHP-FPM, um erro clássico é a diretiva cgi.fix_pathinfo=1. Com essa configuração, uma solicitação para /uploads/shell.png/shell.php fará com que o PHP-FPM abra o arquivo shell.png e execute o código PHP dentro dele, porque o nginx descarta parte do caminho após a barra. Este não é um bug do próprio PHP, mas uma característica do processamento de caminho que muitas vezes é esquecida. Sobre o quão longe você pode ir com essa característica e transformar LFI em RCE através de arquivos temporários do Nginx, está bem escrito no artigo PHP LFI with Nginx Assistance.
PHP
O vetor mais óbvio é simplesmente colocar um arquivo .php em um diretório web acessível. Mas existem técnicas mais complexas. Wrappers como php://filter e phar:// permitem executar código dentro de arquivos ou até mesmo imagens carregadas, se houver um include vulnerável no código. E se o desenvolvedor usar include para carregar arquivos, uma imagem legal com código PHP injetado pode se transformar em um shell completo – o suficiente para que o include processe o arquivo carregado.
Python e Node.js
A execução direta de arquivos carregados aqui é menos comum, mas isso não significa que eles sejam seguros. Muitas vezes, eles procuram path traversal para sobrescrever arquivos de configuração ou arquivos de script do próprio aplicativo. E se o aplicativo usar engines de template (Jinja para Python, Handlebars para Node.js), carregar um arquivo de template pode levar a SSTI – injeção de template do lado do servidor, que muitas vezes dá RCE.
Java
Os principais vetores são o upload de arquivos WAR ou arquivos JSP em diretórios que são processados pelo servlet container. Se você conseguir carregar malicious.war em uma pasta de implantação ou sobrescrever a configuração através de path traversal, você pode obter controle total sobre o aplicativo. Esses ataques são mais difíceis de executar, mas as consequências são mais graves.
Técnicas Avançadas
Analisamos os principais stacks e suas características, agora vamos passar para ataques específicos que usam esse conhecimento na prática. Alguns deles exigem uma confluência de circunstâncias, outros – uma abordagem não padronizada, mas cada um é capaz de levar à completa comprometimento do servidor.
.htaccess – Pequeno Arquivo com Grandes Consequências
Se o servidor permitir o upload de .htaccess, você pode sobrescrever as regras de processamento. Carregamos um arquivo com a diretiva AddHandler application/x-httpd-php .evil. Agora qualquer arquivo com a extensão .evil será executado como PHP. Carregamos shell.evil – obtemos RCE.
Race Condition: Roubar em ~0 Segundos
Às vezes, o desenvolvedor primeiro salva o arquivo e depois verifica – se é malicioso ou não. Se a verificação falhar, o arquivo é excluído. Entre o salvamento e a exclusão, há um microssegundo em que o arquivo está disponível via HTTP. Se você conseguir acessá-lo nesta janela, o código será executado. Na prática, isso é difícil: você precisa adivinhar o nome do arquivo, contornar as restrições de taxa de solicitação e, às vezes, alugar um VPS mais perto do servidor. A técnica em si merece um artigo separado.
Se você quiser tentar sozinho, recomendo o laboratório Web Security Academy sobre o tema de carregar um shell através de race condition.
Zip Slip – Path Traversal Através de Arquivos
O servidor aceita arquivos ZIP, descompacta-os e salva o conteúdo. Se o desenvolvedor não verificar os nomes dos arquivos dentro do arquivo, podemos especificar um caminho com bypass de diretórios. Criamos um ZIP onde o arquivo shell.php está localizado no caminho ../../../../var/www/html/uploads/shell.php. Ao descompactar, o sistema passa por todos os ../ e coloca o arquivo no diretório de destino. A vulnerabilidade se aplica não apenas ao ZIP, mas também a qualquer formato de arquivo: DOCX, XLSX, JAR, APK – em todos os lugares onde o servidor descompacta o conteúdo.
Se você quiser entender mais profundamente a mecânica do Zip Slip e ver exemplos de código, comece com um artigo detalhado no Snyk. Ele explica exatamente como um arquivo malicioso é formado e por que essa vulnerabilidade ainda é encontrada em projetos reais.
Processamento de Metadados: CVE-2016-3714 (ImageTragick)
Uma vulnerabilidade antiga, mas reveladora no ImageMagick. A biblioteca tentou executar o comando curl para carregar um arquivo por URL, e o comando foi montado através de uma chamada shell. A injeção de aspas duplas e ponto e vírgula permitiu executar um comando arbitrário.
Criamos um arquivo que começa com uma assinatura PNG e, em seguida, contém uma string com uma chamada para o comando id e grava o resultado em um arquivo no diretório web. Carregamos – o ImageMagick tenta executar curl, quebra, mas o comando id funciona e o resultado fica disponível via HTTP.
O Que Vem a Seguir
Analisamos as principais técnicas, mas o upload de arquivos não termina aí. Cada linguagem e framework adiciona suas próprias nuances. Java, Python, Node.js – em todos os lugares existem vetores específicos relacionados à configuração, processamento de arquivos e engines de template. O princípio geral permanece o mesmo: a validação deve ser abrangente. Extensão, Content-Type, magic bytes, estrutura do arquivo, local de salvamento – todos esses são elos de uma corrente. Se pelo menos um enfraquecer, isso pode levar a uma vulnerabilidade.
Conclusões
Pode parecer que as vulnerabilidades de upload de arquivos são algo simples e estudado há muito tempo. Mas, na prática, elas são encontradas em todos os lugares, desde pequenos serviços até grandes corporações, e levam às consequências mais graves: RCE, vazamento de dados, comprometimento total do servidor.
Também é importante que seja lucrativo procurá-los – você pode obter uma recompensa decente por um bug crítico e vulnerabilidades massivas em plugins populares trazem bounties mesmo após a divulgação pública.
Finalmente, compartilho links úteis sobre o tema:
Laboratórios Web Security Academy da PortSwigger – a melhor maneira de praticar. Na seção sobre upload de arquivos, existem várias tarefas práticas de diferentes níveis de dificuldade.
Burp Suite com extensões (Autorize, Turbo Intruder, Magic Bytes Selector).
Listas de extensões para enumeração – estão no SecLists.
Pesquisas sobre vulnerabilidades de arquivos – os links para elas estavam ao longo do artigo.
A todos, boas descobertas. E lembre-se: mesmo que o formulário pareça simples, um vetor inesperado pode estar escondido nele.
🛡️⚡
Pare de pesquisar. Comece a hackear.
O MundiX é seu copiloto de pentest com IA: comandos exatos, análise de outputs e próximo passo na kill chain — em segundos.
Sem cartão para começar · Planos a partir de R$49/mês
Começando no Bug Bounty: File Upload – Mais do que Apenas uma Imagem
Olá, Habr! (referência à plataforma onde o artigo foi originalmente publicado)
Este material foi preparado em conjunto com Dmitry Prokhorov, um pentester da PT SWARM (conhecido no mundo do bug bounty como ratel_xx). Vamos falar sobre a busca de vulnerabilidades através do upload de arquivos.
Você aprenderá como funciona o mecanismo multipart/form-data, quais mecanismos de proteção os desenvolvedores implementam e como contorná-los. Mostraremos na prática o que pode ser feito com extensões de arquivos, Content-Type, magic bytes e também abordaremos exploits como race condition, zip-slip e vetores não padronizados, como o upload de .htaccess. Este artigo é adequado para bug hunters iniciantes, então, mesmo que você tenha pouca experiência, continue lendo!
O artigo é exclusivamente informativo e educacional e não é uma instrução ou um apelo para cometer atos ilegais. Os materiais descritos destinam-se a aumentar a conscientização sobre possíveis vulnerabilidades e métodos para preveni-las. Qualquer teste de segurança é permitido apenas com a permissão explícita do detentor dos direitos autorais dos recursos relevantes ou como parte de um programa oficial de bug bounty. Ações não autorizadas podem violar a lei. O autor do artigo não incentiva ou apoia o uso indevido das informações apresentadas e não é responsável por seu uso para fins ilegais. Lembre-se de prestar atenção à proteção de seus dados e usar as informações do artigo exclusivamente para fins legais.
Se você está dando os primeiros passos no bug hunting, recomendamos ver como os membros da comunidade Standoff Bug Bounty começaram.
👾 Para aqueles que já estão se aproximando das recompensas, o artigo sobre como encontrar vulnerabilidades SSRF com muitas links para recursos e ferramentas úteis será útil.
👾 Recomendamos também a leitura sobre Broken Access Control – um dos tipos de vulnerabilidade mais comuns.
👾 E também não perca o top 10 de ferramentas para começar no bug bounty.
Por que File Upload é um Ímã de Bounty
Formulários de upload de arquivos são encontrados em todos os lugares. Feedback, importação de dados, upload de documentos financeiros, avatares de usuários – todos esses são pontos de entrada potenciais. Onde há upload, há oportunidades para um invasor.
E não se trata apenas da prevalência, mas também do potencial – o upload de arquivos geralmente leva a consequências críticas. Execução remota de código (RCE), path traversal para sobrescrever arquivos de configuração, negação de serviço (DoS) – tudo isso torna o upload particularmente atraente para bug hunters.
Aqui está um exemplo de uma vulnerabilidade massiva em um popular plugin do WordPress – um erro colocou milhares de sites em risco.
A história com o Telegram, quando um erro de sintaxe permitia o upload de arquivos que eram executados ao abrir um chat, confirma mais uma vez que mesmo grandes desenvolvedores não estão imunes.
Nos principais relatórios do HackerOne, você pode encontrar exemplos em que os bypasses eram ridiculamente simples. Por exemplo, bastava adicionar um espaço na extensão do arquivo e a proteção caía. Falaremos sobre essas técnicas ao analisar as técnicas básicas, mas por enquanto vamos começar com a teoria.
Como Funciona o Upload de Arquivos
Para entender onde procurar vulnerabilidades, você precisa primeiro entender como o upload de arquivos realmente acontece do ponto de vista do protocolo e dos padrões. Vamos examinar o mecanismo multipart/form-data em que ele é construído, dar uma olhada no RFC 7578 e ver exatamente o que o servidor presta atenção quando recebe um arquivo.
Mecânica Multipart/Form-Data
Quando você carrega um arquivo através de um formulário da web, o navegador envia uma solicitação para o servidor no formato multipart/form-data. Este mecanismo permite transmitir campos de texto e dados binários – os próprios arquivos – em uma única solicitação. A solicitação possui um campo oculto com o nome do formulário e o próprio arquivo. O código do cliente não pode ser confiável, portanto, você precisa verificar a solicitação enviada ao servidor.
No entanto, os desenvolvedores geralmente confiam em bibliotecas padrão e não pensam em como essa solicitação é analisada. E existem divergências com o padrão na implementação dos parsers. São essas divergências, por exemplo, o tratamento incorreto de limites ou a ignorância de caracteres de terminação, que levam a vulnerabilidades. Ao entender a estrutura multipart, você pode encontrar esses erros onde outros veem um formulário de upload comum.
Para ver a solicitação bruta e entender o que exatamente está sendo enviado para o servidor, as ferramentas de proxy são usadas. O mais popular no bug hunting é o Burp Suite. Ele intercepta o tráfego entre o navegador e o servidor, mostra a estrutura da solicitação e permite alterar qualquer uma de suas partes em tempo real.
Padrão RFC 7578
O formato multipart/form-data para upload de arquivos é descrito no padrão RFC 7578. Este documento descreve as regras para formar limites (boundary), cabeçalhos e o corpo da solicitação. Os limites são separadores exclusivos que são gerados no lado do cliente e não devem ser repetidos dentro do conteúdo. O servidor procura esses limites para entender onde cada parte do formulário começa e termina.
Pode parecer um detalhe puramente técnico, mas os desvios do RFC são um terreno fértil para vulnerabilidades. Um desenvolvedor usa uma biblioteca que segue estritamente o padrão. Outro escreve seu próprio parser e corta cantos. Um terceiro nem suspeita que seu colega inventou a roda. Como resultado, diferentes componentes do sistema interpretam a mesma solicitação de forma diferente.
Um exemplo clássico é uma vulnerabilidade na popular biblioteca Node.js Multer. O parser esperava que o último limite na solicitação terminasse com dois hífens, conforme exigido pelo RFC. Se não houvesse hífens, o servidor entrava em uma espera infinita pela próxima parte. Um par extra ou ausente de caracteres – e o DoS está pronto.
Em 2025, foi publicado um grande estudo onde os autores mutaram os limites, cabeçalhos e a estrutura das solicitações multipart, sem tocar no próprio payload. Como resultado, eles encontraram mais de mil maneiras de contornar AWS, Cloudflare, Google Cloud Armor, Azure e ModSecurity. O problema é mais profundo do que parece: os parsers WAF e de aplicativos web divergem em detalhes e quase sempre é possível transformar isso em um ataque.
Para Onde o Servidor Olha
Portanto, descobrimos como uma solicitação multipart é estruturada e por que o padrão é importante. Agora vamos ver exatamente o que o servidor presta atenção quando recebe um arquivo.
O servidor presta atenção em três coisas.
Nome do arquivo (filename) – o servidor usa a extensão dele para entender com que tipo de arquivo está lidando. Se o desenvolvedor verificar apenas a extensão, esse já é um motivo para dar uma olhada mais de perto.
Content-Type – o tipo MIME que veio do cliente. O problema é que ele é gerado no lado do navegador e pode ser facilmente substituído através de um proxy.
Corpo do arquivo, ou melhor, seu início – aqui estão os chamados magic bytes – assinaturas de bytes exclusivas que determinam o tipo real de conteúdo, independentemente da extensão. Por exemplo, um arquivo PNG sempre tem os primeiros bytes 89 50 4E 47 0D 0A 1A 0A. Se o desenvolvedor confiar apenas nos cabeçalhos e extensões, mas não verificar as assinaturas, esse é um caminho direto para o bypass.
Ataques Básicos: Como Contornar a Proteção Simples
Quando chegamos a um formulário de upload de arquivos, a primeira coisa que fazemos é tentar carregar algo malicioso: um shell PHP, JavaScript para XSS, SVG com código injetado. Em resposta, os desenvolvedores implementam mecanismos de proteção. As principais técnicas que ajudam a contorná-los: enumeração de extensões (.php5, .phtml, .phps), caracteres especiais (espaços, pontos, null-byte), substituição de maiúsculas e minúsculas (no Linux), recursos de normalização de nomes (no Windows), substituição de Content-Type, injeção de magic bytes, concatenação de arquivos e uso de extensões duplas.
Vamos começar com o cenário mais simples, quando não há proteção no servidor – todos os arquivos são aceitos e salvos em um diretório acessível pela web. Preparamos um shell simples com uma chamada para o comando id, carregamos uma imagem normal, interceptamos a solicitação no Burp e observamos sua estrutura. No corpo do arquivo, em vez da imagem, inserimos nosso código PHP, alteramos a extensão para .php. O servidor responde que o arquivo foi salvo. Seguimos o link – em vez da imagem, vemos o resultado da execução do comando.
Claro, em programas reais, esse cenário simples é raro. Na maioria das vezes, os desenvolvedores verificam algo: proíbem certas extensões, olham para o Content-Type ou até mesmo para o conteúdo do arquivo. E aqui técnicas um pouco mais complexas entram em jogo.
Uma das mais interessantes é o bypass através de magic bytes. O servidor aceita apenas imagens e olha para os primeiros bytes do arquivo. Substituir o Content-Type não ajuda – é necessário que o arquivo comece com a assinatura correta. Para esses casos, o Burp Suite tem a extensão Magic Bytes Selector. Ele permite que você substitua a assinatura do formato desejado no início do arquivo com um clique – GIF, PNG, JPEG e outros.
Se você quiser ver mais exemplos reais de bypass – do simples ao não óbvio – confira uma seleção de técnicas com exemplos de bug bounty no Briskinfosec.
Você Não Passará – Prática Avançada
Analisamos as técnicas básicas, mas os bugs reais geralmente se escondem mais profundamente. Para encontrá-los, você precisa entender como o arquivo carregado é processado após ser salvo – e é aqui que entram as características dos servidores, linguagens de programação e bibliotecas de terceiros. Antes de passar para técnicas específicas, vamos adicionar um pouco de teoria.
Características do Processamento de Arquivos – Linguagens de Programação, Servidores e Buracos nas Configurações
Quando falamos sobre upload de arquivos, não basta pensar apenas em extensões e magic bytes. O arquivo carregado entra em um ecossistema – servidor web, linguagem de programação, framework, bibliotecas de terceiros. Cada um desses componentes adiciona suas próprias nuances e, às vezes, vetores prontos para um ataque.
Servidores Web: Apache
O principal risco no Apache está associado ao arquivo .htaccess. Se o servidor permitir que ele seja carregado em uma pasta com arquivos de usuário, um invasor pode carregar seu próprio .htaccess com a diretiva AddHandler, que fará com que o Apache execute qualquer arquivo (por exemplo, com a extensão .evil) como PHP.
Além disso, o Apache às vezes é configurado para processar arquivos que contêm a substring .php no nome – então shell.php.jpg se tornará executável, mesmo que a extensão seja formalmente .jpg.
Servidores Web: Nginx + PHP-FPM
Em conjunto com o nginx e o PHP-FPM, um erro clássico é a diretiva cgi.fix_pathinfo=1. Com essa configuração, uma solicitação para /uploads/shell.png/shell.php fará com que o PHP-FPM abra o arquivo shell.png e execute o código PHP dentro dele, porque o nginx descarta parte do caminho após a barra. Este não é um bug do próprio PHP, mas uma característica do processamento de caminho que muitas vezes é esquecida. Sobre o quão longe você pode ir com essa característica e transformar LFI em RCE através de arquivos temporários do Nginx, está bem escrito no artigo PHP LFI with Nginx Assistance.
PHP
O vetor mais óbvio é simplesmente colocar um arquivo .php em um diretório web acessível. Mas existem técnicas mais complexas. Wrappers como php://filter e phar:// permitem executar código dentro de arquivos ou até mesmo imagens carregadas, se houver um include vulnerável no código. E se o desenvolvedor usar include para carregar arquivos, uma imagem legal com código PHP injetado pode se transformar em um shell completo – o suficiente para que o include processe o arquivo carregado.
Python e Node.js
A execução direta de arquivos carregados aqui é menos comum, mas isso não significa que eles sejam seguros. Muitas vezes, eles procuram path traversal para sobrescrever arquivos de configuração ou arquivos de script do próprio aplicativo. E se o aplicativo usar engines de template (Jinja para Python, Handlebars para Node.js), carregar um arquivo de template pode levar a SSTI – injeção de template do lado do servidor, que muitas vezes dá RCE.
Java
Os principais vetores são o upload de arquivos WAR ou arquivos JSP em diretórios que são processados pelo servlet container. Se você conseguir carregar malicious.war em uma pasta de implantação ou sobrescrever a configuração através de path traversal, você pode obter controle total sobre o aplicativo. Esses ataques são mais difíceis de executar, mas as consequências são mais graves.
Técnicas Avançadas
Analisamos os principais stacks e suas características, agora vamos passar para ataques específicos que usam esse conhecimento na prática. Alguns deles exigem uma confluência de circunstâncias, outros – uma abordagem não padronizada, mas cada um é capaz de levar à completa comprometimento do servidor.
.htaccess – Pequeno Arquivo com Grandes Consequências
Se o servidor permitir o upload de .htaccess, você pode sobrescrever as regras de processamento. Carregamos um arquivo com a diretiva AddHandler application/x-httpd-php .evil. Agora qualquer arquivo com a extensão .evil será executado como PHP. Carregamos shell.evil – obtemos RCE.
Race Condition: Roubar em ~0 Segundos
Às vezes, o desenvolvedor primeiro salva o arquivo e depois verifica – se é malicioso ou não. Se a verificação falhar, o arquivo é excluído. Entre o salvamento e a exclusão, há um microssegundo em que o arquivo está disponível via HTTP. Se você conseguir acessá-lo nesta janela, o código será executado. Na prática, isso é difícil: você precisa adivinhar o nome do arquivo, contornar as restrições de taxa de solicitação e, às vezes, alugar um VPS mais perto do servidor. A técnica em si merece um artigo separado.
Se você quiser tentar sozinho, recomendo o laboratório Web Security Academy sobre o tema de carregar um shell através de race condition.
Zip Slip – Path Traversal Através de Arquivos
O servidor aceita arquivos ZIP, descompacta-os e salva o conteúdo. Se o desenvolvedor não verificar os nomes dos arquivos dentro do arquivo, podemos especificar um caminho com bypass de diretórios. Criamos um ZIP onde o arquivo shell.php está localizado no caminho ../../../../var/www/html/uploads/shell.php. Ao descompactar, o sistema passa por todos os ../ e coloca o arquivo no diretório de destino. A vulnerabilidade se aplica não apenas ao ZIP, mas também a qualquer formato de arquivo: DOCX, XLSX, JAR, APK – em todos os lugares onde o servidor descompacta o conteúdo.
Se você quiser entender mais profundamente a mecânica do Zip Slip e ver exemplos de código, comece com um artigo detalhado no Snyk. Ele explica exatamente como um arquivo malicioso é formado e por que essa vulnerabilidade ainda é encontrada em projetos reais.
Processamento de Metadados: CVE-2016-3714 (ImageTragick)
Uma vulnerabilidade antiga, mas reveladora no ImageMagick. A biblioteca tentou executar o comando curl para carregar um arquivo por URL, e o comando foi montado através de uma chamada shell. A injeção de aspas duplas e ponto e vírgula permitiu executar um comando arbitrário.
Criamos um arquivo que começa com uma assinatura PNG e, em seguida, contém uma string com uma chamada para o comando id e grava o resultado em um arquivo no diretório web. Carregamos – o ImageMagick tenta executar curl, quebra, mas o comando id funciona e o resultado fica disponível via HTTP.
O Que Vem a Seguir
Analisamos as principais técnicas, mas o upload de arquivos não termina aí. Cada linguagem e framework adiciona suas próprias nuances. Java, Python, Node.js – em todos os lugares existem vetores específicos relacionados à configuração, processamento de arquivos e engines de template. O princípio geral permanece o mesmo: a validação deve ser abrangente. Extensão, Content-Type, magic bytes, estrutura do arquivo, local de salvamento – todos esses são elos de uma corrente. Se pelo menos um enfraquecer, isso pode levar a uma vulnerabilidade.
Conclusões
Pode parecer que as vulnerabilidades de upload de arquivos são algo simples e estudado há muito tempo. Mas, na prática, elas são encontradas em todos os lugares, desde pequenos serviços até grandes corporações, e levam às consequências mais graves: RCE, vazamento de dados, comprometimento total do servidor.
Também é importante que seja lucrativo procurá-los – você pode obter uma recompensa decente por um bug crítico e vulnerabilidades massivas em plugins populares trazem bounties mesmo após a divulgação pública.
Finalmente, compartilho links úteis sobre o tema:
Laboratórios Web Security Academy da PortSwigger – a melhor maneira de praticar. Na seção sobre upload de arquivos, existem várias tarefas práticas de diferentes níveis de dificuldade.
Burp Suite com extensões (Autorize, Turbo Intruder, Magic Bytes Selector).
Listas de extensões para enumeração – estão no SecLists.
Pesquisas sobre vulnerabilidades de arquivos – os links para elas estavam ao longo do artigo.
A todos, boas descobertas. E lembre-se: mesmo que o formulário pareça simples, um vetor inesperado pode estar escondido nele.
📤 Compartilhar & Baixar
🧰 Ferramentas recomendadas
Divulgação: alguns links são patrocinados. Podemos receber comissão se você comprar — sem custo extra para você. Só indicamos o que faz sentido para a comunidade.