SQL Injection The dark side of webapplication *** Siamo davvero certi che chi gestisce i nostri dati sensibili lo faccia in modo sicuro?
Che cos'e' SQL? Acronimo di 'Structured Query Language E' un linguaggio per l'interazione con databases relazionali Sviluppato in principio da IBM nel 1974 Standard ANSI ed ISO (attuale versione SQL:2008) Molti RDBMS hanno estensioni proprietarie oltre al linguaggio SQL standard.
Struttura del database, le tabelle Un RDBMS e' composto da una o piu' tabelle identificate da un nome Ogni tabella contiene dei records che costituiscono i dati La nostra tabella di esempio si chiama 'users' e contiene dati distribuiti su righe e colonne: ID username firstname lastname password 0 mynx Alice Smith qwerty 1 ranger Bob Parker passw0rd 2 orb John Doe t00133t4u
Data Manipulation Language (DML) SQL prevede una sintassi (statements) per inserire, eliminare e modificare i records: SELECT INSERT INTO UPDATE DELETE
Data Description Language (DDL) Analogamente esistono statements per operare sulla struttura del database, quelli piu' comunemente usati sono: CREATE TABLE ALTER TABLE DROP TABLE
Interrogare il database: Interagire col DB SELECT lastname FROM users WHERE id='0'; Risultato: Lastname ------------------- Smith
SQL Injection La SQL Injection e' una tecnica che permette l'exploiting di applicazioni web che non filtrano opportunamente l'input rendendo cosi' possibile l'immissione di codice SQL arbitrario lato client.
Quanto e' comune? Ad oggi e' la vulnerabilita' piu' comune riscontrabile su applicazioni e siti web Non e' un problema relativo al DB, al webserver o all'application server E' una vulnerabilita' meramente applicativa dovuta a: Errori nel design dell'applicazione o del sito Molti sviluppatori non conoscono il problema Le soluzioni reperibili su internet spesso non sono efficaci, fornendo un falso senso di sicurezza
Cosa e' vulnerabile? Se l'applicazione e' vulnerabile e' possibile accedere a qualsiasi db che ne gestisca i dati (MySQL, ORACLE, Postgres, MS Sql, Sybase, DB2, Informix...etc) Sono potenzialmente vulnerabili: Pagine scritte in php, asp, jsp JavaScript XML, XLS Applicazioni web per la gestione dei databases Altro...molto altro
Come funziona? Consideriamo la seguente SELECT: SELECT Username FROM users WHERE Username = 'pippo' AND Password = 'qwerty' Supponiamo un codice simile a: SQLQuery = "SELECT Username FROM Users WHERE Username = '" & strusername & "' AND Password = '" & strpassword & "'" strauthcheck = GetQueryResult(SQLQuery) If strauthcheck = "" Then boolauthenticated = False Else boolauthenticated = True End If
Login: 'OR''=' Password: 'OR''=' La query risultera' essere: Cosa succede se... SELECT Username FROM users WHERE Username = '' OR ''='' AND Password = '' OR ''='' Che ritorna sempre TRUE!
Riconoscere le vulnerabilita' Non e' sempre semplice, mai tralasciare i dettagli La fantasia e l'approccio atipico sono una carta vincente Non sempre le webapplication restituiscono errori... Controllare i sorgenti delle pagine Controllare gli headers Controllare i commenti nelle pagine Attenzione ai 302
Cercare le vulnerabilita' Le vulnerabilita' possono celarsi in posti diversi: Campi nei form Parametri passati agli script attraverso l'url Parametri presenti nei cookies o in campi nascosti o bloccati Effettuare il fuzzing di tutto cio' che puo' essere vulnerabile attraverso tool automatici e non
Caratteri utili ' o " Racchiudono una stringa -- o # Commento singolo /*...*/ Commento multilinea Concatenazione % Wildcard
SELECT tricks Spesso l'unico parametro che possiamo 'injectare' e' la clausola WHERE dello statement SQL Ottenere piu' informazioni attraverso UNION: SELECT something FROM sometable UNION SELECT password FROM users WHERE 1=1;
La potenza di UNION UNION combina i risultati di due o piu' query in un solo set contenente tutte le righe risultanti dalle query oggetto di UNION I risultati delle query devono avere lo stesso numero di colonne. La clausola ALL per uscire da eventuali SELECT DISTINCT
ANCORA SU UNION Ottenere solo quello che ci serve: Codice: SQLString = "SELECT nome, cognome, titolo, FROM dipendenti WHERE citta='" & strcity & "'" Injection: ' UNION ALL SELECT something FROM sometable WHERE ''=' Risultato: SELECT nome, cognome, titolo, FROM dipendenti WHERE citta='' UNION ALL SELECT something FROM sometable WHERE ''=''
Vogliamo di piu' Il contenuto del db non ci basta, vogliamo interagire col sistema operativo Molti DB includono funzioni che permettono di interagire con l'os del server: Recuperare password e files di configurazione Cambiare password e configurazioni Eseguire dei comandi alterando file di configurazione o script di init
Accedere all'os con MySQL MySQL usa la funzione load_file() per accedere ai file Supponiamo di injectare qualcosa di simile a: 'union select 1,load_file('/etc/passwd'),1,1,1; Oppure create table temp( line blob ); load data infile '/etc/passwd' into table temp; select * from temp;
Come difendersi? Quasi facile: Validare l'input! Definire tipi di dato per ogni campo Implementare filtri il piu' possibile stringenti Se l'input e' numerico usare una variabile numerica Scartare l'input malevolo invece di tentare di modificarlo Implementare filtri su keyword riconosciute come pericolose (insert, select, update, delete, drop, --, etc)
Hardening di sistema Un sistema il piu' possibile sicuro aiuta a prevenire: Usare utenze non privilegiate per il DB Grant opportuni per le utenze del DB Auditing delle password per tutti gli account Introdurre firewall applicativi e IDS
Tools: SQLmap (http://sqlmap.sourceforge.net/) Paros proxy (http://www.parosproxy.org/) Burp (http://portswigger.net/) Nikto (http://cirt.net/nikto2/)
Links: OWASP (http://www.owasp.org/) WASC (http://www.webappsec.org/)
Quindi...
Contatti: Francesco Mormile E-mail: shiva@slackware.it Web: http://shiva.slackware.it/