故意使脚本SQL可注入

时间:2017-11-12 20:37:14

标签: php sql sql-injection

我正在审核安全工具,我决定一个好的方法是创建我自己的"不安全的区域" (使用随机生成的假数据),因此我设置了一个易受sql注入的区域。但是,我实际上似乎无法注入它。我注意到,当我给它一个错误的查询时,"以下是找到的帐户"不打印,但错误消息也不打印。

有人可以告诉我,如果我做错了吗?

<?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 个答案:

答案 0 :(得分:1)

对于上面的脚本,

1' OR '1'='1应该是有效的SQLi,因为它将评估为:

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

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

为防止出现这种情况,我建议您使用stored procedures or parameterised queries,并使每个表中的第一个用户拥有尽可能少的权限。我还建议您查看 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
}

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

希望这会有所帮助:)