From 30f193ae802bd5c88ce78474601480002adcbf75 Mon Sep 17 00:00:00 2001 From: Shivam Dixit Date: Mon, 2 Sep 2013 19:20:52 +0530 Subject: [PATCH 1/3] Added FIRST_LOGIN_ATTEMPT column in DB and modified isBruteForce function --- SQL/OWASP.sql | 120 +++++++++++++++++++++++++++---------- libs/auth/adv_password.php | 36 ++++++----- 2 files changed, 109 insertions(+), 47 deletions(-) diff --git a/SQL/OWASP.sql b/SQL/OWASP.sql index 0403c0a..c78e5fb 100644 --- a/SQL/OWASP.sql +++ b/SQL/OWASP.sql @@ -1,32 +1,28 @@ --- phpMyAdmin SQL Dump --- version 4.0.5 --- http://www.phpmyadmin.net +-- MySQL dump 10.13 Distrib 5.5.32, for debian-linux-gnu (x86_64) -- --- Host: localhost --- Generation Time: Aug 14, 2013 at 06:45 AM --- Server version: 5.1.71-community --- PHP Version: 5.3.27 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - +-- Host: localhost Database: OWASP +-- ------------------------------------------------------ +-- Server version 5.5.32-0ubuntu0.12.04.1 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; - --- --- Database: `OWASP` --- - --- -------------------------------------------------------- +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -- -- Table structure for table `LOGS` -- -CREATE TABLE IF NOT EXISTS `LOGS` ( +DROP TABLE IF EXISTS `LOGS`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `LOGS` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `MESSAGE` text, `FILENAME` text, @@ -35,33 +31,56 @@ CREATE TABLE IF NOT EXISTS `LOGS` ( `DATETIME` text, `LINE` int(10) DEFAULT NULL, PRIMARY KEY (`ID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=25 ; +) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; --- -------------------------------------------------------- +-- +-- Dumping data for table `LOGS` +-- + +LOCK TABLES `LOGS` WRITE; +/*!40000 ALTER TABLE `LOGS` DISABLE KEYS */; +/*!40000 ALTER TABLE `LOGS` ENABLE KEYS */; +UNLOCK TABLES; -- -- Table structure for table `PASSWORD` -- -CREATE TABLE IF NOT EXISTS `PASSWORD` ( +DROP TABLE IF EXISTS `PASSWORD`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `PASSWORD` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `TEMP_PASS` varchar(128) NOT NULL, `USE_FLAG` tinyint(1) NOT NULL, `TEMP_TIME` int(10) NOT NULL, `TOTAL_LOGIN_ATTEMPTS` int(2) DEFAULT NULL, `LAST_LOGIN_ATTEMPT` int(10) DEFAULT NULL, + `FIRST_LOGIN_ATTEMPT` int(10) DEFAULT NULL, `USERID` varchar(32) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `USERID` (`USERID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=65 ; +) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `PASSWORD` +-- --- -------------------------------------------------------- +LOCK TABLES `PASSWORD` WRITE; +/*!40000 ALTER TABLE `PASSWORD` DISABLE KEYS */; +/*!40000 ALTER TABLE `PASSWORD` ENABLE KEYS */; +UNLOCK TABLES; -- -- Table structure for table `SESSION` -- -CREATE TABLE IF NOT EXISTS `SESSION` ( +DROP TABLE IF EXISTS `SESSION`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SESSION` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `SESSION_ID` varchar(32) NOT NULL, `DATE_CREATED` int(10) NOT NULL, @@ -69,29 +88,51 @@ CREATE TABLE IF NOT EXISTS `SESSION` ( `USERID` varchar(32) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `SESSION_ID` (`SESSION_ID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=447 ; +) ENGINE=InnoDB AUTO_INCREMENT=447 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; --- -------------------------------------------------------- +-- +-- Dumping data for table `SESSION` +-- + +LOCK TABLES `SESSION` WRITE; +/*!40000 ALTER TABLE `SESSION` DISABLE KEYS */; +/*!40000 ALTER TABLE `SESSION` ENABLE KEYS */; +UNLOCK TABLES; -- -- Table structure for table `SESSION_DATA` -- -CREATE TABLE IF NOT EXISTS `SESSION_DATA` ( +DROP TABLE IF EXISTS `SESSION_DATA`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SESSION_DATA` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `SESSION_ID` varchar(32) NOT NULL, `KEY` varchar(32) NOT NULL, `VALUE` varchar(64) DEFAULT NULL, PRIMARY KEY (`ID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=35 ; +) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `SESSION_DATA` +-- --- -------------------------------------------------------- +LOCK TABLES `SESSION_DATA` WRITE; +/*!40000 ALTER TABLE `SESSION_DATA` DISABLE KEYS */; +/*!40000 ALTER TABLE `SESSION_DATA` ENABLE KEYS */; +UNLOCK TABLES; -- -- Table structure for table `USER` -- -CREATE TABLE IF NOT EXISTS `USER` ( +DROP TABLE IF EXISTS `USER`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `USER` ( `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, `USERID` varchar(32) NOT NULL, `ACCOUNT_CREATED` int(10) NOT NULL, @@ -103,8 +144,25 @@ CREATE TABLE IF NOT EXISTS `USER` ( `STATIC_SALT` varchar(128) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `USERID` (`USERID`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=187 ; +) ENGINE=InnoDB AUTO_INCREMENT=187 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Dumping data for table `USER` +-- + +LOCK TABLES `USER` WRITE; +/*!40000 ALTER TABLE `USER` DISABLE KEYS */; +/*!40000 ALTER TABLE `USER` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2013-09-02 19:09:00 diff --git a/libs/auth/adv_password.php b/libs/auth/adv_password.php index 28b9931..7f52cec 100755 --- a/libs/auth/adv_password.php +++ b/libs/auth/adv_password.php @@ -35,17 +35,24 @@ class AdvancedPasswordManagement /** - * It denotes the # of maximum attempts for login using the password. If this limit exceeds and this happens within a very short amount of time, then it is considered as a brute force attack. + * It denotes the # of maximum attempts for login using the password. If this limit exceeds and this happens within a very short amount of time (which is defined by $bruteForceLockAttemptTotalTime), then it is considered as a brute force attack. * @var int */ public static $bruteForceLockAttempts = 5; //This tells how many attemps must be considered before brute-force lock. + + /** + * It denotes the amount of time in seconds for which time for total number of attempts must not exceed this value. If this happens , then it is considered as a brute force attack. + * @var int + */ + public static $bruteForceLockAttemptTotalTime =5; //This tells that if 5 login attempts are made within this time then it will be a brute force. + /** * It denotes the amount of time in seconds between which no two wrong passwords must be entered. If this happens, then it is considered that a bot is trying to hack the account using brute-force means. * @var int */ - public static $bruteForceLockTimePeriod = 5; //5 SEC - This defines the time-period after which next login attempt must be carried out. E.g if the time is 5 sec, then time-period between two login attempts must minimum be 5 sec, otherwise it will be considered brute-force attack. + public static $bruteForceLockTimePeriod = 1; //1 SEC - This defines the time-period after which next login attempt must be carried out. E.g if the time is 5 sec, then time-period between two login attempts must minimum be 1 sec. Assuming that user will take atleast 1 sec time to type between two passwords. @@ -99,7 +106,7 @@ protected function isBruteForce($user) if (count($result) < 1) { - SQL("INSERT INTO PASSWORD (`TEMP_PASS`, `USE_FLAG`, `TEMP_TIME`, `TOTAL_LOGIN_ATTEMPTS`, `LAST_LOGIN_ATTEMPT`, `USERID`) VALUES (?, ?, ?, ?, ?, ?)", array( randstr(10), 1, 0, 1, time(), $user)); + SQL("INSERT INTO PASSWORD (`TEMP_PASS`, `USE_FLAG`, `TEMP_TIME`, `TOTAL_LOGIN_ATTEMPTS`, `LAST_LOGIN_ATTEMPT`, `FIRST_LOGIN_ATTEMPT`, `USERID`) VALUES (?, ?, ?, ?, ?, ?,?)", array(randstr(10), 1, 0, 1, time(), $currentTime, $user)); return FALSE; } @@ -107,22 +114,19 @@ protected function isBruteForce($user) { if ( ($currentTime - $result[0]['LAST_LOGIN_ATTEMPT']) <= AdvancedPasswordManagement::$bruteForceLockTimePeriod ) { - if ($result[0]['TOTAL_LOGIN_ATTEMPTS'] >= AdvancedPasswordManagement::$bruteForceLockAttempts) - { - SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = `TOTAL_LOGIN_ATTEMPTS` + 1, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array($currentTime, $user)); - - return TRUE; - } - else - { - SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = `TOTAL_LOGIN_ATTEMPTS` + 1, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array($currentTime, $user)); - - return FALSE; - } + SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = `TOTAL_LOGIN_ATTEMPTS` + 1, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array($currentTime, $user)); + + return TRUE; + } + else if ($result[0]['TOTAL_LOGIN_ATTEMPTS'] >= AdvancedPasswordManagement::$bruteForceLockAttempts && ($currentTime - $result[0]['FIRST_LOGIN_ATTEMPT']) <= AdvancedPasswordManagement::$bruteForceLockAttemptTotalTime) + { + SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = `TOTAL_LOGIN_ATTEMPTS` + 1, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array($currentTime, $user)); + + return TRUE; } else { - SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = ?, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array(1, $currentTime, $user)); + SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = ?, `LAST_LOGIN_ATTEMPT` = ?, `FIRST_LOGIN_ATTEMPT` =? WHERE USERID = ?", array(1, $currentTime, $currentTime, $user)); return FALSE; } From 2efedbce156be0b2099e5d2dfaaf4e4c7c119fbe Mon Sep 17 00:00:00 2001 From: Shivam Dixit Date: Mon, 2 Sep 2013 19:51:34 +0530 Subject: [PATCH 2/3] Corrected the value of bruteForceLockAttemptTotalTime --- libs/auth/adv_password.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/auth/adv_password.php b/libs/auth/adv_password.php index 7f52cec..5cc5574 100755 --- a/libs/auth/adv_password.php +++ b/libs/auth/adv_password.php @@ -45,7 +45,7 @@ class AdvancedPasswordManagement * It denotes the amount of time in seconds for which time for total number of attempts must not exceed this value. If this happens , then it is considered as a brute force attack. * @var int */ - public static $bruteForceLockAttemptTotalTime =5; //This tells that if 5 login attempts are made within this time then it will be a brute force. + public static $bruteForceLockAttemptTotalTime =25; //This tells that if 5 login attempts are made within this time then it will be a brute force. /** From c0fcc9c8c244d028ba9102a8492bdaac7df12073 Mon Sep 17 00:00:00 2001 From: Shivam Dixit Date: Wed, 4 Sep 2013 15:32:38 +0530 Subject: [PATCH 3/3] Modified conditions of isBruteForce() --- libs/auth/adv_password.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/auth/adv_password.php b/libs/auth/adv_password.php index 5cc5574..4ea3403 100755 --- a/libs/auth/adv_password.php +++ b/libs/auth/adv_password.php @@ -118,6 +118,12 @@ protected function isBruteForce($user) return TRUE; } + else if($result[0]['TOTAL_LOGIN_ATTEMPTS'] < AdvancedPasswordManagement::$bruteForceLockAttempts) + { + SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = ?, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array(1, $currentTime, $user)); + + return FALSE; + } else if ($result[0]['TOTAL_LOGIN_ATTEMPTS'] >= AdvancedPasswordManagement::$bruteForceLockAttempts && ($currentTime - $result[0]['FIRST_LOGIN_ATTEMPT']) <= AdvancedPasswordManagement::$bruteForceLockAttemptTotalTime) { SQL("UPDATE PASSWORD SET `TOTAL_LOGIN_ATTEMPTS` = `TOTAL_LOGIN_ATTEMPTS` + 1, `LAST_LOGIN_ATTEMPT` = ? WHERE USERID = ?", array($currentTime, $user));