php - SQL 注入(inject)易受攻击的代码,即使我们正在清理输入 mysql_real_escape_string

标签 php sql security sql-injection owasp

我们被攻击了;黑客从下面代码中的 页面进入系统,但我们无法找出这段代码中的实际问题。

您能否指出此代码中的问题以及可能的修复方法?

    <?php
        //login.php page code
        //...
        $user = $_POST['user'];
        $pass = $_POST['password'];
        //...
        mysql_connect("127.0.0.1", "root", "");
        mysql_select_db("xxxx");

        $user = mysql_real_escape_string($user);
        $pass = mysql_real_escape_string($pass);
        $pass = hash("sha1", $pass, true);
        //...
        $query = "select user, pass from users where user='$user' and pass='$pass'";
        //...

    ?>

最佳答案

这里的问题在$pass= hash("sha1",$pass, true);

你需要这样写 $pass= hash("sha1",$pass, false);

迁移到 PDO 是一个不错的选择。


让我们看看为什么会这样:

你的代码正在做的是返回一个原始的二进制散列,这意味着在某个时间点散列可能包含一个相等的字符 =, 对于您的示例,在这种情况下导致 SQL 注入(inject)的散列是 "ocpe" 因为散列 ("ocpe",sha1) 具有 '=' 字符, 但我怎样才能弄清楚呢?

您只需要运行一个简单的暴力破解并测试它是否在哈希原始位中包含一个'='

这是一个可以帮助你的简单代码

<?php
$v = 'a';
while(1)
{
        $hash = hash("sha1",$v, true);
        if( substr_count( $hash, "'='" ) == 1 ) {
            echo $v;
            break;
        }
        $v++;
}

?>

现在你有一个字符串,它给出了一个哈希值,它内部有一个相等的值 '='

查询变为:

$query = "select user, pass from users where user='$user' and pass='hash("ocpe",sha1)'";

然后

$query = "select user, pass from users where user='$user' and pass='first_Part_of_hash'='Second_part_of_hash'";

在这种情况下,我假设 ocpe 字符串具有这种格式的散列 first_Part_of_hash'='Second_part_of_hash

因为 pass='first_Part_of_hash' 将导致 00='Second_part_of_hash' 由 SQL 引擎进行类型转换,但在string 的情况,如果我们将其类型转换为 int,它将给出 0((int)'Second_part_of_hash' 中的结果>0)
所以最后 0=0

$query = "select user, pass from users where user='$user' and 0=0";

每次都会产生“true”,正如您所见,它可以应用于所有哈希函数,如 MD5 和 sha256 等。


值得检查的好资源:

How can I prevent SQL injection in PHP?

Could hashing prevent SQL injection?

关于php - SQL 注入(inject)易受攻击的代码,即使我们正在清理输入 mysql_real_escape_string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55522941/

相关文章:

mysql - 按列计算 SQL 出现次数

mysql - 在sql中对内容进行分组

php - 是否有任何好的基于 PHP 的 HTML 过滤器可用?

php - 使用什么检查来防止直接访问页面(使用 PHP)?

php - MySQL 连接表

sql - 如何使用带有文本 "|"的 sql 脚本创建文本文件

javascript - jsrsasign - 如何提取 x.509 证书的指纹?

php - Yii 同时使用 mongo DB 和 MySQL

javascript - 从 PHP 访问 POST 字符串

php - 通过 Mac 的撇号无法正确保存到数据库