Page 1 of 2

Identify compromised accounts

Posted: Mon Jun 24, 2013 4:23 pm
by MobiusNZ
Hi,
We've had a customer who's zimbra server has been sending out spam. We eventually found it was an account that had its password guessed/compromised and were able to fix it by changing the password.
However, finding the account was trickier than I would've expected. It was sending via authenticated smtp, but using a different FROM address.
Is there any easy way to identify which authenticated account is used to send a particular email?

Identify compromised accounts

Posted: Mon Jun 24, 2013 6:15 pm
by quanah
The account sending an email is logged in /var/log/zimbra.log:
For example, on ZCS8.0.4:



Jun 24 11:58:06 edge01-zcs postfix/smtps/smtpd[30581]: 72E91EB2: client=FQDN[IP], sasl_method=PLAIN, sasl_username=user@domain


Identify compromised accounts

Posted: Mon Jun 24, 2013 6:17 pm
by quanah
There some additional information logged when persistent authenticated connections are used as well, but I don't have that in front of me atm.

Identify compromised accounts

Posted: Thu Jun 27, 2013 5:40 pm
by 7310pyperdown
I'm giving this script i wrote this am a try. The system needs to be able to protect itself from obvious abuse. More than 5 authenticated sessions in a minute is likely evidence of abuse. So once identified we lock the account. Since they most likely fell for a phishing mail and should know better I'm not real concerned about sending them notice. they can call me when they can't get into their account. No, I'm not bitter or anything.
UPDATE: I added a pipe through sed to remove multiple spaces from the log entries as it was throwing off the awk column numbers, as well as only modifying active accounts.

#!/bin/bash

# checks log file and gets a count of authentications sent per minute, per user

# and if the count exceeds the maxmails value the user's account is locked.
logfile="/var/log/zimbra.log"

maxmails="10"

mydomain="example.com"

support="techsupport@$mydomain"

accounts="/tmp/active_accounts"
su zimbra -c "/opt/zimbra/bin/zmaccts" | grep "@" | grep active | awk '{print $1}' > $accounts
zgrep -i "auth ok" $logfile | sed 's/ / /g' | awk -F"[ :]" '{print $3":"$4,$11;}' | uniq -c | sort -n |

while read line

do

count=`echo ${line} | cut -d' ' -f 1`

userid=`echo ${line} | cut -d' ' -f 3`

timestamp=`echo ${line} | cut -d' ' -f 2`

active=`grep "$userid@$mydomain" $accounts`
if [ "$count" -gt "$maxmails" ] && [ "$active" == "$userid@$mydomain" ]; then

echo "Maximum email rate exceeded, $userid@$mydomain will be locked"

su zimbra -c "/opt/zimbra/bin/zmprov ma $userid@$mydomain zimbraAccountStatus locked"

subject="$userid account locked due to excessive connections"

# Email text/message

message="/tmp/emailmessage.txt"

echo "$userid account has been locked as there were $count connections made at"> $message

echo "$timestamp. Please have the user change their password, and check for phishing" >>$message

echo "emails if possible." >>$message

# send an email using /bin/mail

/usr/bin/mail -s "$subject" "$support"
rm -f $message
#update list of active accounts

su zimbra -c "/opt/zimbra/bin/zmaccts" | grep "@" | grep active | awk '{print $1}' > $accounts

fi

done
rm -f $accounts


Identify compromised accounts

Posted: Tue Jul 02, 2013 4:04 pm
by MobiusNZ
Thanks guys, that helps a lot. That script looks especially useful.
Cheers, Al

Identify compromised accounts

Posted: Mon Jul 08, 2013 6:42 pm
by 7310pyperdown
I modded the script to only lock active accounts. runs a bit faster. Otherwise there tend to be a lot of hits and redundant notification emails, and the zmprov ma command is pretty slooooooow.

Identify compromised accounts

Posted: Wed Aug 07, 2013 3:32 pm
by drwho18
The script posted above is a good idea, however it doesn't really stop an in process attack (at least on my Zimbra setup). It checks for "auth ok" of which I tend to see a few, the spammer appears to hold smtp open and I see each send tagged with a "sasl_username" in the logs, checking the message ID out I see it was a new message with fresh recipients. I have modded the script to check for sasl_username, as I think that is more relevant to trip off a spam notice, however locking the account does not stop said account from continuing to spam through the server. If it tries to come in from a new IP it will try to reauth and fail fine, but I believe it will continue to function untl the SMTP session is stopped, by which time a lot of damage can be done to a mail servers reputation. Any ideas how to stop this, or reduce the max SMTP session time or something would be the way to go. I wish every sasl_username request was an actual auth attemp, maybe saslauthd is caching by default on zimbra?

Identify compromised accounts

Posted: Wed Aug 07, 2013 3:43 pm
by quanah
This has nothing to do with sasl auth attempts, but more funky logging. What the spammers do is create a persistent SMTP session. However, postfix logs that sasl auth is OK every time they send a message, even though no *new* sasl authentication is happening. I.e., this is kind of a bug in postfix logging. The only way to close their connection is to bounce postfix.

Identify compromised accounts

Posted: Wed Aug 07, 2013 6:37 pm
by drwho18
Ok, well I kind of feared that. Does it need to be a complete postfix restart, or will a reload do the trick?

Identify compromised accounts

Posted: Wed Sep 11, 2013 3:53 am
by Klug
I rewrote the above script to search for sasl_username in the log and lock according to it.

#!/bin/bash

# checks log file and gets a count of authentications sent per minute, per user

# and if the count exceeds the maxmails value the user's account is locked.
logfile="/var/log/zimbra.log"

maxmails="5"

mydomain="domain.tld"

support="support@$mydomain"

accounts="/tmp/active_accounts"
su - zimbra -c "/opt/zimbra/bin/zmaccts" | grep "@" | grep active | awk '{print $1}' > $accounts
zgrep -i "sasl_method=LOGIN, sasl_username" $logfile | sed 's/ / /g' | awk -F"[ :]" '{print $3":"$4,$13;}' | sed 's/sasl_username=//g' | sort | uniq -c | sort -n |

while read line

do

count=`echo ${line} | cut -d' ' -f 1`

userid=`echo ${line} | cut -d' ' -f 3`

timestamp=`echo ${line} | cut -d' ' -f 2`

active=`grep "$userid@$mydomain" $accounts`
if [ "$count" -gt "$maxmails" ] && [ "$active" == "$userid@$mydomain" ]; then

echo "Maximum email rate exceeded, $userid@$mydomain will be locked"

#su - zimbra -c "/opt/zimbra/bin/zmprov ma $userid@$mydomain zimbraAccountStatus locked"

subject="$userid account locked due to excessive connections"

# Email text/message

message="/tmp/emailmessage.txt"

echo "$userid account has been locked as there were $count connections made at"> $message

echo "$timestamp. Please have the user change their password, and check for phishing" >>$message

echo "emails if possible." >>$message# send an email using /bin/mail

/bin/mail -s "$subject" "$support"
rm -f $message
#update list of active accounts

su - zimbra -c "/opt/zimbra/bin/zmaccts" | grep "@" | grep active | awk '{print $1}' > $accounts

fi

done
rm -f $accounts

postfix restart