PDA

View Full Version : [php]Form: vulnerabilità?


$te
25-11-2009, 11:36
Slave...ultimamente sto ricevendo "attacchi" (non so se chiamarli tali) al mio sito, in cui ho un form contatto. In pratica mi aggiungono un pezzo di codice, ma, se non ricordo male, solo nei file non php (ieri nel file config.inc). Com'é possibile che accada? come fare per difendermi? Se qualcuno ha voglia di cercare di "attaccare" il mio sito, per poi dirmi le vulnerabilità, mi può mandare un mess in privato.

grazie mille!!!

bottomap
25-11-2009, 13:26
Ciao,

Se stiamo parlando di una form mail, documentati sul concetto di mail-header injection:
http://en.wikipedia.org/wiki/E-mail_injection
http://www.damonkohler.com/2008/12/email-injection.html

Più in generale ripulisci attentamente tutti i parametri $_GET/$_POST prima di utilizzarli per formare uno qualsiasi dei parametri della mail.

Ciaociao :)

$te
25-11-2009, 16:31
Ciao,
Più in generale ripulisci attentamente tutti i parametri $_GET/$_POST prima di utilizzarli per formare uno qualsiasi dei parametri della mail.

in che senso ripulire?
Sapresti postarmi un form "pulito"?
sono meglio i formailer?
grazie!

bottomap
25-11-2009, 16:44
Ciao,

Il sito è quello in firma?

Se non si tratta di una mail-header injection (solitamente utilizzata sulle form mail), probabilmente hai un problema di XSS o di SQL-Injection.

In ogni caso alla base c'è sempre la mancata pulitura dei parametri in arrivo allo script (ed eventualmente l'uso - da evitare assolutamente a meno di non avere alternative - della register_globals ad on nel php.ini).

Il linguaggio php ti fornisce una serie di funzioni esplicitamente pensate per ripulire il codice prima di stamparlo a video o usarlo in una query (htmlentities, htmlspecialchars, stripslashes, mysql_real_escape_string).
Per usi più fini poi (ad esempio togliere cc: o \r\n dal testo di una mail) hai comunque tutta una serie di funzionalità che operano su stringhe (preg_replace, strstr, str_replace).

Ciaociao :)

BlackAuron
25-11-2009, 21:06
Ho dato giusto una occhiata al tuo sito, e ti consiglio di contattare al più presto qualcuno che si occupi di web application security a livello professionale :)
Se ti serve,non appena avrò tempo, in PM posso inviarti la lista delle vulnerabilità che ho trovato facendo una analisi non troppo approfondita del tuo sito, ma credo che ti serva pure un aiuto per capire come tappare le falle.


PS: Se il tuo sito non è già stato compromesso, ritieniti molto fortunato ...

$te
26-11-2009, 07:53
Comunque con il form, possono solo sfruttare la funzione mail() per fare dello spam ? perché il problema é proprio che mettevano del codice maligno nei miei files!!!

vhost87
26-11-2009, 08:46
Ho dato giusto una occhiata al tuo sito, e ti consiglio di contattare al più presto qualcuno che si occupi di web application security a livello professionale :)
Se ti serve,non appena avrò tempo, in PM posso inviarti la lista delle vulnerabilità che ho trovato facendo una analisi non troppo approfondita del tuo sito, ma credo che ti serva pure un aiuto per capire come tappare le falle.


PS: Se il tuo sito non è già stato compromesso, ritieniti molto fortunato ...

Oddio dai, non penso generi una mole cosi impressionante di traffico.

BlackAuron
26-11-2009, 08:50
il problema non è solo la mail, ci sono falle ben peggiori ... che ti ho segnalato in PM :)

@michele : ha quell'indirizzo in firma in un forum piuttosto popolato : chiunque sia interessato a danneggiarlo personalmente, potrebbe farlo senza troppi problemi, una RFI e diverse XSS ( e probabilmente qualche SQL injection point ) non sono proprio vulnerabilità da nulla.
Tra l'altro, se i permessi del server sono settati male, rischia pure un mass deface di tutti i siti hostati ... ma si, forse sono catastrofista :)

bottomap
26-11-2009, 09:09
Ciao,

Come dice BlackAuron non sono proprio cosette da niente.

