Be a Supporter!

Help With Php Ip Ban Script

  • 1,138 Views
  • 7 Replies
New Topic Respond to this Topic
DoomyCheese
DoomyCheese
  • Member since: Aug. 25, 2006
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Help With Php Ip Ban Script 2008-06-06 22:51:35 Reply

I have a contact form on my website that is rather exploitable, I've implemented the below code into the page as a means of stopping spammers (incoming mail includes the senders IP), but it's a pain to add new bans.

<?php
$banned = array("70.248.51.77", "75.156.110.47");
if (in_array($_SERVER['REMOTE_ADDR'], $banned)) {
header( 'Location: banned.html' ) ;
exit;
}
?>

What I would really like is a form in which I can easily add/remove bans to this script. Can anyone help me with this?


BBS Signature
Loccie
Loccie
  • Member since: Feb. 27, 2004
  • Offline.
Forum Stats
Member
Level 16
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-07 01:36:45 Reply

You're going to have to save the IPs in some sort of database if you want to save them. The form can then save it to the databse and the ban script can get all the info from the database.

Fruitpastles
Fruitpastles
  • Member since: Oct. 13, 2005
  • Offline.
Forum Stats
Member
Level 10
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-11 14:02:44 Reply

Hi,

I wrote you something the otherday in school. I only just remembered, I'll see if I can get it.

Fruitpastles
Fruitpastles
  • Member since: Oct. 13, 2005
  • Offline.
Forum Stats
Member
Level 10
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-11 14:59:30 Reply

<?php
/**********************************************
* AUTHOR: 		Craig Kewley
* E-MAIL: 		fruitpastles@gmail.com
* DESCRIPTION: 	IP Address ban functionality
***********************************************/

//*********************
// SETTINGS
//*********************

//change me :)
define("USERNAME", "user1");
define("PASSWORD", "pass1");
define("SALT", "ksjf94w38auja8q93u");

define("FILE_NAME", "bans.txt");

define("BAN_MESSAGE", "<b>Access Denied</b><br/>");



//*********************
// FUNCTIONS
//*********************

//LOGIN - checks username and password
function login($username, $password)
{
	//if username and password were correct
	if($username == USERNAME && $password == PASSWORD)
	{
		//encrypt password
		$code = crypt(USERNAME, SALT);
		
		//start session
		session_start();
		
		//set auth cookie with code 
		setcookie("auth", $code);
		
		//fill session var with code
		$_SESSION['auth'] = $code;
		
		//regen session id
		session_regenerate_id();
		
			//login successful
			return true;
	}
	else //credentials incorrect
	{
		//login failed
		return false;
	}
}


//logout - destroys login info
function logout()
{
	//if logged in
	if( isLoggedIn() )
	{	
		//initialize session
		session_start();
		
		//destroy session
		session_destroy();
		
		//fill the session global empty
		$_SESSION = array();
		
		//set expiration in the past
		$expires = mktime(0, 0, 1, 1, 1990);
	
		//remove auth cookie
		setcookie("auth", "", $expires);
	}
	
		return true;
}


//ISLOGGEDIN - check if logged in
function isLoggedIn()
{
	//ensure new session is not set if not logged in
	if( isset($_COOKIE['auth']) && !isset($_SESSION['auth']) ) 
	{
		session_start(); //initialize session
	}
	
	
	//check if session and cookie exist
	if( !isset($_SESSION['auth']) || !isset($_COOKIE['auth']) ) //or not xor
	{
		return false;
	} 
	else 
	{
		//if hashes are the same
		if($cookieCode == $sessionCode)
		{
			return true;
		} 
		else //codes don't match
		{
			//destroy login files
			logout();
			
			//codes dont match - return false
			return false;
		}
	}

}


//ISBANNED - checks if user has been banned
function isBanned($ip)
{
	//get list of bans and split into array
	$bans = getBans();
	$bans = explode(";", $bans);
	
	//check if ip is in ban list
	if( in_array($ip, $bans) )
	{
		return true;
	}
	else
	{
		return false;
	}
}


