首页  >  问答  >  正文

使用 mysqli_multi_query 对于成功的 SQL 注入至关重要

我正在尝试创建一个 SQL 注入示例,但 MySQL 每次都拒绝第二个查询,除非我将其更改为 mysqli_multi_query。

<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" name="dummyDorm">
        <label>Name: </label>
        <input type="text" name="name"><br>
        <input type="submit" value="Submit">
    </form>

    <?php 
        if($_SERVER["REQUEST_METHOD"] == "POST")
        {
            $name = $_POST['name'];
            $conn = mysqli_connect("localhost", "root", "", "testDB");
            if (mysqli_connect_errno()){
                echo "failed to connect" . mysqli_connect_error();
                die();
            }
            else
            {

                $sql = "SELECT * FROM users WHERE name = '{$name}'";
                var_dump($sql);
                if (mysqli_query($conn, $sql))
                {
                    echo "Success";
                } 
                else {
                    echo "Error: " . $sql . "<br>" . mysqli_error($conn);
                }

                mysqli_close($conn);
            }

        }
    ?>

该表单实际上并没有执行任何操作,我只是想演示使用 SQL 注入可以编辑数据。我想在输入“DROP TABLE testTable”的地方执行注入。我的 MySQL 看起来像这样:

DROP DATABASE IF EXISTS testDB;
CREATE DATABASE testDB;
USE testDB;

CREATE TABLE users
(
    userID INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
)engine=innodb;

CREATE TABLE testTable
(
    test VARCHAR(10)
)engine=innodb;

INSERT INTO users VALUES(null, "user01");

进入注入时:';删除表测试表 --

输出如下: 错误:SELECT * FROM users WHERE name = '';删除表测试表 --' 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在第 1 行“DROP TABLE testTable --”附近使用的正确语法

我继续浏览教程,他们使用 MySQLi_query 并且它工作正常,但我必须将其更改为 Mysqli_multi_query 才能完成注入。

谢谢

P粉925239921P粉925239921283 天前428

全部回复(1)我来回复

  • P粉795311321

    P粉7953113212023-12-16 00:48:03

    确实mysqli_query()不允许多重查询。为此,您需要 mysqli_multi_query(),并且如果您避免使用使用该函数,您可以免受依赖于运行多个查询的 SQL 注入攻击,例如 DROP TABLE 示例。

    但是,除了 DROP TABLE 之外,SQL 注入还可能导致其他类型的危害。

    我可以使用其他参数访问您的 PHP 页面的 URL,这些参数允许我控制您的 SQL 查询的逻辑:

    读取表中的所有行:

    ?name=x' OR 'x'='x

    读取另一个表:

    ?name=x' UNION ALL SELECT ... FROM othertable WHERE 'x'='x

    执行拒绝服务攻击,用万亿行临时表杀死您的数据库服务器:

    ?name IN (SELECT 1 FROM othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable CROSS JOIN othertable) AND 'x'='x

    SQL 注入不一定是恶意攻击。这可能是对合法字符串的无意使用,从而导致意外的 SQL 语法:

    ?name=O'Reilly

    SQL 注入的修复众所周知且简单:使用参数化查询。

    查看mysqli_prepare()手册或流行的完整示例Stack Overflow 问题,例如 如何防止 PHP 中的 SQL 注入?

    回复
    0
  • 取消回复