1

我创建了一个测试站点,以便了解 SQLi 并加以防范。我可能会误解它应该如何表现,但目前我没有得到我期望的结果。

这页纸:

<!DOCTYPE html>
<html><body>

<h1>SQL Injection Test Site</h1>
<h2>Login Form</h2>

<form action="" method="post">
Username: <input type="text" name="username">
Password: <input type="text" name="password">
<input type="submit"></form>

<?php
$db = mysql_connect(***, ***, ***); 
if(!$db){ 
    die('Could not connect: ' . mysql_error()); 
}else{
    mysql_select_db(***);  
}

if(isset($_POST["username"]) && isset($_POST["password"])){
    $username = $_POST["username"];
    $password = $_POST["password"];
    $result = mysql_query("SELECT * FROM customer_data 
                            WHERE username = '$username' 
                               AND password = '$password'");
    $result = mysql_fetch_assoc($result);
    //we would now process the login if details matched
    echo "Logged in: " . $result['username'];
    var_dump($result);
}
?>

</body></html>

数据库中的表:

http://imgur.com/FvIbCuz(似乎无法发布图片)

输入:

username: admin
password: ' OR '1'='1

我的期望是它会找到管理员用户,然后接受来自密码字段的输入,因为 '1'='1 应该评估为真。它实际上返回表中第一个条目的结果,用户名 JBloggs。这是我不明白的一点。

谁能指出导致这种行为的代码或逻辑错误?

4

2 回答 2

2

您当前的注入会生成以下代码:

SELECT
    * 
FROM
    customer_data
WHERE 
    username = 'admin'
AND 
    password = '' OR '1'='1'

它为您提供表中的所有行。而你只取第一个。

要破解该站点,请尝试以下操作:

<?php
$username = 'admin';
$password = "' OR username='admin";

$sql = "SELECT * FROM customer_data
WHERE username = '$username'
AND password = '$password'";

print $sql;

印刷:

SELECT * FROM customer_data
WHERE username = 'admin'
AND password = '' OR username='admin'

这将选择必要的行。

于 2013-07-21T12:26:29.253 回答
1

我建议您创建一个 $sql 变量来查看请求。像那样 :

$sql = "SELECT * FROM customer_data 
                        WHERE username = '$username' 
                           AND password = '$password'";

然后显示一个 var_dump($sql) 这样你就会看到最终的请求。

于 2013-07-21T12:27:26.880 回答