故意使脚本 SQL 可注入

Purposely Make Script SQL Injectible

我正在审核安全工具,我决定创建自己的 "insecure area"(使用随机生成的虚假数据)是一个好方法,所以我设置了一个容易受到攻击的区域sql 注射。但是,我实际上似乎无法注入它。我确实注意到,当我给它一个错误的查询时,"Here are the accounts found" 不会打印,但错误消息也不会打印。

有人可以告诉我我做错了什么吗?

<?php

$resultHTML;
if (isset($_POST['email']) || isset($_GET['email'])) {

    $conn = mysqli_connect($servername,$username,$password);

    if ($conn) {

        //this part is insecure (intentionally for testing)
        if (isset($_GET['email'])) {
            $query = "SELECT * from badSQL.Two WHERE email = '$_GET[email]'";
        } else {
            $query = "SELECT * from badSQL.Two WHERE email = '$_POST[email]'";
        }

        //echo $query;
        $result = $conn->query($query);

        if ($result) {
            $resultHTML = "Here are the accounts found: ";

            $hasAccount = false;
            while ($row = mysqli_fetch_assoc($result)) {
                $hasAccount = true;
                $resultHTML .= "<br>".print_r($row);
            }

            if ($hasAccount === false) {
                $resultHTML = "No accounts found.";
            }
        }

    } else {
        $resultHTML = "DB Connection could not be established: ".$conn->connect_error;
    }

}

?>

<html>
<head>

    <title>Two BadSQL Test</title>

</head>
<body>

    <h1>Two Website!</h1>
    <br>
    <h3>Forgot Password</h3>
    <p>Enter your email below, and click submit:</p>
    <form id="forgotForm" method="get">
        <input type="text" name="email" />
        <input type="submit" value="submit" />
    </form>

    <br>
    <div id="results"><?php echo $resultHTML; ?></div>
</body>
</html>

1' OR '1'='1 对于您的上述脚本应该是有效的 SQLi,因为它的计算结果为:

"SELECT * from badSQL.Two WHERE email = '1' OR '1'='1'"

电子邮件地址总是错误并不重要,因为它使用了 OR 子句。考虑到 1 总是 等于 1,整个表达式将始终成立。因此,上述脚本将'skip over'所有的电子邮件检查,然后尝试找到第一个满足'1' = '1'条件的用户。这与 table 中的第一个用户相关(通常是管理员,因为 ID 为 1,导致进一步利用)。

为了防止这种情况发生,我建议使用 stored procedures or parameterised queries, and making the first user in each table have the fewest privileges possible. I'd also recommend checking out the OWASP SQLi Prevention Cheat Sheet

等效的非易受攻击的 PHP 参数化查询类似于:

$stmt = $dbConnection->prepare('SELECT * FROM badSQL.TwoWHERE name = ?');
$stmt->bind_param('s', $name);

$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    // Do something with $row
}

此外,我建议不要故意让您自己的网站更容易受到攻击,因为为封装的虚假数据创建漏洞可能会成为合法攻击的载体。

希望对您有所帮助:)