提问人:Addeuz 提问时间:1/21/2019 最后编辑:Peter MortensenAddeuz 更新时间:7/20/2019 访问量:622
有没有办法用mysqli演示SQL注入?
Is there a way to demonstrate SQL injection with mysqli?
问:
我想快速轻松地演示一下 SQL 注入的工作原理。我已经解决了我的一些问题。我有一个包含随机用户名、密码和电子邮件的表格,我能够“注入”SQL 代码以通过此注入查看搜索中的所有用户:
' OR '1'='1
这是我的PHP代码搜索“成员”的方式:
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);
}
}
现在我想演示一些更致命的问题,比如有人截断了你的整张桌子。所以我在搜索栏中尝试了这段代码:
'; TRUNCATE TABLE Members; --
但是我收到以下错误消息:
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
似乎我得到了一个额外的,但我不知道如何摆脱它,尽管会注释掉它。首先,我认为问题在于我后面没有空格,但添加空格没有任何区别。'
--
--
我尝试切换到 PDO,因为我认为 mysqli 不接受多个查询存在问题,但后来我在某处读到 PDO 也不支持它,但我不知道。
有没有办法让它工作?
后来我发现PDO默认支持多查询,但是当我尝试它时,它不起作用。也许我绑定了错误的参数。但我什至无法进行简单的选择查询来工作。
答:
mysqli_query() 默认不支持多查询。它有一个单独的函数:mysqli_multi_query()。
SQL注入不仅仅是运行多个语句,尽管有著名的XKCD卡通。
您的代码存在不良的 SQL 注入漏洞。您是否认为以某种方式使查询安全,即使您将 $_POST 请求数据中的内容直接插入到 SQL 字符串中?prepare()
你的代码是这样的:
$searchterm = $_POST['searchterm'];
$sql = "SELECT username, email FROM Members where username = '$searchterm'";
if ($stmt = $conn->prepare($sql)) {
/* execute statement */
$stmt->execute();
...
不安全的输入很容易以这种方式使 SQL 注入恶作剧。它甚至可能是无辜的,但仍然会导致问题。例如,假设搜索是:。将该值直接复制到 SQL 中将导致如下查询:O'Reilly
SELECT username, email FROM Members where username = 'O'Reilly'
看到不匹配的引号了吗?这不会做任何恶意的事情,但只会导致查询失败,因为不平衡的引号会产生语法错误。'
使用并不能修复意外的语法错误,也不能防止复制修改查询语法的恶意内容。prepare()
为了防止意外和恶意 SQL 注入,应使用如下绑定参数:
$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 查询中。它们被单独发送到数据库服务器,并且在解析查询之前永远不会与查询组合,因此它不会导致语法问题。
至于你关于的问题,如果你的SQL查询不需要绑定参数,你可以使用它。mysqli::query()
回复您的评论:
...容易受到注入,所以我可以向学生展示恶意攻击可能造成多大的伤害。
下面是一个示例:
几年前,我是一名 SQL 培训师,在一家公司的一次培训中,我谈到了 SQL 注入。其中一位与会者说,“好吧,给我看一个SQL注入攻击。他把他的笔记本电脑递给我。浏览器打开了他的站点的登录屏幕(这只是他的测试站点,而不是真正的生产站点)。登录表单很简单,只有用户名和密码字段。
我从未见过他处理登录表单的代码,但我认为表单是由一些代码处理的,就像大多数不安全的网站一样:
$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.
(这是我对他的代码的有根据的猜测,我还没有看到代码。
我花了 5 秒钟来思考逻辑,我在用户名的登录表单中输入了一个布尔表达式,对于密码,我输入了随机的垃圾字符。
然后我登录了他的帐户 - 不知道甚至试图猜测他的密码。
我不会给出我使用的确切布尔表达式,但如果你了解任何离散数学类中涵盖的基本布尔运算符优先级,你应该能够弄清楚。
评论
你试过这样的东西吗?
'(here put something);
这样,您将使用 ' 关闭查询并向其中添加其他内容,当您添加 ;其他一切都将被丢弃
上一个:如何使用SQL注入提取登录信息?
评论
$searchterm = "' union select password, username from admins--";
admins