//ADDBAN - add ban to list
function AddBan($ip)
{
	//open file
	$fs = fopen(FILE_NAME, "a");
	
	//prep string ';' delimiter
	$toWrite = $ip. ";";
	
	//overwrite data in file with new
	fwrite($fs, $toWrite);
	
	//close file
	fclose($fs);
	
		return true;
}


//REMOVEBAN - remove ban from list
function RemoveBan($ip)
{
	//prep ip - ';' delimiter
	$ip .= ";";
	
	//get ban list
	$bans = getBans();
	
	//replace the string if found
	$bans =	str_replace($ip, "", $bans);
	
	//open file
	$fs = fopen(FILE_NAME, "w");
	
	//overwrite with new complete + new data
	fwrite($fs, $bans);
	
	//close
	fclose($fs);
	
}


//GETBANS - returns list of bans
function getBans()
{
	//if file has data
	if( filesize(FILE_NAME) != 0)
	{
		//open file
		$fs = fopen(FILE_NAME, "r");
		
		//get list from file
		$bans = fread($fs, filesize(FILE_NAME) );
		
		//close
		fclose($fs);
		
		//return data - i suppose i could return it as an array or summit but cba now ;P.
			return $bans;
	}
	else //file contains no data
	{
		return false;
	}
}


//REDIRECT - redirect user
function redirect($location)
{
		//check if http headers already sent
		switch( headers_sent() )
		{
			//if not then redirect using header
			case false:
					header("Location: " . $location);
				break;
			
			//else use meta refresh
			case true:
				echo('<meta http-equiv="refresh" content="0;url=' . $location . '">');
			break;
		}
		
		//output link incase of fail
		die('<a href="' . $location . '"><b>Click here to continue...</b></a>');
}




//*********************
// Main
//*********************


//--GRAB THE ACTION VARIABLE
(isset($_GET['act'])) ? extract($_GET) : $act = NULL;



