Tutorials

Anti bruteforce script

Een enkele functie via een (my)SQL-database bijhoudt hoe vaak en wanneer en waarmee er ingelogd wordt. Bij overschrijding van van het geconfigureerde aantal volgt er onherroepelijk een die()!

Pagina 1

Inleiding

Wat op http://www.phphulp.nl/php/tutorial/beveiliging/anti-bruteforce-bij-inloggen/782/ staat is handig. Dus hier de uitwerking.

Het script moet bij login-pogingen geïmporteerd en aangeroepen worden.

1. Sla het script op als antibruteforce.php
2. Importeer het bestand:
<?php 
require("antibruteforce.php");
?>

3. Voer de functie uit:
<?php 
$protected = protect_against_brute_force_attacks();
?>


De functie returned geeft TRUE terug bij succes.
En (dus) FALSE bij fouten (met trigger_error()).

Pagina 2

Het script

Dit is het script wat in antibruteforce.php komt te staan:

<?php

function protect_against_brute_force_attacks($account = null, $clear = false)
	{
	// protect your website against brute_force_attacks 
	// call protect_against_brute_force_attacks() to log
	// call protect_against_brute_force_attacks(true) to remove logs with current IP-adress
	
	// Configurate the script here
	$config['table_name'] = 'antibruteforcetable'; // make sure its not used for something else
	$config['attempts'] = 10; // count the amounts of (failed) attempts
	$config['in_amount_of_minutes'] = 3; // check last ... minutes
	$config['get_account'] = $_POST['username']; // what is the account-input? Emailadress? IP
	
	$config['could-not-create-table'] = 'The anti-brute-force-table can\'t be made.'; // error messages
	$config['could-not-clear-rows'] = 'The rows with your IP couldn\'t be deleted'; // error messages
	$config['could-not-select-logs'] ='Can\'t SELECT the logs for some reason.'; // error messages
	$config['user-is-bruteforcing'] = 'You seems like a brute-forcer. Just wait a few minutes before trying again.'; // error messages
	$config['could-not-update-table'] = 'The log can\'t be made.'; // error message
	
	// grap some information
	$ipadress = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
	if($account !== NULL)
		{
		$account = mysql_real_escape_string($_POST[$config['account']]);
		}
	
	// make table in database (connection needed)
	$res = mysql_query("
					CREATE TABLE IF NOT EXISTS ".$config['table_name']." 
						(
						abf_id int(11) NOT NULL auto_increment,
						abf_account varchar(255) NOT NULL,
						abf_ipadress varchar(15) NOT NULL,
						abf_time datetime NOT NULL,
						abf_post text NOT NULL,
						abf_get text NOT NULL,
						PRIMARY KEY  (abf_id)
						) 
					ENGINE='MyISAM'
					DEFAULT CHARSET='utf8'
					COMMENT='Logs of brute-force attacks' ;
					AUTO_INCREMENT = 1;
					");
	// check for table
	if ($res === false) 
		{
		trigger_error($config['could-not-create-table']);
		return false;
		}
	
	// check if login was good 
	if($clear !== false)
		{
		// clear the records for this ip for this account
		$res = mysql_query("DELETE FROM ".$config['table_name']." WHERE abf_ipadress = '".$ipadress."' AND abf_account = '".$account."' ");
		if ($res === false) 
			{
			trigger_error($config['could-not-clear-rows']);
			return false;
			}	
		}
  	
	// search in database for records on this adress, only last $config['minutes'] 
	$res = mysql_query("SELECT COUNT(abf_id) FROM ".$config['table_name']." WHERE abf_ipadress = '".$ipadress."' AND abf_time > DATE_SUB(NOW(), INTERVAL ".$config['in_amount_of_minutes']." MINUTE)");
	
	// could we get the requested data?
	if ($res === false) 
		{
		trigger_error($config['could-not-select-logs']);
		return false;
		}
	// yes, we can. So, check for brute-force attempts
	else
		{
		// fetch it while you can
		$data = mysql_fetch_array($res, MYSQL_NUM);
		
		// oke, here is the master-part: the equasion
		if($data[0] > $config['attempts'])
			{
			// to much login-attempts in the configured time
			
			// let de server sleep (and let the user wait)
			sleep(5);
			die($config['user-is-bruteforcing']);
			return false;
			}
		
		// make a log of this attempt
		$res = mysql_query("INSERT INTO ".$config['table_name']." (abf_account, abf_ipadress, abf_time, abf_get, abf_post) VALUES ('".$account."', '".$ipadress."', NOW(), '".mysql_real_escape_string(print_r($_GET, true))."', '".mysql_real_escape_string(print_r($_POST, true))."'); ");
		
		// could it be done?
		if ($res === false) 
			{
			// trigger the error
			trigger_error($config['could-not-update-table']);
			return false;
			}
		}
	return true; // why not?
	}
Pagina 3

False alarm?

Als iemand gewoon wat fouten maakte zal dat blijken uit een succesvolle loginpoging.

Daarom moet het worden 'opgeruimd'.
Op het punt waar je inlogd roep je het script nogmaals aan:

<?php
$account = '...'; // wat dan ook
protect_against_brute_force_attacks($account, true);
?>


Account kan dus ook $_SESSION['login']['name'] zijn oid. Dat maakt niet zo veel uit.

Succes ermee.
Reacties graag!

Reacties

0
Nog geen reacties.