Corso di Sicurezza Informatica
Sicurezza del software
Ing. Gianluca Caminiti
SQL Injection
Sommario
• Premessa sul funzionamento
dinamici
• SQL Injection: Overview
• Scenari di attacco:
dei
siti
• Errata gestione dell’input (mancato filtraggio o
mancata gestione del tipo di dati)
• Strategie di attacco
– attacchi Blind
• Contromisure
Premessa: Siti Web Dinamici
• Interfaccia Web (lato client: HTML, Flash,
Javascript)
• Linguaggio di programmazione orientato a
web/database (“tipicamente” lato server: PHP,
ASP, .NET, JSP, ecc.)
• Database layer (lato server: MySQL, Oracle,
SQL Server, ecc.)
Interfaccia verso il DB
• Il linguaggio di programmazione server-side
permette di formulare queries in SQL,
parametrizzabili mediante variabili tipicamente
passate da un form HTML.
Esempi
• moduli HTML per ricercare nell’archivio di un
DB online (Amazon, IBS, ecc.)
• moduli per accesso a web-based email (login +
password, es. Hotmail)
• moduli per inserimento di commenti sui siti
(guestbook, forum, ecc.)
SQL Injection: Overview
• Tecnica che sfrutta una vulnerabilità presente
nel linguaggio che funge da interfaccia al DB
e/o nello strato del DB al fine di produrre
un’alterazione nella semantica del codice SQL
inteso.
• Si fa in modo che l’input dell’utente contenga
istruzioni SQL al fine di ottenere (lato server)
una query differente da quella intesa dal
programmatore.
Scenari tipici
• La vulnerabilità è presente quando si verifica una
delle seguenti condizioni:
– L’input inserito dall’utente non è affatto o correttamente
filtrato rispetto alle occorrenze di “sequenze di escape”
(tipicamente presenza di apici).
– L’input inserito dall’utente non subisce verifiche sul tipo di
dati e pertanto sono possibili esecuzioni inaspettate.
– Sono presenti errori di programmazione nel software del
server di Database che consentono a utenti malicious di
sfruttarne gli effetti per eseguire codice SQL arbitrario.
1. Sequenze di escape non
filtrate correttamente
• un semplice modulo HTML per inserire username e password
<form action='login.php' method='post'>
Username: <input type='text' name='user' />
Password: <input type='password' name='pwd' />
<input type='submit' value='Login' />
</form>
•
I dati immessi sono passati al file login.php, rispettivamente nelle variabili
$_POST['user'] e $_POST['pwd']. Una volta ricevuti questi dati, PHP
esegue una query sul DB.
codice PHP
<?php
$query = "SELECT * FROM users WHERE user='"
.$_POST['user']."' AND pwd='" .$_POST['pwd']. "'";
$sql = mysql_query($query,$db);
//Se il numero di righe trovate > 0 allora i dati
immessi sono corretti
if(mysql_affected_rows($sql)>0)
{
//permette l'accesso alle pagine protette
}
?>
Esempio con input tipico
• L’utente inserisce BillGates come user e
Windows come password.
• La query sarà
SELECT * FROM users WHERE
user='BillGates' AND pwd= 'Windows'
Esempio di attacco/1
• L’utente inserisce BillGates come user e
' OR user='BillGates come password.
• La query sarà
SELECT * FROM users WHERE
user='BillGates' AND pwd= '' OR
user='BillGates‘
• Quando funziona questo attacco?
Esempio di attacco/1
• L’utente inserisce BillGates come user e
' OR user='BillGates come password.
• La query sarà
SELECT * FROM users WHERE
user='BillGates' AND pwd= '' OR
user='BillGates‘
• L’attacco funziona solo se esiste un utente
BillGates
Esempio di attacco/2
• Attacco blind: l’utente inserisce x' OR 1=1 sia
come user che come password.
• La query sarà
SELECT * FROM users WHERE
user='x' OR 1=1 AND pwd='x' OR 1=1
• Qual è l’effetto di questa query?
Esempio di attacco/2
• Attacco blind: l’utente inserisce x' OR 1=1 sia
come user che come password.
• La query sarà
SELECT * FROM users WHERE
user='x' OR 1=1 AND pwd='x' OR 1=1
• Il risultato non dipende dalla precedenza degli
operatori: la condizione è sempre vera, ci si
autenticherà come l’utente rappresentato dalla
prima tupla del DB (admin?)
Simulazione di Attacco
2. Scorretta gestione dei tipi di dati
• Attacco NON blind: si verifica quando mancano verifiche sui
vincoli di tipo dei dati di input. Si pensi ad un modulo per la
ricerca di prodotti in un catalogo in base al codice.
$query = "SELECT * FROM data WHERE id=" .$variabile_intera. ";"
• La variabile $variabile_intera è di tipo stringa, anche
se il tipo di dati inteso per l’input è int. L’utente può inserire
come id la stringa: 1; DROP TABLE data
SELECT * FROM data WHERE id = 1; DROP TABLE data;
•
Cosa succede se l’utente inserisce come input
1; SELECT * FROM data
?
Blind SQL Injection
• Per “indovinare” i nomi delle tabelle
SELECT COUNT(*) FROM tabname
(restituisce valori solo quando la tabella tabname esiste)
• Per “indovinare” i nomi dei campi delle tabelle
SELECT x FROM users
(con x che rappresenta il tentativo)
• Per indovinare i nomi degli utenti
SELECT 1/0 FROM users WHERE
username='Ralph'
Contromisure
• Verificare bug ed exploit del sistema in uso
• fissare limitazioni sui diritti di accesso al DB
• filtrare opportunamente le sequenze di escape
(ci sono funzioni appositamente definite nei
linguaggi)
• whitelisting basate su espressioni regolari
• forzare la conversione di tipo delle variabili di
input nel target desiderato (es. stringa Æ int)