La mail-header injection è verificata (come detto via PM - ma a parte agevolare gli spammer non può portare ad osservare quanto hai descritto), confermo le XSS (l'RFI non l'ho individuato ma sicuramente ci sarà).
Confermo pure l'SQL-injection (o almeno la possibilità) vista una delle XSS che mi informa che "la query è errata" e di controllarne la sintassi.

Per quanto riguarda la modifica fisica di file .inc o .js come $te faceva notare, necessariamente il malintenzionato è riuscito ad ottenere le credenziali per l'accesso o ha installato una shell (E se c'è una RFI la cosa è probabile).

Alla base di tutto, in ogni caso, ci sono sempre input esterni non filtrati, che sia mail-header injection, XSS, RFI, SQL-injection. Tutti gli spezzoni di codice che coinvolgono array autoglobali ($_POST e $_GET in primo luogo) vanno filtrati accuratamente...

Ciaociao :)

BlackAuron
26-11-2009, 09:40
La RFI è confermata, testata e funzionante, e, come dettoin pm, credo che quello sia il problema maggiore: tramite essa, uno non solo ha accesso a tutti i file che hosti (quindi pure i files di configurazione, dai quali uno può ottenere le tue credenziali di accesso e i dati per accedere al db), ma li può pure spostare, modificare, ed eventualmente fare l'upload di qualunque cosa.
Come già suggerito, la soluzione è unica: controlla ogni variabile che l'utente può modificare, e controlla che i numeri sian numeri, gli URL siano URL, le immagini immagini, and so on.

$te
26-11-2009, 10:27
La RFI è confermata, testata e funzionante, e, come dettoin pm, credo che quello sia il problema maggiore: tramite essa, uno non solo ha accesso a tutti i file che hosti (quindi pure i files di configurazione, dai quali uno può ottenere le tue credenziali di accesso e i dati per accedere al db), ma li può pure spostare, modificare, ed eventualmente fare l'upload di qualunque cosa.
Come già suggerito, la soluzione è unica: controlla ogni variabile che l'utente può modificare, e controlla che i numeri sian numeri, gli URL siano URL, le immagini immagini, and so on.
puoi farmi un es di come puoi "entrare" nel mio sito pf?(magari in ptv). QUindi in pratica, ogni volta che uso delle variabili, come ad es nella pag: ?servizi/campi.php&img=, come faccio? devo controllare che img sia uguale ad un numero che é predefinito?(quindi se ho 20 immagini..il numero non puo che essere tra 0 e 20)

bottomap
26-11-2009, 10:37
Ciao,

Non tanto delle variabili in senso stretto quanto di tutta la roba che proviene dall'esterno ... nella porzione di url che hai postato ricevi un parametro in $_GET['img'].

Devi assicurarti prima di tutto che sia un numero, poi eventualmente verificare, se tale numero ha dei limiti superiore e inferiore, che sia un numero nel range che ti aspetti.

Per testare se una stringa contiene un numero puoi sfruttare la funzione is_numeric() di php che ti ritorna un booleano true o false. La is_numeric accetta coem valido anche un simbolo di segno (+-) e il punto decimale (.).
In alternativa la intval() ti restituisce il valore numerico contenuto in una stringa (0 se la stringa non può essere interpretata come numero).
Ancora in alternativa puoi ricorrere ad una trim() con un parametro opzionale. trim(stringa,'0123456789') toglie di mezzo tutto ciò che non è una cifra dalla stringa.

Ciaociao :)

$te
26-11-2009, 10:44
Ciao,

Non tanto delle variabili in senso stretto quanto di tutta la roba che proviene dall'esterno ... nella porzione di url che hai postato ricevi un parametro in $_GET['img'].

Devi assicurarti prima di tutto che sia un numero, poi eventualmente verificare, se tale numero ha dei limiti superiore e inferiore, che sia un numero nel range che ti aspetti.

Per testare se una stringa contiene un numero puoi sfruttare la funzione is_numeric() di php che ti ritorna un booleano true o false. La is_numeric accetta coem valido anche un simbolo di segno (+-) e il punto decimale (.).
In alternativa la intval() ti restituisce il valore numerico contenuto in una stringa (0 se la stringa non può essere interpretata come numero).
Ancora in alternativa puoi ricorrere ad una trim() con un parametro opzionale. trim(stringa,'0123456789') toglie di mezzo tutto ciò che non è una cifra dalla stringa.

Ciaociao :)
ok grazie!!! pero nel caso di un testo...la cosa si fa molto piu dura vero? (anche ad es in una iscrizione) Nel caso in cui m'aspetto, ad es, un campo "Nome", limitando il numero di caratteri (ad es a 15), limito tanto questi attacchi? o dal momento che uno sa che esiste questa limitazione...riescono a raggiararla?

BlackAuron
26-11-2009, 10:55
Mah... Relativamente: se vuoi un nome, controlla che non contenga apici o caratteri speciali, se vuoi una mail controlla che il formato sia valido, e via dicendo.
Ci sono infinite funzioni php per 'aggiustare' input corrotti, vedi mysql real escape o simili. Sta a te capire cosa puoi accettare e cosa no.

bottomap
26-11-2009, 11:00
Ciao,

Nel caso del testo "libero", in genere si cerca di filtrare un poco i possibili contenuti.

In primo luogo se quello che ti aspetti ha una forma specifica (un url, un numero di telefono, un indirizzo) si può usare un'espressione regolare per validare quello che viene immesso.

In secondo luogo, per evitare che quel campo contenga codice html (che si inietterebbe nella pagina) venga riusato direttamente sulla stessa, si passa il tutto almeno attraverso la funzione htmlentities() (ma si può anche bloccare proprio l'invio se si presentano tag html - anche in questo caso un'espressione regolare può aiutare), che impedisce l'iniezione di codice html.

Per la RFI, cerca se possibile di non usare require() o include() sul valore di una variabile o di usare la variabile come src o href di un qualsiasi tag html. Soprattutto se la variabile proviene da una richiesta POST o GET.
Se proprio devi (ma in generale non è obbligatorio), puoi cercare di stabilire:
- una politica per il nome del file (la stringa deve avere certe caratteristiche specifiche) in modo da poterne verificare la correttezza.
- una politica di path (vietati i caratteri di slash / \ ed eventualmente di protocollo http:, ftp:, file:, ). Il file è relativo. Il path, se necessario, lo generi tu in testa, dall'esterno non dovrebbe mai arrivare.
- una politica per i caratteri speciali (vieti %00, \0, \n, \r e/o ogni cosa che non rientra in un insieme di caratteri applicabili per la natura del dato in input (anche in questo caso una espressione regolare può aiutare).

Edit: Ooops, crossposting...

Ciaociao :)

vhost87
26-11-2009, 11:06
il problema non è solo la mail, ci sono falle ben peggiori ... che ti ho segnalato in PM :)

@michele : ha quell'indirizzo in firma in un forum piuttosto popolato : chiunque sia interessato a danneggiarlo personalmente, potrebbe farlo senza troppi problemi, una RFI e diverse XSS ( e probabilmente qualche SQL injection point ) non sono proprio vulnerabilità da nulla.
Tra l'altro, se i permessi del server sono settati male, rischia pure un mass deface di tutti i siti hostati ... ma si, forse sono catastrofista :)

Un pò dai :D
Comunque concordo con te sulle vulnerabilità.

EDIT: non ci avevo fatto caso che il sito incriminato fosse in firma, al mattino presto connetto a fatica :D

$te
26-11-2009, 21:49
ma, dato che penso proprio sia un problema comune e diffuso, non esiste una guida o un tool con su gia tutte le indicazioni (consigli e soluzioni), che possano rendermi la vita piu facile...ma soprattutto sicura?....so che chiedo tanto...

BlackAuron
26-11-2009, 22:42
http://www.owasp.org/images/5/56/OWASP_Testing_Guide_v3.pdf
è LA guida relativa alla web application security ... c'è da vedere se hai tempo e voglia di studiartela per bene.

$te
26-11-2009, 22:49
http://www.owasp.org/images/5/56/OWASP_Testing_Guide_v3.pdf
è LA guida relativa alla web application security ... c'è da vedere se hai tempo e voglia di studiartela per bene.

e no appunto...ne tempo...ne voglia:P ma pensavo a qlc di piu semplice (in cui ti fanno es di codice per "tutte" le situazioni, form contatto, ecc).

BlackAuron
26-11-2009, 22:55
pretendi troppo. C'è gente che come lavoro perfeziona la sicurezza di siti web e determina la soluzioni a potenziali falle, se esistesse una guida di quel tipo sarebbe troppo facile :) tra l'altro, la guida che ti ho postato è praticamente la più breve a riguardo che puoi trovare.