//--PROCESS ACTION VARIABLE
switch($act)
{
	//--LOGIN
	case "login":

		if( !isset($_POST['username']) || !isset($_POST['password']) )
		{
			echo('<form action="?act=login" method="post">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="login">');
		}
		else
		{
			if( login($_POST['username'], $_POST['password']) )
			{
				redirect("?act=main");
			}
			else
			{
				die("Incorrect Username or Password.<br>
				<a href='?act=login'>Re-try...</a>");
			}
		}
		
	break;
	
	//--LOGOUT
	case "logout":
		logout();
			redirect("?");
	break;
	
	//--ADD
	case "add":
		if( isLoggedIn())
		{
			AddBan($_POST['ip']);
			redirect("?act=main");
		}
		else
		{
			redirect("?");
		}
	break;
	
	
	//--REMOVE
	case "remove":
		if( isLoggedIn())
		{
			RemoveBan($_GET['ip']);
			redirect("?act=main");
		}
		else
		{
			reidrect("?");
		}
	break;
	
	
	//--MAIN
	case "main":
	
		//LOGIN STUFF
		if ( !isLoggedIn() )
		{
			redirect("?");
		}
		else
		{
			echo( "<b>" . ucfirst(USERNAME) . "</b>(<a href='?act=logout'>Logout</a>)<br><br>");
		}
		
		
		//BAN LIST STUFF
		if( !getBans() ) //if list is empty
		{
			echo('<table cellspacing="1" border="1">
		<tr> <td>IP</td> <td>Remove</td> </tr>
		<tr> <td colspan="2" align="center">None</td> </tr>
		</table><br><br>');
		}
		else //list the bans
		{
			//get bans
			$bans = getBans();
			
			//split into array
			$bans = explode(";", $bans);
		
			//table start
			echo('<table cellspacing="1" border="1">
			<tr> <td>IP</td> <td>Remove</td> </tr>');
		
			foreach($bans as $id => $ip)
			{
				if($ip != "")
				{
					//output for each ban
					echo('<tr> <td>'. $ip .'</td> <td> <a href="?act=remove&ip='. $ip .'">Remove</a> </td> </tr>');
				}
			}
		
			//end table
			echo('</table><br><br>');
			}
		
		//add ban form
		echo('<form action="?act=add" method="post">
IP: <input type="text" name="ip"><br>
<input type="submit" value="Add">
</form>');
	break;
	
	
	//--DEFAULT - check username
	default:
		if( isBanned( $_SERVER['REMOTE_ADDR'] ))
		{
			die(BAN_MESSAGE);
		}
}

?>

To use just put the following on the first line the file you want to protect: (after changing "PATH_TO")

<?php require("PATH_TO/ipban.php"); ?>
henke37
henke37
  • Member since: Sep. 10, 2004
  • Offline.
Forum Stats
Member
Level 30
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-12 05:46:07 Reply

I have to say, that looks like a very profesional script. Too bad it has one sevre bug, you never set $cookieCode (and the other variable).


Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.

Fruitpastles
Fruitpastles
  • Member since: Oct. 13, 2005
  • Offline.
Forum Stats
Member
Level 10
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-12 11:38:53 Reply

At 6/12/08 05:46 AM, henke37 wrote: I have to say, that looks like a very profesional script. Too bad it has one sevre bug, you never set $cookieCode (and the other variable).

Oh god! Now I just feel stupid. I took the isLoggedIn() function from another one of my scripts and changed it. In my other one, I run a check on the data coming in through the cookie and session, before assigning them to the, now unset, variables.

Normally I would have spotted that but it was rushed slightly, stupid that I didn't use error_reporting(E_ALL); as well. Although looking at it, It would have been difficult for somebody to set $_SESSION['auth'] without knowing the login information.

Anyway Thanks a lot for pointing that out :)!

@DoomyCheese
Replace the Logout(); and isLoggedIn(); function with the following:

//logout - destroys login info
function logout()
{
		//initialize session
		session_start();
		
		//destroy session
		session_destroy();
		
		//fill the session global empty
		$_SESSION = array();
		
		//set expiration in the past
		$expires = mktime(0, 0, 1, 1, 1990);
	
		//remove auth cookie
		setcookie("auth", "", $expires);
	
		return true;
}


//ISLOGGEDIN - check if logged in
function isLoggedIn()
{
	//ensure new session is not set if not logged in
	if( empty($_COOKIE['auth']) || empty($_SESSION['auth']) ) //or not xor
	{
		session_start(); //initialize session
	}
	else
	{
		return false; //not logged in
	}
	
	
	//check if both empty - will equal if both are
	if( empty($_COOKIE['auth']) || empty($_SESSION['auth']) )//or not xor
	{
		//are empty - destroy
		logout();	
		
		//redirect
		redirect("?");
	}
	
	//if hashes are the same
	if($_COOKIE['auth'] == $_SESSION['auth'])
	{
			return true;
	} 
	else //codes don't match
	{
		//destroy login files
		logout();
			
		//codes dont match - return false
		return false;
	}
}
henke37
henke37
  • Member since: Sep. 10, 2004
  • Offline.
Forum Stats
Member
Level 30
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-13 12:45:16 Reply

Now some comments contradicts other comments and the actual code.


Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.

Fruitpastles
Fruitpastles
  • Member since: Oct. 13, 2005
  • Offline.
Forum Stats
Member
Level 10
Blank Slate
Response to Help With Php Ip Ban Script 2008-06-13 18:22:20 Reply

At 6/13/08 12:45 PM, henke37 wrote: Now some comments contradicts other comments and the actual code.

Meh it works, the first empty check should be isset though. Doesn't look like the authors coming back anyways.

At 6/13/08 02:48 PM, bagoverhead wrote: giving crutches to a cobra >.<

Matter of opinion...its just a little more convenient.
I don't understand the reason you have to get so annoyed when I PM you to ask the meaning of your comments either?