[horde] Compromised account/Spammer detection hook
Kevin Konowalec
webadmin at ualberta.ca
Tue Dec 16 19:30:48 UTC 2008
Hey guys,
Something we're constantly fighting with here is people falling prey
to Phishing scams. We're doing our best to educate our users but
invariably someone will send their username and password to Nigeria
and before you know it we're getting blocked by ISPs for sending
spam. Horde 3.3 helps a lot in this regard by allowing permissions to
be set to limit the number of recipients a message can have and the
number of messages that can be sent out during a specified time
period. However, where it was falling short for us was the lack of
administrator notification when a user had hit that limit. We want to
be able to detect holed accounts as quickly as possible so we can
disable and reset them without further damage being done. Horde out
of the box didn't have this functionality so I grabbed a PHP manual
and wrote one myself.
I'm putting this out there to the community so that a) other admins
can make use of it if they need something like this but also b)
because I'm not a native PHP coder nor am I intimately familiar with
the inner workings of the horde codebase so I'm hoping someone might
spot something I missed or maybe suggest ways to make the code a
little more elegant.
Anyway... this hook detects when a user exceeds the max_timelimit
setting and then immediately grabs the contents of their (one or more)
signatures (since that's where they usually hide the spam text) and
packages it up into an email message to whatever your "problems" email
is set up to be. I also threw in a var dump of the 'confirm_email'
field as I found a whole bunch of crap stuffed in there too so I just
wanted to cover all the bases.
So here's the code. Any comments/suggestions would be appreciated.
K
// Kevin's funky _perms_hook_denied function (/horde/config/hooks.php)
if (!function_exists('_perms_hook_denied')) {
function _perms_hook_denied($permission)
{
if (($pos = strpos($permission, ':')) === false) {
$app = $permission;
} else {
$app = substr($permission, 0, $pos);
$perm = substr($permission, $pos+1, strlen($permission)-
strlen($app)-1);
}
if ($app=="imp" && $perm=="max_timelimit") {
$user = Auth::getAuth();
$old_login = @unserialize($GLOBALS['prefs']-
>getValue('last_login'));
$lastlogin = sprintf("Last login: %s from %s",
strftime('%c', $old_login['time']), $old_login['host']);
$timelimit = IMP::hasPermission('max_timelimit');
// Set up message body here
$ident = @unserialize($GLOBALS['prefs']-
>getValue('identities'));
foreach ($ident as $key => $val) {
$tmp = sprintf("Identity Sig %d -- (%s):\n\n%s
\n\n",$key,$val['id'],$val['signature']);
$ident_dump = $ident_dump . $tmp;
}
$confirm = @unserialize($GLOBALS['prefs']-
>getValue('confirm_email'));
$confirm_dump = var_export($confirm,true);
$body = sprintf("We have detected a user that has
exceeded the threshold for number of messages sent within a 24 hour
period.\nThis could be a legitimate user se
nding a lot of mail, but it could also be a compromised account
sending spam.\nMost of the time the spammers stuff the spam text into
user signatures for their own convenience s
o that's the\nfirst place to look.\n\nThe account information follows
below:\n\n\nUser ID: %s\n%s\n\nIdentities Dump:\n================\n\n
%s\n\nSometimes you get really weird
things going on with these guys stuffing spam text into\nthe
confirmation email field. If there's anything there it should appear
below.\n\nConfirm_email dump:\n===============
===\n\n%s",$user, $lastlogin,$ident_dump,$confirm_dump);
require_once 'Horde/MIME/Mail.php';
$subject = "Message Limit Exceeded for user $user";
$email = $GLOBALS['conf']['problems']['email'];
$mail = new MIME_Mail(_("[Horde Spammer Alert]") . '
' . $subject,
$body, $email, $email,
NLS::getCharset());
$mail->addHeader('Sender', 'horde-alert@' .
$conf['problems']['maildomain']);
$mail_driver = $conf['mailer']['type'];
$mail_params = $conf['mailer']['params'];
$sent = $mail->send($mail_driver, $mail_params);
Horde::logMessage(
sprintf("%s Message sent to %s from %s",
$_SERVER['REMOTE_ADDR'],
preg_replace('/^.*<([^>]+)>.*$/', '$1',
$email),
preg_replace('/^.*<([^>]+)>.*$/', '$1',
$email)),
__FILE__, __LINE__, PEAR_LOG_INFO);
}
$message = @htmlspecialchars(sprintf(_("You are not allowed
to send messages to more than %d recipients within %d hours. This
attempt has been logged and administrators
notified."), $timelimit, $GLOBALS['conf']['sentmail']['params']
['limit_period']), ENT_COMPAT, NLS::getCharset());
return $message;
}
}
More information about the horde
mailing list