$te
27-11-2009, 07:30
pretendi troppo. C'è gente che come lavoro perfeziona la sicurezza di siti web e determina la soluzioni a potenziali falle, se esistesse una guida di quel tipo sarebbe troppo facile :) tra l'altro, la guida che ti ho postato è praticamente la più breve a riguardo che puoi trovare.

eheh...immaginavo...xo io ci speravo:P

Ma allora, in pratica dovrei fare cosi: in un qualsiasi form, dove l'utente puo inserire propri dati:
- telefono: accertarsi che sia un numero, e limitare il numero di numeri
- Nome: accertarsi che contenga solo lettera e limitare anche qui il numero (non piu di 20 ad es)
- commento libero: accertarsi non siano caratteri strani, e limitare anche qui il numero

E poi cercare di limitare i form, dando gia io molte opzioni di scelta.

Oltre ai form, devo sistemare le pag che hanno un indirizzo che si "crea" a differenza della scelta dell'utente: qui devo prevedere tutte le possibilità, e accertarmi che sia una di queste.

Oltre a questo, devo stare attento a tutte le pag con GET e POST e "pulirli", giusto?

grazie

BlackAuron
27-11-2009, 09:35
Non devi controllare solo i form, ma TUTTTe le variabili che in un modo o nell'altro l'utente può modificare: quindi, in linea di massima, tutte quelle il cui valore lo peschi da $_GET, $_POST e $_COOKIE.

$te
30-11-2009, 09:22
Non devi controllare solo i form, ma TUTTTe le variabili che in un modo o nell'altro l'utente può modificare: quindi, in linea di massima, tutte quelle il cui valore lo peschi da $_GET, $_POST e $_COOKIE.

quindi, qnd uso una di quelle funzioni, devo controllare che la variabile che prendo é quella che mi aspetto.
Ma limitando i caratteri in un testo (a 20 pensavo)..limito abb codice maligno??

$te
10-12-2009, 07:12
Ecco, cosa ho fatto: ho un get da cui mi aspetto un numero da 0 a 41, ecco che accorgimento ho attuato:

if($_GET['numero'])

{

if( is_numeric( $_GET['numero']) ) $numero = $_GET['numero'];
else die();
if($numero > 41) die();
}


Pensate vada bene?

kurts
10-12-2009, 10:08
is_numeric accetta anche numeri in formato esadecimale ed in notazione esponenziale.
inoltre prevedi il caso in cui il numero è maggiore di 41 ma non quwello in cui è minore di zero.
invece di usare i die() non ti conviene mettere degli echo per mostrare dei messaggi e continuare con l'esecuzione?

P.S.: dai un'occhiata al cast di tipo in php, in questo caso (int)

$te
10-12-2009, 10:59
is_numeric accetta anche numeri in formato esadecimale ed in notazione esponenziale.
inoltre prevedi il caso in cui il numero è maggiore di 41 ma non quwello in cui è minore di zero.
invece di usare i die() non ti conviene mettere degli echo per mostrare dei messaggi e continuare con l'esecuzione?

P.S.: dai un'occhiata al cast di tipo in php, in questo caso (int)

allora, ricapitolando:
1. controllare i numeri minori di 0
2. controllare se e' un numero int, quindi naturale
3. invece che die, mettere un echo.

Avevo messo die, perche mi semplifica la vita, pero meglio essere puliti e precisi. Grazie per i consigli.

Ora, come passo successivo, volevo mettere a posto il form login.
Come prima cosa limito il numero a 15, pero poi nn so che fare.....:confused:

kurts
10-12-2009, 15:57
cos'è 15?? quale login??:confused: :mbe:

$te
10-12-2009, 17:55
cos'è 15?? quale login??:confused: :mbe:

mi sono spiegato male:P

Ho un form login nel mio sito, e ho limitato la lunghezza degli input a 15 (maxlength).

$te
11-12-2009, 09:14
da quanto ho capito, la cosa piu grave (in teoria) e' l'xp cmdshell. Come posso evitarla?
grazie

$te
14-12-2009, 10:11
in piu, con la funzione trim, limito i caratteri a le lettere dell'alfabeto.