如何使我的登录页面易受 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 注入攻击?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET如何防止SQL注入

如何防止web攻击

手抄:测试网站登录页面是否存在SQL注入攻击

SQL注入易受攻击?

[安全测试入门]详解SQL注入式攻击

Web安全基础之SQL注入式攻击