Re: [exim] syntactically invalid argument(s) - rejected HELO

Top Page
Delete this message
Reply to this message
Author: Tony Finch
Date:  
To: Alan J. Flavell
CC: Exim users list
Subject: Re: [exim] syntactically invalid argument(s) - rejected HELO
On Thu, 16 Dec 2004, Alan J. Flavell wrote:
>
> > or a very long HELO name
>
> Oh, you've spotted that? The addition of a recipe with
>
>              condition = ${if >{${strlen:$sender_helo_name}}{xx} {1}{0}}

>
> for some suitable value of xx is relatively recent here, but it's
> keeping out a modest amount of junk that wasn't caught by other means.
> Many of those had double-dots in them, by the way.


Yes. Our HELO checks are:

  deny
    message        = Please use your name when saying HELO (not $sender_helo_name)
  ! verify         = helo
    condition      = ${if or{{ eq{$acl_c1}{bad} } \
                             { isip{$sender_helo_name} } \
                             { eq{$sender_helo_name}{$local_part} } \
                             { match{$sender_helo_name}{\N[.][.]|.{55}\N} } \
                             { match_domain{$sender_helo_name}{+our_domains} }} }
    set acl_c1     = bad


I did some analysis of HELO names recently to inform the design effort for
CSV. There are two related signatures of stupid malware:

(1) 80 characters of random words (probably concatenated random domain
names or fragments thereof) followed by a random IP address;

(2) a load of random concatenated domain names, variable length, with no
dots between them, e.g. example.co.ukexample.com.

Both of these often have double dots, and they are both often abusively
long. However systematically generated hostnames also tend to be long so
you have to be relatively generous in the limit. We use 55 for our "too
long" limit -- everything longer is a result of the two kinds of malware
listed above.

Another limit that you can use is on the number of dots in the HELO name:
15 is a safe limit, 10 is reasonable, and anything between 5 and 10 will
hit mostly consumer addresses, but risks false positives. However with our
(currently) generous policy this overlaps too much with the 55 char limit
to be useful.

If we decided to ban consumer access addresses outright then I could
reduce these limits. At the moment we use the XBL and the RBL+ which ban a
lot of consumer IP addresses, but not all of them. A lot of more recent
malware is saying HELO with the host's DNS name, so consumer addresses are
probably worth banning, but I'd probably choose a decent DNS blacklist
rather than using tighter HELO restrictions as a heuristic for spotting
them.

You can implement another check which spots a lot of class (2) above, and
also shorter randomly generated HELO names -- things like szklfdug.com are
quite common and a clear sign of abuse. However this check has a few false
positives because people sometimes make up domain names for internal use,
e.g. company-internal.com or company.int, and these leak out in HELO
names, hence running it in warning mode. The following also uses a patch
by me to make the checks more concise; it hasn't been incorporated into
official Exim so far.

# A more complicated HELO check. If the top level domain has name servers,
# but the second and third (if present) level domains do not, reject.
# We allow missing top level servers because of private addresses, and we
# need to check both the 2LD and 3LD because some CC2LDs are part of their
# CCTLD zone rather than being delegated.

  warn
    log_message    = F=<$sender_address> RCPT=<$local_part@$domain> \
                     HELO DNS check failed for $sender_helo_name
    condition      = \
      ${if match{$sender_helo_name}{([^.]+[.])?([^.]+[.])([^.]+)\$} \
           {${lookup dnsdb {defer_never,ns=$3} \
                     {${lookup dnsdb {defer_never,ns=$2$3} \
                               {no} {${lookup dnsdb {defer_never,ns=$1$2$3} \
                                              {no} {yes} }} }} }} }


> But why do they do it?


I didn't say they were immune to stupidity :-) It's like the bare IP
address thing, another stupid and reliable malware signature. I expect a
lot of the writers of these programs are young and naive and too damn
clever to read specs.

Tony.
--
<fanf@???> <dot@???> http://dotat.at/ ${sg{\N${sg{\
N\}{([^N]*)(.)(.)(.*)}{\$1\$3\$2\$1\$3\n\$2\$3\$4\$3\n\$3\$2\$4}}\
\N}{([^N]*)(.)(.)(.*)}{\$1\$3\$2\$1\$3\n\$2\$3\$4\$3\n\$3\$2\$4}}