Se elenchiamo le vulnerabilità nelle applicazioni web che hanno avuto il maggiore impatto per il grado di gravità che possono causare, senza dubbio troveremo il SQL Injection. Questo vulnerabilità può anche consentire all'aggressore di passare dall'elencare il contenuto del database all'ottenere l'accesso completo al serverVediamo in cosa consiste.
Il termine iniezione, si riferisce all'inserimento o all'aggiunta di istruzioni SQL in una query che l'applicazione esegue nel database, questo viene effettuato sfruttando qualsiasi input di dati che l'applicazione richiede direttamente o indirettamente dall'utente, si fa riferimento direttamente ai campi, ad esempio dei moduli dove l'utente inserisce determinati dati, indirettamente potrebbero essere parametri che vengono passati tramite URL (GET). L'obiettivo dell'inserimento di istruzioni SQL nella query è modificare la logica di detta query o il risultato che verrà restituito dal database.
Questo è un tipico form in cui vengono richiesti username e password per accedere ad un'area riservata. Il codice lato server che forma la query sarebbe qualcosa di simile al seguente:
$ nome utente = $ _POST ['nome utente']; $ password = $ _POST ['password']; $ sql = "SELECT * FROM utenti WHERE nome utente = '$ nome utente' AND password = '$ password'";Come possiamo vedere, prima vengono memorizzati rispettivamente il nome utente e la password inseriti nelle variabili nome utente e password, quindi questi valori vengono inclusi nella query che verrà inviata al database per verificare se tale utente esiste. Supponiamo che nel nostro esempio l'utente inserisca come nome utente admin e password pass123, al momento dell'invio del modulo, la query formata sarà la seguente:
SELECT * FROM utenti WHERE username = 'admin' AND password = 'pass123'Come possiamo vedere, quando i dati di input vengono inseriti, questi sono tra le virgolette singole per rappresentare che si tratta di una stringa di testo. Tale interrogazione verrà inviata al database e restituirà un risultato con i dati di detto utente, se presente, e sarà consentito l'accesso all'area riservata, altrimenti restituirà un risultato vuoto e l'accesso sarà negato.
Come abbiamo accennato in precedenza, SQL Injection Consiste nell'aggiungere codice SQL a una query e questo modulo lo consente attraverso i campi di input, in modo da avere un'applicazione vulnerabile all'iniezione SQL.
Sfruttare la vulnerabilità
L'obiettivo dello sfruttamento di questa vulnerabilità è accedere all'area privata senza conoscere il nome utente o la password corretti e sfruttare la vulnerabilità. Quindi quello che dobbiamo ottenere è iniettare codice SQL per formare una query che restituisca un risultato valido.
Vediamo come si forma la query se iniettiamo il seguente codice SQL nel campo password:
Quando viene formata la query, sarà la seguente:
SELECT * FROM utenti WHERE nome utente = 'hacker' AND password = '' o 1 = 1 # 'Importante attenzione va posta al fatto che il codice inserito è tra le virgolette singole che racchiudono la password, la virgoletta singola all'inizio del codice inserito è responsabile del completamento delle virgolette aperte nella password = 'parte della query, in questo modo otteniamo temporaneamente la seguente query:
SELECT * FROM utenti WHERE nome utente = 'hacker' AND password = ''Questa query al momento non restituirà risultati poiché non esiste tale utente con quelle credenziali, tuttavia analizziamo il resto del codice inserito:
o 1 = 1 #Frase o 1 = 1 cambia radicalmente la logica della query, poiché come sappiamo in una query formata dal condizionale O Ritornerà vero quando almeno una delle due espressioni è soddisfatta, nel nostro caso la prima espressione è nome utente = 'hacker' E password = '' , e il secondo o 1 = 1 , quest'ultimo è sempre vero, ovvero 1 è sempre uguale a 1, perché la query restituirà un risultato valido.
Infine dobbiamo eliminare le virgolette che chiudono la frase, per questo possiamo usare i commenti usati in SQL: #, - (doppio trattino), oh bene /* */ . quindi la query completa è:
SELECT * FROM utenti WHERE nome utente = 'hacker' AND password = '' o 1 = 1 # 'Tutto ciò che segue il # verrà preso in considerazione come commento e non farà parte della query.
Per ottenere un risultato valido ci sono molte altre varianti nel codice che possiamo inserire, ad esempio: