渗透测试-SQL注入-登录漏洞-登录次数限制

本文探讨了在SQL注入登录漏洞场景下,如何通过添加登录次数限制和使用验证码来增强安全性,包括数据库操作、PHP代码示例以及防范措施如IP多因素认证。


前言

SQL注入-登录漏洞-Burp爆破中我们提到了Burp爆破的问题,但是在实际的登录过程中,我们还需要考虑到登录次数的限制,否则会被暴力破解,从而导致系统被入侵,本文将对登录次数限制进行修复。

一、次数限制基本思路

(1)需要在数据库中记录某个用户的登录失败的次数,每登录失败一次,则加+1
(2)需要在数据库中记录某个用户的最后一次登录时间,用于判断是否接触限制
(3)每次登录时,只要用户名存在,都需要从数据库里面取两个值,从而进行判断

二、代码准备

1、 核心的SQL语句操作

-- 同时更新两个字段并更新时间为现在:
update userd set failcount=failcount+1,lastttime=now() where userid =?

-- 比较两个时间的差值,单位可以是分或秒:
select lasttime,now(), TIMESTAMPDIFF(minute,lasttime,now()) from user;

2、 在PHP中处理时间

// PHP设置默认时间为中国:
date_default_timezone_set("PRC");

//PHP生成年月日时分秒:
echo data("Y-m-d H:i:s");

//PHP比较两个时间的差值(单位为秒):
$time1 = "2023-08-12 16:46:04";
$time1 = "2023-08-12 16:46:09";
echo (strtotime($time2)) - (strtotime($time1))

三、代码实现

<?php

/**
 * 本代码解决用户登录失败的次数限制问题,更加完整解决登录模块的爆破和其他漏洞
 */

include "common.php";

//获得用户发送的请求
$username = $_POST['username'];
$password = $_POST['password'];
$vcode = $_POST['vcode'];

//根据图片验证码验证
if (strtoupper($_SESSION['vcode']) != strtoupper($vcode)) {
   die("vcode-error");
}else {
   //验证码成功后清空本次Session中的验证码
   unset($_SESSION['vcode']);
   //$_SESSION['vcode'] = '';  //可以用空字符验证码绕过
}

// if (strtoupper($_COOKIE['vcode']) != strtoupper($vcode)) {
//    die("vcode-error");
// }

//每提交一次都清空,会增加服务器负担
unset($_SESSION['vcode']);

 $conn = create_connection_oop();

 //md5加密
 $md5password = md5($password);

 //拼接SQL语句并执行它
 //先查用户名对比密码
 $sql = "select userid,username,password,role,failcount,TIMESTAMPDIFF(minute,lasttime,now()) from users where username=?";

 //绑定查询参数
 $stmt = $conn->prepare($sql);
 $stmt->bind_param("s",$username);

 //绑定结果参数
 $stmt->bind_result($userid,$username2,$password2,$role,$failcount,$timediff);

 $stmt->execute();
 $stmt->store_result();

//认证和授权失败
 if($stmt->num_rows == 1){       //表明用户存在
    $stmt->fetch();

    //判断密码是否正确之前,先判断登录次数是否受限
    if($failcount >=5 && $timediff <=60){
      die('user-locked');
    }


    if ($md5password == $password2) {

      if($failcount > 0){
         $sql = "update users set failcount=0 where userid=?";
         $stmt = $conn->prepare($sql);
         $stmt->bind_param("i",$userid);
         $stmt->execute();
      }

      echo "login-pass";

    //登录成功后,记录SESSION变量
    $_SESSION['username'] = $username;
    $_SESSION['islogin'] = 'true';
    $_SESSION['role'] = $role;

    echo "<script>location.href='list.php'</script>";
    }else{

      $sql = "update users set failcount=failcount+1 ,lasttime=now() where userid=?";
      $stmt = $conn->prepare($sql);
      $stmt->bind_param("i",$userid);
      $stmt->execute();

      echo "login-fail";
      echo "<script>location.href='login.html'</script>";
    }   
 }else{
    echo "user-invalid";
    echo "<script>location.href='login.html'</script>";
 }


 //关闭数据库
$conn->close();
?>

四、登录模块的防护措施:

验证码:不建议使用图片验证码
登录次数的限制,并记录IP
多因素认证:账密+短信
记录用户常用的IP地址区域,如果不在常用区域登录,预警
除了使用Session外,还可以使用Token

完整代码见https://github.com/chengstery/security/tree/main/linux_login

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值