IP block after 3 unsuccessful attempts
Posted: Wed Jul 23, 2008 2:39 pm
Hii,,
i've a small doubt regarding user login attempts restriction, for that i've included attempts.log.class.php in my login check php file.
my aim is to block bruteforcers, for that i created a table that stores User's IP , Attempts and Time stamp.
after running the script, i successfully blocked people who tries to log into the system with more than 3 attempts,my script will not record attempts if the user is genuine. i achieved blocking users who tries to enter with a wrong username and password.
after 3 unsuccessful attempts it should not allow even a genuine user who wanna login. i mean it should block that IP for 1 hr. i did that, but i'm unable to block genuine users after 3 unsuccessful attempts, every timeeven after 3 unsuccessful attempts from the same IP if a genuine user enters his username n password correctly, hez gaining access.
hope u understand my problem, i'm here with pasting the required files, i request you to go thru this and do the needful..
attempt.log.class.php ::
<?php
/*
+----------------------------------------------+
| |
| PHP MySQL Login attempt thing |
| |
+----------------------------------------------+
| Filename : attempt.log.class.php |
| Created : 6-Jun-06 2:41 GMT |
| Created By : Sam Clarke |
| Email : admin@free-php.org.uk |
| Version : 1.0 |
| |
+----------------------------------------------+
+----------------------+
| We like donations =) |
+----------------------+
+---------------------------------------+
| |
| MySQL sql to make tabke |
| |
+---------------------------------------+
| |
| CREATE TABLE `attempt_protect` ( |
| `IP` char(32) NOT NULL default '', |
| `ATTEMPT` int NOT NULL, |
| `TIME` char(20) NOT NULL default '', |
| PRIMARY KEY (`IP`) |
| ) TYPE=MyISAM; |
| |
+---------------------------------------+
LICENSE
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL)
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
To read the license please visit http://www.gnu.org/copyleft/gpl.html
*/
class attempt_log
{
public $attempts = 3; // Number of attemps before blocked
public $keep_secs = 3600; // Number of secounds to keep the user registered 86 400 = 1 day to find out how many in another amount of time google: "how many seconds in {a day/a week/ect}"
// MySQL config
public $host = 'localhost'; // MySQl host
public $password; // MySQL password
public $username; // MySQL username
public $db; // MySQL username
public $link; // MySQl link
public $table = 'attempt_protect'; // table name
// function to connect to MySQL
function db_connect()
{
$this->link = mysql_connect($this->host, $this->username, $this->password); // connect to MySQL
if (!$this->link) // test connection
return false;
if (mysql_select_db($this->db)) // select db and check it worked
return true;
return false;
}
// add user ip address to database
function register_user($ip)
{
// insert ip and currnt time into database
$result = mysql_query('INSERT INTO `' . $this->table .
'` (`IP` , `ATTEMPT` , `TIME`) VALUES (\' ' . mysql_real_escape_string($ip, $this->
link) . '\', \'0\', \'' . time() . '\')', $this->link);
if (!$result)
return false;
return true;
}
// check to see if the user is flooding
function check_request($ip)
{
if (!$this->db_connect())
return false; // if we cannot connect to db then return the user isnt flooding as we don't know
if ($this->user_in_db($ip)) // find out if the user is in the db
{
$return = $this->user_flooding($ip); // if they are check if there flooding
$this->remove_old_users(); // remove the old users
$this->close_db(); // close db connection
return $return; // return if there flooding or not
} else {
$this->register_user($ip); // if there not in the db add them
$this->remove_old_users(); // remove the old users
$this->close_db(); // close db connection
return false; // sonce there not in the db there not flooding so return false
}
}
function user_in_db($ip)
{
// query db to see if there in
$result = mysql_query('SELECT `TIME` FROM `' . $this->table . '` WHERE `IP` = \' ' .
mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1', $this->link);
if (mysql_num_rows($result) > 0) // if more than 0 records are returned there in
return true;
return false; // other wise return false
}
function user_flooding($ip)
{
// query db to see if there flooding
$result = mysql_query('SELECT `TIME` FROM `' . $this->table . '` WHERE `IP` = \' ' .
mysql_real_escape_string($ip, $this->link) . '\' AND `ATTEMPT` >= ' . $this->
attempts . ' LIMIT 1', $this->link);
if (mysql_num_rows($result) > 0)
// if more than 0 records are returned there flooding
return true;
return false; // other wise return false
}
function wrong($ip)
{
$this->db_connect(); // connect to mysql
// get current attempt
$current_attempt = mysql_query('SELECT `ATTEMPT` FROM `' . $this->table .
'` WHERE `IP` = \' ' . mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1',
$this->link);
$current = mysql_fetch_assoc($current_attempt);
$next = $current['ATTEMPT'] + 1;
// query db to see if there flooding
$result = mysql_query('UPDATE `' . $this->table . '` SET `ATTEMPT` = \'' . $next .
'\' WHERE `IP` = \' ' . mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1',
$this->link);
}
function remove_old_users()
{
// Query db to remove all the old users
mysql_query('DELETE FROM `' . $this->table . '` WHERE `TIME` <= \'' . (time() -
$this->keep_secs) . '\'', $this->link);
}
function close_db()
{
mysql_close($this->link);
}
}
$protect = new attempt_log(); //call the class
$protect->password = ''; // set the password for MySQL
$protect->username = 'root'; // set the username for MySQL
$protect->db = 'trrcollege'; // set the MySQL db name
/*if ($protect->check_request(getenv('REMOTE_ADDR'))) { // check the user
//require_once('admin.php');
//session_unset();
//session_destroy();
//header("Location: loginblock.html");
//die('Request block, You have failed to login too many times you are now blocked for: 1 day'); //die there flooding
}*/
// show the login form or proccess the login post data here
// if their attempt was bad call the function wrong to add a bad attempt to the log
$protect->wrong(getenv('REMOTE_ADDR'));
?>
admin.php ::
<?php
//Connect to mysql server
$link=mysql_connect("localhost","root","");
if(!$link) {
die('Failed to connect to server: ' . mysql_error());
}
//Select database
$db=mysql_select_db("admintbl");
if(!$db) {
die("Unable to select database");
}
//Check whether the query was successful or not
//require_once('attempt.log.class.php');
//if ($protect->check_request(getenv('REMOTE_ADDR'))) {
//Create query
$username = $_POST["username"];
$password = $_POST["password"];
$query="SELECT * FROM adminlogin WHERE username='".$username."' AND password='".$password."'";
$result=mysql_query($query);
$rows2=mysql_fetch_array($result);
if($rows2["password"] == $password && $rows2["username"] == $username )
{
if(mysql_num_rows($result)>0)
{
//Login Successful
session_start();
$start=time();
$_SESSION['time_start']=$start;
session_register('username');
session_register('time_start');
$_SESSION['username']=$username;
$_SESSION['password']=$password;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
session_regenerate_id();
session_write_close();
include "session.php";
include("class_session.inc.php");
header("Location: redirect.php");
exit();
}
else {
//Login failed
session_unset();
session_destroy();
header("location: loginfail.htm");
exit();
}
}
/*else{
session_unset();
session_destroy();
header("Location: loginblock.html");
die('Request block, You have failed to login too many times you are now blocked for: 1 day'); //die there flooding
}
}*/
else{
session_unset();
session_destroy();
header("location: loginfail.htm");
}
?>
the problem is it is not executing the correct login part... if{}
plz do help me...
many thanks
i've a small doubt regarding user login attempts restriction, for that i've included attempts.log.class.php in my login check php file.
my aim is to block bruteforcers, for that i created a table that stores User's IP , Attempts and Time stamp.
after running the script, i successfully blocked people who tries to log into the system with more than 3 attempts,my script will not record attempts if the user is genuine. i achieved blocking users who tries to enter with a wrong username and password.
after 3 unsuccessful attempts it should not allow even a genuine user who wanna login. i mean it should block that IP for 1 hr. i did that, but i'm unable to block genuine users after 3 unsuccessful attempts, every timeeven after 3 unsuccessful attempts from the same IP if a genuine user enters his username n password correctly, hez gaining access.
hope u understand my problem, i'm here with pasting the required files, i request you to go thru this and do the needful..
attempt.log.class.php ::
<?php
/*
+----------------------------------------------+
| |
| PHP MySQL Login attempt thing |
| |
+----------------------------------------------+
| Filename : attempt.log.class.php |
| Created : 6-Jun-06 2:41 GMT |
| Created By : Sam Clarke |
| Email : admin@free-php.org.uk |
| Version : 1.0 |
| |
+----------------------------------------------+
+----------------------+
| We like donations =) |
+----------------------+
+---------------------------------------+
| |
| MySQL sql to make tabke |
| |
+---------------------------------------+
| |
| CREATE TABLE `attempt_protect` ( |
| `IP` char(32) NOT NULL default '', |
| `ATTEMPT` int NOT NULL, |
| `TIME` char(20) NOT NULL default '', |
| PRIMARY KEY (`IP`) |
| ) TYPE=MyISAM; |
| |
+---------------------------------------+
LICENSE
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL)
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
To read the license please visit http://www.gnu.org/copyleft/gpl.html
*/
class attempt_log
{
public $attempts = 3; // Number of attemps before blocked
public $keep_secs = 3600; // Number of secounds to keep the user registered 86 400 = 1 day to find out how many in another amount of time google: "how many seconds in {a day/a week/ect}"
// MySQL config
public $host = 'localhost'; // MySQl host
public $password; // MySQL password
public $username; // MySQL username
public $db; // MySQL username
public $link; // MySQl link
public $table = 'attempt_protect'; // table name
// function to connect to MySQL
function db_connect()
{
$this->link = mysql_connect($this->host, $this->username, $this->password); // connect to MySQL
if (!$this->link) // test connection
return false;
if (mysql_select_db($this->db)) // select db and check it worked
return true;
return false;
}
// add user ip address to database
function register_user($ip)
{
// insert ip and currnt time into database
$result = mysql_query('INSERT INTO `' . $this->table .
'` (`IP` , `ATTEMPT` , `TIME`) VALUES (\' ' . mysql_real_escape_string($ip, $this->
link) . '\', \'0\', \'' . time() . '\')', $this->link);
if (!$result)
return false;
return true;
}
// check to see if the user is flooding
function check_request($ip)
{
if (!$this->db_connect())
return false; // if we cannot connect to db then return the user isnt flooding as we don't know
if ($this->user_in_db($ip)) // find out if the user is in the db
{
$return = $this->user_flooding($ip); // if they are check if there flooding
$this->remove_old_users(); // remove the old users
$this->close_db(); // close db connection
return $return; // return if there flooding or not
} else {
$this->register_user($ip); // if there not in the db add them
$this->remove_old_users(); // remove the old users
$this->close_db(); // close db connection
return false; // sonce there not in the db there not flooding so return false
}
}
function user_in_db($ip)
{
// query db to see if there in
$result = mysql_query('SELECT `TIME` FROM `' . $this->table . '` WHERE `IP` = \' ' .
mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1', $this->link);
if (mysql_num_rows($result) > 0) // if more than 0 records are returned there in
return true;
return false; // other wise return false
}
function user_flooding($ip)
{
// query db to see if there flooding
$result = mysql_query('SELECT `TIME` FROM `' . $this->table . '` WHERE `IP` = \' ' .
mysql_real_escape_string($ip, $this->link) . '\' AND `ATTEMPT` >= ' . $this->
attempts . ' LIMIT 1', $this->link);
if (mysql_num_rows($result) > 0)
// if more than 0 records are returned there flooding
return true;
return false; // other wise return false
}
function wrong($ip)
{
$this->db_connect(); // connect to mysql
// get current attempt
$current_attempt = mysql_query('SELECT `ATTEMPT` FROM `' . $this->table .
'` WHERE `IP` = \' ' . mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1',
$this->link);
$current = mysql_fetch_assoc($current_attempt);
$next = $current['ATTEMPT'] + 1;
// query db to see if there flooding
$result = mysql_query('UPDATE `' . $this->table . '` SET `ATTEMPT` = \'' . $next .
'\' WHERE `IP` = \' ' . mysql_real_escape_string($ip, $this->link) . '\' LIMIT 1',
$this->link);
}
function remove_old_users()
{
// Query db to remove all the old users
mysql_query('DELETE FROM `' . $this->table . '` WHERE `TIME` <= \'' . (time() -
$this->keep_secs) . '\'', $this->link);
}
function close_db()
{
mysql_close($this->link);
}
}
$protect = new attempt_log(); //call the class
$protect->password = ''; // set the password for MySQL
$protect->username = 'root'; // set the username for MySQL
$protect->db = 'trrcollege'; // set the MySQL db name
/*if ($protect->check_request(getenv('REMOTE_ADDR'))) { // check the user
//require_once('admin.php');
//session_unset();
//session_destroy();
//header("Location: loginblock.html");
//die('Request block, You have failed to login too many times you are now blocked for: 1 day'); //die there flooding
}*/
// show the login form or proccess the login post data here
// if their attempt was bad call the function wrong to add a bad attempt to the log
$protect->wrong(getenv('REMOTE_ADDR'));
?>
admin.php ::
<?php
//Connect to mysql server
$link=mysql_connect("localhost","root","");
if(!$link) {
die('Failed to connect to server: ' . mysql_error());
}
//Select database
$db=mysql_select_db("admintbl");
if(!$db) {
die("Unable to select database");
}
//Check whether the query was successful or not
//require_once('attempt.log.class.php');
//if ($protect->check_request(getenv('REMOTE_ADDR'))) {
//Create query
$username = $_POST["username"];
$password = $_POST["password"];
$query="SELECT * FROM adminlogin WHERE username='".$username."' AND password='".$password."'";
$result=mysql_query($query);
$rows2=mysql_fetch_array($result);
if($rows2["password"] == $password && $rows2["username"] == $username )
{
if(mysql_num_rows($result)>0)
{
//Login Successful
session_start();
$start=time();
$_SESSION['time_start']=$start;
session_register('username');
session_register('time_start');
$_SESSION['username']=$username;
$_SESSION['password']=$password;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
session_regenerate_id();
session_write_close();
include "session.php";
include("class_session.inc.php");
header("Location: redirect.php");
exit();
}
else {
//Login failed
session_unset();
session_destroy();
header("location: loginfail.htm");
exit();
}
}
/*else{
session_unset();
session_destroy();
header("Location: loginblock.html");
die('Request block, You have failed to login too many times you are now blocked for: 1 day'); //die there flooding
}
}*/
else{
session_unset();
session_destroy();
header("location: loginfail.htm");
}
?>
the problem is it is not executing the correct login part... if{}
plz do help me...
many thanks