如何使我的登录页面易受 SQL 注入攻击?
Posted
技术标签:
【中文标题】如何使我的登录页面易受 SQL 注入攻击?【英文标题】:How to make my login page vulnerable to SQL Injection? 【发布时间】:2019-03-21 14:36:04 【问题描述】:你好,我正在做一个项目,我需要让这个 php 登录页面易受攻击的 sqli .. 我尽我所能删除逃避特殊字符的函数 但是当我尝试注入时
' or '1' = '1'
什么都没发生... 登录.php:
include ("config.php");
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT id FROM users WHERE username = '$username' and password = '$password'";
$result = mysqli_query($db,$sql);
$count = mysqli_num_rows($result);
// If result matched $username and $password, table row must be 1 row
if($count == 1)
session_register("username");
$_SESSION['login_user'] = $username;
header("location: welcome.php"); //set a http header
else
header("location: failed.php");
【问题讨论】:
第一个问题:你为什么愿意这样做? @AaronJonk 可以用来学习 SQL 注入攻击的工作原理吗?nothing happen
听起来像是一个致命错误。页面的状态码是什么?你检查过你的错误日志吗?
@AaronJonk 准备一个易受攻击的实验室
【参考方案1】:
但是当我尝试注入
' or '1' = '1'
试试这个
$_POST['username'] = "' OR 1 LIMIT 1 --";
您甚至可以使用/添加OFFSET
来选择您想要的用户(按行)。
SELECT id FROM users WHERE username = '' OR 1 LIMIT 1 --' and password = '$password'
那么(因为 LIMIT 1)
if($count == 1)
是真的。 --
是 SQL 中内联注释的开始,因此查询的其余部分将被忽略。这有明显的好处,因为我们可以缩短或简化查询。条件越少越好,我们希望访问查询的末尾以获取 Limit 和 Offset。
这也说明了搜索密码的愚蠢。如果在代码中签入,这不会让您登录。但因为它不是,它会,定时攻击等等。
【讨论】:
这应该是公认的答案,比我们的答案更完整 @Cid - 谢谢。这可能是这种攻击最常见的形式。 当您使用LIMIT
子句时,您还应该添加ORDER BY id
子句以获得确定性结果,假设 id 列存在并且是主键,它在 10 个案例中的 9 个中执行,否则您可以尝试已弃用的ORDER BY 1
SQL 标准语法,人们倾向于将主键列放在表中。
我会遍历它们,找到任何有趣的帐户,然后更改密码和电子邮件。等等... :-)
我知道@ArtisticPhoenix 我的意思是LIMIT
没有ORDER BY
是不确定的,所以当MySQL 由于(可能的)随机性而给出相同的记录时,您可能会丢失一些有趣的帐户。SQL 表和结果集根据 SQL 定义 orderless 不使用 ORDER BY
子句【参考方案2】:
如果您在密码字段中注入此类 SQL,您的查询将失败。
与' or '1' = '1'
您的查询将变为:
SELECT id FROM users WHERE username = '$username' and password = '' or '1' = '1''
-- Syntax error a single quote is in excess --------------------------------^
您可以删除注入的最后一个单引号:' or '1' = '1
【讨论】:
但这仍然行不通,因为计数为一,对吗? @PraveenKumarPurushothaman 确实如此,但LIMIT 1
和更改 $count == 1
已经在其他答案中提及,我不想窃取其他解决方案
但是LIMIT 1
不是在问题或OP中吗?
好吧,他可以更改代码,也可以更改注入(他必须更改注入,因为它会提供语法错误)
@Cid 它在没有更改代码的情况下工作,也没有注入我只是忘记删除你提到的引号【参考方案3】:
这可能不会起作用,因为如果您有许多用户记录,$count
将比 1
多,但您正在检查只有一条记录出来:
if ($count == 1)
可以尝试将条件更改为:
if ($count != 0)
那么上面的条件只会过滤掉不存在的用户,不会只检查返回一个用户。
【讨论】:
以上是关于如何使我的登录页面易受 SQL 注入攻击?的主要内容,如果未能解决你的问题,请参考以下文章