渗透测试-SQL注入-登录漏洞-登录次数限制
前言
在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

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

2万+

被折叠的 条评论
为什么被折叠?



