有没有办法用mysqli演示SQL注入? [英] Is there a way to demonstrate SQL injection with mysqli?

查看:48
本文介绍了有没有办法用mysqli演示SQL注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想简单快速地演示一下SQL注入的工作方式.我已经解决了一些问题.我有一个包含随机用户名,密码和电子邮件的表,并且能够注入" SQL代码以查看与此注入相关的所有用户:

I want to make a quick and easy demonstration about how SQL injection work. And I've solved some of my problems. I have a table with random usernames, passwords and emails in, and I'm able to "inject" SQL code to view all of the users in a search with this injection:

' OR '1'='1

这是我的PHP代码寻找成员"的样子:

This is how my PHP code looks for searching for "members":

if (isset($_POST['search'])) {
    $searchterm = $_POST['searchterm'];
    echo $searchterm . '<br>';

    /* SQL query for searching in database */
    $sql = "SELECT username, email FROM Members where username = '$searchterm'";
    if ($stmt = $conn->prepare($sql)) {
        /* Execute statement */
        $stmt->execute();

        /* Bind result variables */
        $stmt->bind_result($name, $email);

        /* Fetch values */
        while ($stmt->fetch()) {
            echo "Username: " . $name . " E-mail: " . $email . "<br>";
        }
    } 
    else {
        die($conn->error);
    }
}

现在,我想演示一些更致命的问题,例如有人将您的整个桌子都截断了.因此,我在搜索栏中尝试了以下代码:

Now I want to demonstrate some more fatal problems, like someone truncating your whole table. So I tried this code in the search bar:

'; TRUNCATE TABLE Members; -- 

但是我收到此错误消息:

But I get this error message:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'TRUNCATE TABLE Members; -- '' at line 1

似乎我得到了一个额外的',但是我不知道如何摆脱它,尽管--会对此予以注释.首先,我认为问题在于--后面没有空格,但是添加空格没有任何作用.

It seems like I get an extra ', but I don't know how to get rid of it, though the -- would comment that out. First I thought that the problem was that I had no whitespace behind the -- but adding a whitespace didn't make any difference.

我曾尝试切换到PDO,因为我认为mysqli不接受多个查询存在问题,但是后来我在某处读到PDO也不支持,但我不知道.

I have tried switching to PDO, because I thought there was a problem with mysqli not accepting multiple queries, but then I somewhere read that PDO doesn't support that either, but I don't know.

有什么办法可以使它工作?

Is there a way I can make it work?

后来我发现PDO默认情况下支持多重查询,但是当我尝试时它不起作用.也许我把参数绑定错了.但是我什至无法做一个简单的选择查询来工作.

I later found that PDO supports multi-querying by default, but when I tried it it didn't work. Maybe I bound the parameters wrong. But I couldn't even make a simple select query to work.

推荐答案

mysqli_query()默认不支持多查询.它具有一个单独的功能: mysqli_multi_query().

mysqli_query() does not support multi-query by default. It has a separate function for that: mysqli_multi_query().

SQL注入不仅涉及运行多个语句,还有著名的 XKCD卡通.

SQL injection is not only about running multiple statements, the famous XKCD cartoon notwithstanding.

您的代码有一个严重的SQL注入漏洞.即使您将$ _POST请求数据中的内容直接内插到SQL字符串中,您是否认为使用prepare()使查询安全?

Your code has a bad SQL injection vulnerability. Do you think that using prepare() somehow makes a query safe, even though you interpolate content from your $_POST request data directly into the SQL string?

您的代码是这样的:

$searchterm = $_POST['searchterm'];

