MySQL php查询缺陷

3

我需要做一个关于SQL注入的演示,最好的方法是自己编写PHP查询并展示给同学们。问题在于我的数据库和PHP代码都运行良好,但是在我制作的编辑表单中无法找到UPDATE查询的漏洞。

如果有人能够查看一下并告诉我如何插入例如'DROP TABLE'之类的命令,那将非常有帮助!

<?php
session_start();

require_once 'config.php';
error_reporting(E_ALL);
ini_set('display_errors', 1);

$userid = $_SESSION["userid"];
$fname = $_SESSION["fname"];
$lname = $_SESSION["lname"];
$gender = $_SESSION["gender"];
$email = $_SESSION["email"];

if($_SERVER["REQUEST_METHOD"] == "POST") {

    $userid = trim($_POST["userid"]);
    $fname = trim($_POST["fname"]);
    $lname = trim($_POST["lname"]);
    $gender = trim($_POST["gender"]);
    $email = trim($_POST["email"]);

    $query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender = '$gender', email = '$email' WHERE userid = '$userid' ";

    if (mysqli_query($link, $query)) {


        echo 'Update complete!';

    }
    echo mysqli_error($link);
    // else { 

    //     echo '<p>' . 'Woah something went really wrong dude' . '</p>' ;
    //     echo mysqli_error($link);
    // }


}

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Edit</title>
    <link rel="stylesheet" href="bootstrap.css">
    <style type="text/css">
        body{ font: 14px sans-serif; }
        .wrapper{ width: 350px; padding: 20px; }
    </style>
</head>
<body>
    <div class="container">
        <form class= "form-inline" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
            <label>First Name</label>
            <input type="text" name="fname" class="form-control" value="<?php echo $_SESSION["fname"]; ?>">
            <label>Last Name</label>
            <input type="text" name="lname" class="form-control" value="<?php echo $_SESSION["lname"]; ?>">
            <label>Gender</label>
            <input type="text" name="gender" class="form-control" value="<?php echo $_SESSION["gender"]; ?>">
            <label>Email</label>
            <input type="text" name="email" class="form-control" value="<?php echo $_SESSION["email"]; ?>">
    </div> 
    <div class = "wrapper">
            <label>UserID</label>
            <input type="text" name="userid" class="form-control" value="<?php echo $_SESSION["userid"]; ?>">
            <button type="submit">Submit</button>

    </form>
    <form action="action.php"><button type="submit">Back</button></form>
    </div>    
</body>
</html>

我尝试通过输入$userid 1234' ; DROP TABLE table_test -- 来进行查询,但似乎没有成功。目前正在更深入地研究如何正确地实现它,但我相信我的新手代码对于这个网站上的大多数人来说很容易被破解。 - John
我尝试过通过输入 "$userid 1234'; DROP TABLE table_test --" 的方式搭便车查询,但貌似行不通。mysql_query 不支持多个 SQL 语句。 - Raymond Nijland
问题在于我的数据库和php代码都能够完美运行,但我似乎无法在我创建的编辑表单中找到UPDATE查询的漏洞。唯一可以利用的方法是使用基于时间的SQL注入向量..例如:UPDATE user_details SET fname = (SELECT SLEEP(5)) -- - Raymond Nijland
2个回答

3
在大多数情况下,mysqli会防止多个查询,并且MySQL本身具有某些内置的安全措施以防止意外删除表和数据库。因此,您的DROP TABLE将不起作用。
但是,您可以使用MySQL注入漏洞演示成功的登录尝试。
创建一个登录表单并将数据传递到验证页面。在那里编写您的查询,如下所示:
query =  "SELECT * FROM `user`
     WHERE `username` = '." username ".' AND `password` = '." password ".'";

现在,在登录表单中输入用户名 ' OR '1'='1,密码也输入 ' OR '1'='1。因此最终完整的查询语句看起来像这样:
SELECT * FROM `user` WHERE `username`='' OR '1'='1' AND `password`='' OR '1'='1';

这将返回user表中的所有用户记录,应用程序将使用第一条记录进行登录。


谢谢你的回答!你看透了我,我已经制作了一个可工作的注册和登录示例,展示了你刚才输入的内容,但我想在编辑表单中展示一个DROP TABLE示例作为最后一个示例,并通过在edit.php表单中注入查询来展示我的DB更改(表被删除),以震惊班级。我将只需将函数调用更改为mySQL而不是mySQLi,因为它非常安全。 - John
是的,也可以尝试这个。但正如我所说,MySQL本身具有一些安全性。您可能无法保证DROP TABLE的结果。但是此登录尝试是有保证的。 - Roshana Pitigala

0

不确定我完全理解你的意思,但我会尝试告诉你为什么这似乎是一个坏主意...

如果我发布到用户ID

$userid="';DROP TABLE XY;SELECT * FROM USER_DETAILS WHERE fname = '"

你的代码会执行...

$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender 
= '$gender', email = '$email' WHERE userid = '$userid' ";

这将导致查询:

$query = "UPDATE user_details SET fname = '$fname', lname = '$lname', gender   
= '$gender', email = '$email' WHERE userid = '';DROP TABLE XY;SELECT * FROM 
USER_DETAILS WHERE fname = '' ";

查询将会是

UPDATE user_details SET fname = '$fname', lname = '$lname', gender   
= '$gender', email = '$email' WHERE userid = ''

DROP TABLE XY

SELECT * FROM USER_DETAILS WHERE fname = ''

它们每一个都是有效的...现在创建一个名为XY的表格,并使用此发布的注入运行您示例中的原始查询...

我错过了什么吗?

编辑:正如@RaymondNijland指出的那样,示例中使用的mysql函数似乎阻止了这种攻击。我仍然认为这是一种危险的代码风格,只有驱动程序才能创建安全性。也许会有未来的更新允许批量sql,我会更放心,知道我的代码不会打开这样的大门...


1
mysql_query不支持多个SQL语句,因此它将无法工作。 - Raymond Nijland
@RaymondNijland 我明白了,那么我应该使用不同的函数来进行查询吗?再次强调,这个系统需要有SQL注入漏洞,以作为向班级展示的例子。 - John
@john,如果这有帮助到你,请标记答案为“正确”。 - P.S.
@John,你可以利用时间基 SQL 注入向量来利用你的 UPDATE 查询.. UPDATE user_details SET fname = (SELECT SLEEP(5)) -- 举个简单的例子,多个 SQL 语句是行不通的。 - Raymond Nijland
@RaymondNijland 好的,那么我该怎么做才能让它容易受到DROP TABLE注入攻击呢?使用mySQL_query而不是mysqli吗? - John
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接