[exim] Blocking compromised accounts

Top Page
Delete this message
Reply to this message
Author: Lena
Date:  
To: exim-users
Old-Topics: Re: [exim] rewrite From header with smtp auth-ed username?
Subject: [exim] Blocking compromised accounts
> From: Jan Ingvoldstad

> In my experience, spamming through authenticated accounts are currently
> tailored to go under the radar for rate limits, typically one or two
> handfuls of messages sent every day, to 10-30 recipients, maybe less.


OK, below I try to re-implement (for Exim 4.67 or higher)
Alan Doherty's idea (from the new-spam-l.com|spammers.dontlike.us list):

> we use 3 factors for smtpa
>
> a username
> b password
> c is the envelope from one that the user has previously setup on our
> systems
>
> if they fail c the email is rejected at rcpt-to
> and the user is sent an email explaining why they are locked out of
> smtpa (their user/password still works for admin pop3/imap)
> so they can just hop over to the admin page and change their
> password to unlock the accounts smtpa, also if it was an error on
> their part they can belatedly add the 3rd party envelope-from they
> were trying
>
> this way if an account is successfully used to send spam (ie they
> use his from: as well) the torrent of bounces is ours and the users
> notification.
>
> so far its worked
> (obviously we also content filter after data, but very few hit the
> quarantine queue (if they do the user can release, but a copy is
> also flagged for admin review, so far all just bad chain-mail, that
> we educate/LART the user for)
>
> I do worry about the potential for a bot (or human herder) to take
> the credentials and use them to admin the account so each new
> envelope sender is added before the smtp send, we have yet to add an
> automated confirmation loop, its on my to-do list


I'm assuming that each user's username is full email address of the mailbox
like johndoe@???

When users are issued a password, give them also a link to a webpage such as
http://example.com/emailaddresses-explanation.html
with an explanation like this:

| You were issued a mailbox on our server and password for it.
| You are allowed to send mail from that our mailbox
| (with its email address in "From")
| using that password and that our mailbox's email address as username
| via the smtp.example.com SMTP-server, port 25 or 587.
| If you want to send mail with another email address in "From"
| using smtp.example.com and that password
| then you must at first prove that that another address also is yours.
| For that send a message from our mailbox to register@???,
| type two email addresses (of our mailbox and another mailbox,
| separated with a space) in Subject.
| A message with confirmation code will be sent to that another mailbox.
| You must send one more message to register@???
| with same two email addresses and the confirmation code
| (also separated with spaces) in Subject.
| Messages with unconfirmed email address in "From" will be rejected
| because we need to prevent spamming using stolen passwords,
| unfortunately nowadays passwords are stolen (with malware or phishing)
| too often.


In Exim spool directory (/var/spool/exim in case of FreeBSD)
create a subdirectory "regsend" with same owner and permissions as other
subdirectories there.

In Exim config:
At the beginning of config (type a random word in the SALT line):

REGISTER = register@???
EXPL = http://example.com/emailaddresses-explanation.html
EXIMBIN = /usr/local/sbin/exim
SHELL = /bin/sh
SALT = aardvark

In acl_check_data:

  discard condition = ${if forany{<, $recipients}{eqi{$item}{REGISTER}}}
        set acl_m_subj1 = ${if match{$header_Subject:}\
                                    {\N^\s*([\w.+=-]+@[\w.]+)\s\N}{$1}}
        set acl_m_subj2 = ${if match{$header_Subject:}\
                                    {\N^\s*\S+\s+([\w.+=-]+@[\w.]+)\N}{$1}}
        set acl_m_subj3 = ${if match{$header_Subject:}\
                                    {\N^\s*\S+\s+\S+\s+(\S+)\s*$\N}{$1}}
        set acl_m_hash = ${nhash_10000:${sha1:SALT,$acl_m_subj1,$acl_m_subj2}}
        authenticated = *
        condition = ${if def:acl_m_subj1}
        condition = ${if def:acl_m_subj2}
        condition = ${if !def:acl_m_subj3}
        condition = ${if eqi{$authenticated_id}{$sender_address}}
        condition = ${if eqi{$authenticated_id}{$acl_m_subj1}}
        continue = ${run{SHELL -c "\N{\N echo Subject: confirmation code; \
           echo To: $acl_m_subj2; echo; echo confirmation code: $acl_m_hash; \
           \N}\N | EXIMBIN -f REGISTER $acl_m_subj2"}}


  discard condition = ${if def:acl_m_subj1}
        condition = ${if def:acl_m_subj2}
        condition = ${if eq{$acl_m_subj3}{$acl_m_hash}}
        continue = ${run{SHELL -c "echo $acl_m_subj2 \
           >> $spool_directory/regsend/$acl_m_subj1; \
           \N{\N echo Subject: confirmed; echo; echo Now you \
           can send from $acl_m_echo2 using password for $acl_m_subj1; \
           \N}\N | EXIMBIN -f REGISTER $acl_m_subj1 $acl_m_subj2"}}


In acl_check_rcpt:        


  accept authenticated = *
        condition = ${if eqi{$sender_address}{$authenticated_id}}
        control = submission/domain=


  accept authenticated = *
        condition = ${if exists{$spool_directory/regsend/$authenticated_id}}
        condition = ${lookup{$sender_address}lsearch\
                    {$spool_directory/regsend/$authenticated_id}{1}{0}}
        control = submission/domain=


  deny  authenticated = *
        message = EXPL


The address register@??? should be redirected
(with a "redirect" router) to :blackhole: or /dev/null

Each authenticator must contain correct server_set_id line.

Please comment and test.

Lena