it-swarm.dev

È possibile eseguire uno script php in un file di immagine?

Ho un sito Web php per il caricamento di immagini. Gli utenti possono caricare immagini sul mio sito Web. Un utente afferma di poter hackerare il mio sito Web utilizzando un'immagine caricata.

Ho aperto tutte le immagini che ha caricato sul mio server con il blocco note. L'ultima riga di un'immagine è:

À[email protected] ;
<?php

echo "test ok";
?>

Può hackerare il mio sito Web usando questa immagine? Come posso impedire agli utenti di caricare immagini come questa?

18
open source guy

I caricamenti di immagini (qualsiasi file in generale) sono molto difficili da rendere completamente sicuri, specialmente in PHP, che fornisce molti vettori di attacco.

Se ad esempio visualizzi l'immagine chiamando

require($someImage);

e quell'immagine ha PHP all'interno (come quello che hai pubblicato), può essere interpretata ed eseguita come tale.

Suppongo che, se afferma di possedere il tuo sito, molto probabilmente lo ha fatto. L'immagine che hai fornito di per sé non farà altro che stampare "test ok", ma quel codice potrebbe essere facilmente scambiato con alcuni che danno accesso non autorizzato (anche completamente illimitato) al tuo sito e server.

Per assicurarti che il file caricato sul tuo sito sia effettivamente un'immagine, rielaboralo usando Gd (o Imagick) e salva l'immagine elaborata. È una cattiva pratica salvare l'immagine originale, in particolare utilizzando il nome del file originale, poiché si apre a molti altri attacchi (ad esempio attraversamento di directory e sovrascrittura di file).

Ulteriori informazioni: https://www.owasp.org/index.php/Unrestricted_File_Upload

13
GBC

Sì, il tuo server could run PHP all'interno di un file immagine se non è configurato correttamente:

http://www.phpclasses.org/blog/post/67-PHP-security-exploit-with-GIF-images.html

Un esempio è image.gif.php. Un file può essere sia un'immagine valida sia un valido PHP, non è sufficiente controllare semplicemente la dimensione dell'immagine o altre proprietà. Né è sufficiente strip metadata , una GIF non compressa può contenere PHP come dati di immagine (anche se potrebbe non essere semplice), PNG supporta blocchi di dati arbitrari .

Il difetto sta accettando i caricamenti con un controllo di sanità mentale insufficiente, in particolare cercando di prevenire nomi di file indesiderati (ad esempio .php) Utilizzando una regex non ancorata come \.(png|gif|jpg|jpeg) (nessun ancoraggio $) , e che consentono di pubblicare quelle immagini da una directory con PHP abilitata. La migliore pratica è che dovresti probabilmente non usare mai un nome file fornito dall'utente così com'è.

Questi sono abbastanza classici validazione dati e validazione input ​​fallimenti.

Se segui le Istruzioni per l'installazione di PHP (per Apache 2) avrai qualcosa del genere nella tua configurazione di Apache:

<FilesMatch "\.ph(p[2-6]?|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>

Nota l'ancoraggio $, Impedirà a file.php.gif Di essere interpretato da PHP. (Ciò che manca in quelle istruzioni è assicurarsi che PHP è limitato da un contesto <Directory> Contenente solo codice attendibile e non scrivibile dall'utente del web server.)

Se non segui queste istruzioni e usi invece AddType di mod_mime (O AddHandler):

AddType application/x-httpd-php .php      # STOP! 

Ciò può causare lo stesso problema perché mod_mime Potrebbe fare qualcosa che non ti aspetti con più estensioni. Vedi http://blog.dynom.nl/archives/Be-careful-with-double-extensions_20081024_25.html (grazie a Hendrik Brummermann per averlo sottolineato) . Questo rischio può essere mitigato con un contesto <Directory> Correttamente configurato per consentire solo il codice attendibile.

Questo documento (PDF) è un po 'vecchio, ma copre bene le mitigazioni: http://www.net-security.org/dl/articles/php-file-upload.pdf

Un'altra possibile fonte di problemi sono le istruzioni non sicure include/require (anch'esse coperte in quel PDF) che consentono a un utente malintenzionato di caricare il contenuto include modificando le stringhe di query o le intestazioni delle richieste HTTP.

Vedi anche la recente domanda correlata: Rischi di a PHP modulo di caricamento dell'immagine (anche se non credo sia corretto fare affidamento su getimagesize per verificare immagini) e sa PHP per controllare il file di immagine caricato per malware? (che contiene un utile set di collegamenti).

20
mr.spuratic

Presumo che tu stia eseguendo LAMP (e una risposta per altre configurazioni php sarebbe molto simile).


Molto probabilmente, il suo codice non può fare nulla per il tuo sito.

Supponiamo che Apache stia offrendo file da /var/www sul tuo server. Dì che qualcuno visita index.php sul tuo sito web.

  1. Apache riceverà che stanno cercando /index.php
  2. Apache cercherà il file /var/www/index.php
  3. Se Apache esegue mod_php, verificherà se index.php corrisponde in qualche modo a una regola nel file di configurazione mod_php. Il tuo file di configurazione mod_php (probabilmente in /etc/Apache2/mods-available/php5.conf) è molto probabilmente un superset di questo esempio minimo che ho creato di seguito:

    <IfModule mod_php5.c>
        <FilesMatch ".+\.ph(p[345]?|t|tml)$">
            SetHandler application/x-httpd-php
        </FilesMatch>
    </IfModule>
    
    • Se il nome del file corrisponde, Apache eseguirà il file tramite un interprete php, creando una pagina Web che verrà servita all'utente.
    • Se il nome del file non corrisponde, Apache lo servirà semplicemente all'utente.
    • (Questi dettagli saltano molti frammenti di Apache che non credo siano rilevanti qui)

Supponiamo che un utente carichi un'immagine, diciamo evil_image.png e ha arbitrario PHP in esso.

Diciamo anche che lo servi agli utenti da qualche parte, diciamo a /images/evil_image.png (quindi nel tuo filesystem, /var/www/images/evil_image.png).

Quando qualcuno tenta di recuperare questa immagine accedendo al tuo sito Web all'indirizzo /images/evil_image.png, Apache eseguirà i passaggi sopra indicati. Al passaggio 3, /images/evil_image.pngnon corrisponderà al modello dal tuo file di configurazione, quindi non eseguirai il codice come php. Servirai semplicemente l'immagine all'utente.

L'utente riceverà il file immagine che contiene al suo interno il testo pericoloso creato. L'importante è che il server non abbia tentato di eseguire il codice, rendendolo inefficace.


Non sto dicendo che è impossibile eseguire quel codice. Ti dirò che devi mancare molto la configurazione del tuo server web per far eseguire quel codice.

1
David Mah