[pmwiki-users] making brute force attacks more difficult

Thomas Bley thomas.bley at simple-groupware.de
Mon Aug 20 14:19:52 CDT 2007


Hello,

I propose two things:
- bind the session to the remote ip address and the user agent
- restrict a login from a remote ip address if there are more than 5 bad 
logins within the last 2 hours

What do you think ?

Code:

function getSessionIpAgent() {
  $ip = "";
  if (isset($_SERVER["REMOTE_ADDR"])) $ip .= $_SERVER["REMOTE_ADDR"];
  if (isset($_SERVER["HTTP_CLIENT_IP"])) $ip .= $_SERVER["HTTP_CLIENT_IP"];
  if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) $ip .= 
$_SERVER["HTTP_X_FORWARDED_FOR"];
  if (isset($_SERVER["HTTP_USER_AGENT"])) $ip .= 
$_SERVER["HTTP_USER_AGENT"];
  return $ip;
}

// tb begin
function badLogin() {
  $ipagent = sha1(getSessionIpAgent());
  mkdirp('temp');
  $ipfile = "temp/_$ipagent";
  if (file_exists($ipfile) && filemtime($ipfile) < time()-7200) 
@unlink($ipfile);
  if ($fp = fopen($ipfile,'a')) {
    fwrite($fp,'1');
    fclose($fp);
  }
}
// tb end

function SessionAuth($pagename, $auth = NULL) {
  global $AuthId, $AuthList, $AuthPw;
  static $called;

  @$called++;
  if (!$auth && ($called > 1 || !@$_REQUEST[session_name()])) return;

  $sid = session_id();
  @session_start();

  // tb begin
  $ipagent = sha1(getSessionIpAgent());
  if (!empty($_SESSION['authipagent']) && $_SESSION['authipagent'] != 
$ipagent) {
    echo 'Access denied. (ip, user agent mismatch)';
    exit;
  }
  $ipfile = "temp/_$ipagent";
  if (file_exists($ipfile) && filesize($ipfile) > 5) {
    echo 'Access denied. (too many incorrect logins, please wait 2 hours)';
    exit;
  }
  $_SESSION['authipagent'] = $ipagent;
  // tb end
 
  foreach((array)$auth as $k => $v)
    if ($k) $_SESSION[$k] = (array)$v + (array)@$_SESSION[$k];
   
  if (!isset($AuthId)) $AuthId = @end($_SESSION['authid']);
  $AuthPw = array_keys((array)@$_SESSION['authpw']);
  $AuthList = array_merge($AuthList, (array)@$_SESSION['authlist']);
  if (!$sid) session_write_close();
}

function PmWikiAuth($pagename, $level, $authprompt=true, $since=0) {
...
  if (!$authprompt) return false;

  // tb begin
  if (!empty($_POST['authpw'])) badLogin();
  // tb end

Regards,
Thomas


Christophe David wrote:
> Looking at the logfiles I suspect someone is trying a brute force
> attack to get the admin password one of my PmWiki fields, sending many
> requests at a time and loading the server quite a lot.
>
> If I understand correctly, as $DefaultPasswords['admin']  is normally
> always defined, there is no need for an attacker to bother with the
> AuthUser or LDAP aspects.
>
> So trying SiteAdmin.Whatever?action=edit repeatedly with the HTTP POST
> method and setting the authpw variable to the guessed value should
> work if enough time is spent.
>
> I was wondering is it would not be a good idea to save the remote IP
> address and a timestamp for every failed authentication (ideally
> whatever the method used - AuthUSer, LDAP, etc.), and to deny access
> without any other control if the same address tried less than n
> seconds earlier.  This would make brute force attacks too long to be
> practical.
>
> Is there already something available or did someone alreday think
> about how to implement such a feature efficiently, if possible in a
> way that is independent of the authetication method ?
>
> Thank you in anticipation.
>
> Christophe
>
> _______________________________________________
> pmwiki-users mailing list
> pmwiki-users at pmichaud.com
> http://www.pmichaud.com/mailman/listinfo/pmwiki-users
>
>   




More information about the pmwiki-users mailing list