SQL INJECTION: come violare un sito internet!

SQL injection

La sicurezza informatica, campo applicativo in cui trova luogo questo articolo, è un settore molto vasto e variegato . La stessa è da intendersi come un processo piuttosto che un prodotto. E’ il risultato di scelte ed aspetti differenti. Possiamo intendere la sicurezza come una catena composta da diversi anelli: ognuno di questi fa la sua parte per la stabilità globale del sistema; ne deriva che la robustezza complessiva dipende dall’anello più debole della catena. L’obiettivo di questo articolo è soffermarci su uno di questi anelli: la SOL injection

SQL injection è un problema molto diffuso nell’ambito della scrittura di applicazioni web sicure. Vedremo le tecniche usate per sfruttare le vulnerabilità di applcazioni che presentano questa falla analizzando le misure e le buone regole da tenere in considerazione al fine di scrivere applicazioni che possano stare al sicuro da questa problematica . Requisiti essenziali: una buona conoscenza del linguaggio SOL. È richiesta anche una discreta dimestichezza con PHP e MySOL che saranno da supporto negli esempi proposti.

SQL injection

SQL INJECTION: TECNICA PER VIOLARE SITI                         

Se da un lato aumentano gli investimenti in sicurezza informatica (si registra un incremento dell’8% a livello  globale nonostante il perdurare della crisi economica) dall’altro si registra un incremento (sia in termini di numeri che di gravità) degli attacchi informatici! Le informazioni restano un patrimonio particolarmente appetibile, per motivazioni varie, da parte dei cyber criminali: è proprio in  quest’ottica, nella sfera della cyber security, che si colloca la SOL injection.

La SOL injection è una tipologia di attacco informatico, appartenente alla famiglia delle code injection, orientato a colpire applicazioni (in modo particolare le web application) che fanno uso di database SOL. Tramite questa tecnica  malintenzionati tentano di “iniettare” codice SOL non previsto all’interno di una pagina web al fine di alterarne il comportamento e visualizzare , prelevare, modificare o cancellare dati in modo non autorizzato. Inoltre, spesso, sono la premessa finalizzata ad ottenere le informazioni necessarie per portare avanti attacchi ben più articolati e sofisticati.

I tentativi di SOL injection sono difficili da monitorare: si confondono bene nel normale traffico di rete e, pertanto, le tradizionali misure di sicurezza spesso vengono messe in crisi o rese inefficaci da attacchi basati su questa filosofia.

A questa premessa , che introduce la problema­ tica , si aggiunge la grande diffusione delle SOL injection nel mondo dei cyber-attack tanto da risultare nella top 1O delle maggiori vulnerabilità stilata dall’Open Web Application Security Project (OWASP), riconosciuta organizzazione che si occu­pa della sicurezza delle applicazioni.

UN PRIMO ESEMPIO CONCRETO DI INJECTION

Vediamo ora un esempio di base di SOL injection. Utilizzeremo PHP e MySOL rispettivamente come linguaggio di scripting e come DBMS anche se ogni riferimento è facilmente estendibile ad altri linguaggi e database SOL utilizzati per scrivere applicazioni web based.

Supponiamo esista, all’interno di una applicazione web, un form destinato a raccogliere i dati di login di un generico utente:

<form action=’ verifica.php’ method= ‘post’ >

User : < input type=’te x t’ name=’user ‘ />

Password : <input type= passw ord’ name=’psw’ />

<input type= ‘submit ‘ />

</form >

Il form è abbastanza immediato : raccoglie due soli campi di input (user e psw) e li invia tramite POST ad una pagina chiamata verifica.php . All’interno della pagina verifica .php ci sarà una porzione di script che si occuperà di intercettare i dati passati dal form e fare un’interrogazione al DBMS al fine di verificare che nella tabella “utenti” sia presente un’utenza con le credenziali specificate. In caso positivo consentirà l’accesso ad un’area riservata, negli altri casi mostrerà un messaggio di errore.

La query che si occuperà di ottenere l’informazione sarà del tipo:

//Script PHP

//Leggo le variabili di POST usr e psw e le memorizzo in variabili

$user=$_POST[‘ user’ ];

$psw=$_POST[‘ psw’ ];

$query = “SELECT * FROMutentiWHERE user = ‘$user’

AND psw = ‘$psw”‘;

$sql = mysqli_query($DB_LINK,$query);

$row = mysqli_fetch_array($sql);

$number = mysqli_num_rows($sql);

if ($number==l)

{

//login corretto

//accesso all’area riservata

// ..

}

else

{

//login errato

// …

}

Come è facile notare, lo script illustrato non fa alcun tipo di controllo sulle variabili passate come POST dal form di autenticazione, questo lo rende vulnerabile al fenomeno della SQL injection.

Supponiamo esista un’utenza definita sul database con le seguenti credenziali:

usr = admin

psw = 839837

Se un utente malintenzionato andasse a compilare il form con queste credenziali:

usr = admin

psw = ‘ OR user=’admin

la query presente nello script diventerebbe (per semplice sostituzione delle variabili):

SELECT * FROMutentiWHERE user = ‘admin’ AND psw =” OR user = ‘admin’

È facile verificare che la select di cui sopra sarà sempre vera (supposto che esista l’utente admin definito) consentendo, di fatto, di superare il login senza conoscere la password dell’utente ed autenticarsi con i diritti e permessi dell’utenza di amministrazione!

Sfruttando la possibilità di inserire dei commenti nella sintassi SOL si aprono ulteriori scenari.

Usando infatti come usr= ‘ OR 1=1 — la password in questo caso risulta indifferente, infatti il doppio trattino è da intendersi l’inizio di un commento secondo la sintassi SQL pertanto tutto ciò che segue verrà ignorato. La query risulterebbe alterata come segue:

SELECT * FROM utenti WHERE user = ” OR 1 = 1 — AND psw = ”

Da notare che se fossimo in presenza di valori numerici, probabilmente, non ci sarebbe bisogno neanche di usare l’apice come visto nell’esempio precedente. Supponendo infatti di essere in un contesto di questo tipo:

/ / script PHP della web app

$id_utente=$_GET[‘ id_utente’ ] ;

$query = “SELECT *FROM utentiWHERE id=

$id_utente”;

dove $id_utente è un numerico che contiene l’identificativo di un utente passato tramite GET e non sottoposto ad alcun controllo, iniettando nella variabile di GET la seguente:

1 OR 1=1

si modificherebbe la query nel seguente modo:

SELECT * FROM utenti WHERE id = 1 OR 1=1

Come è facile osservare anche questa query è sempre vera, a prescindere dal valore dell’id, ed il risultato sarebbe di mostrare l’intero elenco utenti!