Gli exploit sono attacchi che sfruttano le vulnerabilità del software; per vulnerabilità si intende un difetto del codice, dovuto a qualche errore o superficialità nella realizzazione del programma, che si presta ad attacchi.
Spesso la vulnerabilità è dovuta alla mancata validazione dell’input nel programma; non si deve lasciare all’utente la possibilità di inserire qualcosa che non è permesso. Se l’utente inserisce dati non corretti come minimo l’output non sarà corretto (si parla di GIGO – Garbage In Garbage Out), ma potrebbero esserci anche degli effetti indesiderati e pericolosi. Per esempio se in qualche caso il programma può eseguire delle divisioni per 0, questo fatto potrebbe essere sfruttato intenzionalmente per bloccare il programma.
Qualche volta la vulnerabilità è dovuta alla presenza di trapdoor nel codice; una trapdoor è un punto di ingresso non documentato a un modulo, inserito nel programma durante lo sviluppo del codice per esempio a scopo di test; la trapdoor può rimanere nel programma per dimenticanza o essere lasciata intenzionalmente a scopo di manutenzione o come mezzo nascosto di accesso.
Le vulnerabilità in genere possono essere sfruttate solo con procedimenti abbastanza complessi da individuare (una volta che sono stati individuati e pubblicizzati però possono essere usati anche da persone non eccessivamente competenti).
Per difendersi bisogna cercare di correggere le vulnerabilità del software installando le versioni più aggiornate e tutti i moduli di correzione offerti dal produttore (patch).
Per individuare quali servizi sono attivi sul sistema, e quindi quali vulnerabilità potrebbero essere presenti, gli attaccanti esaminano le porte in ascolto sul sistema (scansione delle porte).
I firewall possono proteggere dai tentativi di scansione delle porte; se un client tenta di accedere a una porta/indirizzo non disponibile tramite un firewall, il firewall accetta l’inizio della sessione (SYN) ma non risponde mai (risposta segreta); in questo modo un attaccante non può capire se l’indirizzo esiste o no, o se la porta è aperta o chiusa.
I firewall meno recenti inviano un reset (RST) informando che l’indirizzo non esiste.
Alcuni esempi di exploit sono:
-
buffer overflow: un buffer overflow consiste nella scrittura in un buffer (un’area di memoria) di una quantità di dati superiore a quella contenibile dal buffer stesso, provocando intenzionalmente la sovrascrittura di zone di memoria adiacenti; l’hacker può usare un buffer overflow per attaccare un sistema remoto, sovrascrivendo parti di memoria riservate, iniettando del codice arbitrario e facendolo eseguire indipendentemente dalle restrizioni imposte sul sistema; in questo modo può riuscire anche ad ottenere il controllo totale del computer (o della rete se l’attacco avviene su un server di rete);
-
SQL injection: con questo attacco si riesce a far eseguire comandi SQL arbitrari e non autorizzati ad una applicazione che esegue una query SQL costruita in base a input passati da un utente;
-
cross site scripting: un attacco cross site scripting (CSS o meglio XSS) consiste nell’inserire del codice javascript nelle pagine di un sito che accetta messaggi o commenti inseriti dagli utenti (per esempio un forum), sfruttando il fatto che il codice del sito non controlli l’input inserito; quando un utente accede alla pagina per visualizzare i messaggi ottiene anche gli script e la loro esecuzione.
Si ribadisce che questi attacchi sono possibili solo in presenza di codice vulnerabile cioè non realizzato in modo corretto e sicuro.
In tutti e tre i casi la possibilità di eseguire l’attacco dipende dalla mancata validazione dell’input da parte di chi ha scritto il codice.
Per evitare un buffer overflow basta controllare la dimensione dei dati inseriti.
Per evitare un attacco SQL injection si può controllare che vengano inseriti solo i caratteri strettamente richiesti o almeno sostituire i caratteri '
e "
con le sequenze di escape \'
e \"
.
Alcuni server Web fanno automaticamente la sostituzione con le sequenze di escape (per esempio in PHP l’escape è controllato dalla direttiva magic_quotes_gpc
nel file di configurazione php.ini, che per default è attiva.
Un attacco cross site scripting si può evitare filtrando l’input degli utenti in modo da sostituire i simboli (come < o >) con i rispettivi codici esadecimali; in questo modo gli script non verranno eseguiti ma soltanto visualizzati.
L’utente può difendersi da un attacco cross site scripting disabilitando l’esecuzione di codice javascript.
Esempio – SQL injection
Un’istruzione che accede a una tabella di utenti:
in PHP
$risultato=mysql_query(select * from utenti where nome = '$nome' and password = '$password');
in JSP
String nome = request.getParameter("nome"); String password = request.getParameter("password"); ResultSet rs = st.executeQuery("SELECT * from utenti where nome='" + nome +"' and password='" + password +"'");
può essere usata per ottenere l’autorizzazione senza conoscere la password; per esempio inserendo come nome admin e come password:
1' or '1'='1
l’istruzione diventa:
select * from utenti where nome = 'admin' and password = '1' or '1'='1'
rendendo sempre vera la condizione ed eludendo il controllo della password.
L’istruzione potrebbe essere usata addirittura per inserire nel database un nuovo utente, che poi può essere usato per accedere al sistema; inserendo un nome qualsiasi (per esempio prova) e come password:
prova'; insert into utenti (nome, password) values ('pippo', 'pippo'); - -
l’istruzione diventa:
select * from utenti where nome = 'prova' and password = 'prova'; insert into utenti (nome, password) values (‘pippo’, ‘pippo’); --'
che corrisponde a due istruzioni; la prima cerca i dati (anche se non li trova), la seconda inserisce il nuovo utente nella tabella; i trattini indicano l’inizio di un commento (perchè non ci siano errori di sintassi a causa degli apici che delimitano le stringhe).
Se il DBMS non supporta gli statement multipli viene prodotto soltanto un messaggio di errore.
Altri errori nella scrittura dei programmi che si prestano ad attacchi di vario tipo sono:
-
Mediazione incompleta
è una situazione in cui dei dati sensibili si trovano in una condizione esposta non controllata, cioè i valori dei dati non sono completamente mediati; per esempio quando si passano dei parametri mediante un URL come nell’istruzione:
URL?param1=val1¶m2=val2
i valori dei parametri potrebbero essere modificati dall’utente; per esempio se tramite un parametro di questo tipo viene passato il il prezzo di un articolo acquistato l’utente potrebbe modificarlo con un valore inferiore;
-
Errori tempo di controllo/tempo di utilizzo
è una situazione in cui viene effettuato un controllo in un certo momento su chi accede, ma successivamente viene eseguita un’azione diversa senza che il controllo venga ripetuto.
Altri attacchi legati alla scrittura del codice, questa volta però non dovuti a una programmazione non corretta, ma realizzati in modo intenzionale, sono:
-
attacco granulare (salami attack): attacco in cui un programma unisce valori irrilevanti per ottenere risultati importanti (per esempio accumulando i valori decimali oltre i centesimi degli interessi di vari conti bancari nel conto dell’attaccante);
-
bug Web: chiamato anche tag pixel o gif in chiaro, gif invisibile o gif di segnalazione; è un’immagine invisibile (anche di un solo pixel), nascosta in un documento HTML, che permette al sito da cui viene scaricata l’immagine di inserire cookie sul computer dell’utente per tracciare le sue abitudini:
<img height=”1” width=”1” src=”http://url”>
Full disclosure, responsible disclosure e non disclosure
Le vulnerabilità individuate vengono pubblicate e discusse in siti Web, forum, mailing list ecc.
Si parla di full disclosure se oltre alle vulnerabilità vengono spiegati anche tutti i dettagli per ripetere l’attacco; si parla invece di responsible disclosure se vengono pubblicate solo le vulnerabilità.
La non disclosure è invece la politica seguita normalmente dai produttori di software, che consiste nel rilasciare le patch senza descrivere le vulnerabilità.