hacking contest

hacking exploits security forum
hacking
compliance articles
upgrade backup exec
information security consultant

Gotisch
Some time ago someone asked me how he could write a secure login script for his homepage. Of course you can make a script 100% secure but you can make it resonably secure, which is enough for the you-and-me-homepage.

The aim was to write a script where you provide your username and password. And with a successfull login the $_SESSION var 'login' would be set. There was also the problem of bruteforce cracking which was taken care of by only allowing one try every 30 seconds and after 3 trys banning the ip for half an hour.

For that script i used PHP and mysql.

you can see the code at work here: http://bwl.cositel.com/login.php

the right username/password is: username/passwort



for the aboce script to work you need mysql.class.php (just rename the txt)

[attachmentid=2535]

CODE

<?
/* login.php - a hopefully "secure" login Script

Mysql tables we need :

1. ipdatenbank :
CREATE TABLE `ipdatenbank` (
`ip` VARCHAR( 15 ) NOT NULL ,
`count` TINYINT( 1 ) NOT NULL ,
`time` INT( 10 ) NOT NULL
);

2. benutzer :
CREATE TABLE `benutzer` (
`username` VARCHAR( 255 ) NOT NULL ,
`passwort` VARCHAR( 255 ) NOT NULL
);

255 is very high.

by Gotisch :)
*/
function check_ip($ip) {
global $DB;
$ip = mysql_escape_string($ip);
$ipcheck = $DB->query("SELECT count, time FROM `ipdatenbank` WHERE `ip`='$ip'");
if (mysql_num_rows($ipcheck) == 0)
{
$upd = $DB->query("INSERT INTO `ipdatenbank` (count, time, ip) VALUES ('1', UNIX_TIMESTAMP(), '$ip')");
       return 0;
}
$array = mysql_fetch_array($ipcheck);
if ($array['count'] > 3)
{
       if ($array['time'] + 1800 < time())
       {
        $upd = $DB->query("UPDATE `ipdatenbank` SET `count`='1', `time`=UNIX_TIMESTAMP() WHERE `ip`='$ip'");
        return 0;
       }
       return "You have been blocked for 30 min.";
}
if ($array['time'] + 30 < time())
{
        $upd =  $DB->query("UPDATE `ipdatenbank` SET `count`=count+1, `time`=UNIX_TIMESTAMP() WHERE `ip`='$ip'");
       return 0;
}
return "You have to wait 30sec.";
}

function check_user($username, $passwort) {
global $DB;
$username = mysql_escape_string($username);
$usercheck = $DB->query("SELECT passwort FROM `benutzer` WHERE `username`='$username'");
if (mysql_num_rows($usercheck) != '0')
{
 $array = mysql_fetch_array($usercheck);
       if ($array['passwort'] == $passwort)
       {
               return 0;
       }
}
return "This Username/Password is not OK.";
}
/* username and pass where given.*/
$login = "Please Enter your Username and Password";
if ($_POST['username'] && $_POST['passwort'])
{
//connect to database.
require("mysql.class.php");
$DB=new FM_SQL_CLASS;
$DB->server="localhost";
$DB->dbname="yourdb";
$DB->username="yourusername";
$DB->password="yourpass";
$DB->connect();
$login = check_ip($_SERVER['REMOTE_ADDR']);
if ($login == '0')
{
 $login = check_user($_POST['username'], $_POST['passwort']);
 if ($login == '0')
 {
 $_SESSION['login'] = true;
 $login = "You are now Logged in";
 }
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><? echo $login; ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<?
if($_SESSION['login'])
{
echo "You are now loggin in and login is set to true;)";
} else {
echo $login; ?>
<br />
<form name="form1" id="form1" method="post" action="<? echo $_SERVER['PHP_SELF']; ?>">
 <input type="text" name="username" />
 <input type="password" name="passwort" />
 <input type="submit" name="Submit" value="Einloggen" />
</form>
<?
}
?>
</body>
</html>



Any suggestions bugs / comments are highly welcome.
Vixen
Shouldn't I use htmlentities and addslashes on the variables to prevent SQL injection/XSS attacks? Or what else do they use for that?
FuzZyBeeR
the mysql_escape_string is used for this.

for more info look at http://www.php.net/mysql_escape_string
realmasterX
You have to reset the 'count'-entery (or delete the db-entery for the IP) if the login is correct! Otherwise you can login 3 times and then you have to wait for half an hour!!!

btw: 'mysql_escape_string' is not up to date! have al look: mysql-real-escape-string

very nice work!
myth
Cheers for the script Gotisch, got a mate that needs to see how to write secure logins, he wanted me to put the password in the url to make it more secure. Idiots :P

Just a note about the link realmasterX put in, if you read it, it shows you an example sql injection attack which could occur if did not put those checks in place.

(the english version of the link just click on the link and change the /de/ to /en/ or prefered language-code)

QUOTE
Example 2. An example SQL Injection Attack

<?php
// Query database to check if there are any matching users
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);

// We didn't check $_POST['password'], it could be anything the user wanted! For example:
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// This means the query sent to MySQL would be:
echo $query;
?>

The query sent to MySQL:

SELECT * FROM users WHERE name='aidan' AND password='' OR ''=''

This would allow anyone to log in without a valid password.


Quiet a nice little example i thought i'd point out
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.

 
Invision Power Board © 2001-2005 Invision Power Services, Inc.