$sql = "SELECT username, email FROM Members where username = '$searchterm'";
if ($stmt = $conn->prepare($sql)) {
    /* execute statement */
    $stmt->execute();
    ...

不安全的输入很容易以这种方式使SQL注入恶作剧.它甚至可能是无辜的,但仍然会导致问题.例如,假设搜索为:O'Reilly.直接将该值复制到您的SQL中将导致如下查询:

It's easy for unsafe input to make SQL injection mischief this way. It might even be innocent, but still result in problems. Suppose for example the search is: O'Reilly. Copying that value directly into your SQL would result in a query like this:

SELECT username, email FROM Members where username = 'O'Reilly'

看到不匹配的'报价了吗?这不会带来任何恶意,但只会导致查询失败,因为不平衡的引号会导致语法错误.

See the mismatched ' quotes? This won't do anything malicious, but it'll just cause the query to fail, because unbalanced quotes create a syntax error.

使用prepare()不能修复意外的语法错误,也不能防止复制修改查询语法的恶意内容.

Using prepare() doesn't fix accidental syntax errors, nor does it protect against copying malicious content that modifies the query syntax.

为防止意外和恶意SQL注入,您应使用如下绑定参数:

To protect against both accidental and malicious SQL injection, you should use bound parameters like this:

$searchterm = $_POST['searchterm'];

$sql = "SELECT username, email FROM Members where username = ?";
if ($stmt = $conn->prepare($sql)) {
    $stmt->bind_param('s', $searchterm);
    /* execute statement */
    $stmt->execute();
    ...

绑定参数未复制到SQL查询中.它们将分别发送到数据库服务器,并且在解析后 之后才与查询组合,因此不会引起语法问题.

Bound parameters are not copied into the SQL query. They are sent to the database server separately, and never combined with the query until after it has been parsed, and therefore it can't cause problems with the syntax.

关于您关于mysqli::query()的问题,如果您的SQL查询不需要绑定参数,则可以使用它.

As for your question about mysqli::query(), you may use that if your SQL query needs no bound parameters.

发表您的评论

...容易被注射,所以我可以向学生展示恶意攻击可能会造成多大危害.

... vulnerable to injection, so I can show the students how much harm a malicious attack may [do].

这是一个例子:

几年前,我是一名SQL培训师,在一家公司的一次培训中,我谈论的是SQL注入.一位与会者说:好吧,请向我展示SQL注入攻击."他递给我他的笔记本电脑.浏览器已打开他网站的登录屏幕(这只是他的测试网站,而不是实际的生产网站).登录表单很简单,只包含用户名和密码字段.

A few years ago I was an SQL trainer, and during one of my trainings at a company I was talking about SQL injection. One of the attendees said, "ok, show me an SQL injection attack." He handed me his laptop. The browser was open to a login screen for his site (it was just his testing site, not the real production site). The login form was simple with just fields for username and password.

我从未见过他处理登录表单的代码,但是我认为表单是由某些代码处理的,例如大多数不安全的网站是:

I had never seen his code that handles the login form, but I assumed the form was handled by some code like most insecure websites are:

$user = $_POST['user'];
$password = $_POST['password'];

$sql = "SELECT * FROM accounts WHERE user = '$user' AND password = '$password'";
// execute this query.
// if it returns more than zero rows, then the user and password
// entered into the form match an account's credentials, and the
// client should be logged in.

(这是我对他的代码的有根据的猜测,但我仍然没有看到代码.)

(This was my educated guess at his code, I had still not seen the code.)

我花了五秒钟的时间来思考逻辑,然后我在登录表单中输入了一个布尔表达式来表示用户名,并为密码输入了随机垃圾字符.

It took me 5 seconds to think about the logic, and I typed a boolean expression into the login form for the username, and for the password, I typed random garbage characters.

然后我登录到他的帐户-不知道甚至试图猜测他的密码.

I was then logged into his account — without knowing or even attempting to guess his password.

我不会提供我使用的确切布尔表达式,但是如果您了解任何离散数学类中涵盖的基本布尔运算符优先级,那么您应该可以弄清楚.

I won't give the exact boolean expression I used, but if you understand basic boolean operator precedence covered in any Discrete Math class, you should be able to figure it out.

这篇关于有没有办法用mysqli演示SQL注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