Consulting djbware Publications

7. Malware Protection

We consider the following types of malware:

  1. Infected mails with virii and trojan horses targeting the operating system of the MDA, the MUA, or perhaps the MTA. However, most likely the MUA running on top of the Windows (TM) Operating System.
  2. Advanced Persistent Threat (APT) malware targeting the specific user to react upon receiving and reading the mail.
  3. Spam mails, also known as Unsolicited Commercial E-Mails UCE, being distributed deliberately for commercial or fraud reasons and wide-spread targeting unspecified.

What can we do about it?

Virus protection is actually .... almost impossible. Spam protection ist at least difficult and may lead to unwanted results. There exist two scenarios:

A virus may originate from

  1. a (untrusted) host in the Internet
  2. a trusted sender (host of originating mail address).

Beware of the sender ...

Spam - on the other side - originates mostly from unknown senders (MTA). Thus, there is a good chance to at least control the level of finally accepted spam mails such, neither the MTA nor the final recipient is bothered to much.

Email forgery ...

qmail-smtpd provides some methods to deal with email forgery. Email forgery means, that the purported sender uses an identity (given by the 'Mail From:' SMTP envelope variable or perhaps the authenticated user) is faked, thus does not represent the 'original' sender.

Emails can be easily forged. Most MUAs or MDAs are not able to 'understand' forged emails. Even worse: Some MUAs don't require to insist on coherent sending information. Thus, the recipient can not judge the quality of the received identity.

However, lets at first make some abbreviations and usual terms clear:


Quick links:

7.1 Delivery pipeline to protect from malware

The methods to protect against malware can be categorized:

With qmail-smtpd joined by typically

  1. sslserver and
  2. rblsmtpd and now in addition with
  3. qmail-postgrey (using a Postgrey daemon)

you can setup a 'malware protection pipeline' which is able to qualify mail/malware at the earliest step in the reception process. Here, you find the 'big picture' including all the possible steps:

Figure: qmail-smtpd's mail qualification pipeline (available as PDF.)

As one can see, there exist essentialy two checklines:

  1. The numbers 1 to 6 denote qualification checks on the sender and potentially for the recipient as well. The first steps are carried out by sslserver and rblsmtpd; in particular considering Greetdelay.
  2. The letters a, b and c are a defense line against the content of the mail. Here, we have:
    • Internal: The WARLORD extension.
    • Semi-internal: The Qmail High Performance Scanner Interface QHPSI.
    • External: The 'standard' Qmail QUEUE-EXTRA mechanism.

7.1.1 Mailware mail prevention

The early detection of potential malware senders is the clue to protect users and the email system itself, since virus mail detection is (apart from WARLORD) resource intensive. Thus the following steps can be applied:

  1. Check, if the sending MTA is properly listed in the DNS.
  2. Is the sending MTA able to cope with Greetdelay?
  3. Does a RBL signature exist for the sending IP address of the MTA?
  4. Is the HELLO/EHLO greeting of the MTA valid?
  5. Can the Mail From: address/domain found in the DNS?
  6. Is there and existing SPF record available to point to forgery?
  7. Is the recpient address valid (Recipients extension)?
  8. Can the sending client cope with Greylisting?
  9. What does eventually SpamAssassin say?

As we can see from the previous picture, the Q/A's are provided in different modules. The earlier a (potential negative) answer is given, the less resources are required. In the following sections, we discuss the methods which are inherent to s/qmail and in partcular qmail-smtpd.

7.1.2 Virus mail detection

s/qmail and in particular qmail-smtpd includes my WARLORD extension, which is a much robuster and efficient filter for BASE64 encoded MIME attachments and bundled with the Qmail High Performance Scanner Interface (QHPSI):

  1. BASE64 encoded MIME attachments are detected and can be filtered accordingly to an easily extendable badmimetypes file.
  2. Within the BASE64 encoded MIME attachments so-called specific loader assignments (ie. for Windows OS) can be detected and messages - containing these suspicious badloadertypes patterns - are rejected.
  3. Additional and optional on-the-fly scanning of emails through the QHPSI.
  4. Initial badmimetype or badloadertype flagged messages are not subject of the QHPSI.
  5. Employing the environment variable BASE64, QHPSI is advised to by-pass virus scanning if no BASE64 encoded attachment is found.

In case a badmimetype or badloadertype filter condition is met or a virus is detected, qmail-smtpd sends a SMTP 554 reply to the sender "554 sorry, invalid message content (#5.3.2)". Populating the REPLY554 environment variable, allows to include additional information (typically an URL), which can be used to deal with potential false-positives.

The 'traditional' QUEUE-EXTRA mechanism allows s/qmail to plug-in any other other Spam or virus scanner, for instance:

... and probably many others (like AMaViS).

7.2 The BADMIMETYPE filter

The badmimetype filter becomes active if

  • the environment variable BADMIMETYPE="" is set
  • and the control file badmimetypes is populated and readable by qmail-smtpd.
  • Reversely, if BADMIMETYPE="-" is supplied, the check is disabled. This is useful for particular hosts as provided within rules.smtpd.tcp.cdb.
  • The badmimetypes check can be conditionally disabled for RELAYCLIENTS (eg. once authenticated), in case BADMIMETYPE="+" is set. Thus here, the badmimetypes check is only performed in a none-RELAYCLIENT case (standard incoming SMTP traffic). Unlike the "-" flag, this can be used as a global setting.
    Note: Setting BADMIMETYPE="+" without a cdb is equivalent to BADMIMETYPE="!" for none-RELAYCLIENTS.
  • 7.2.1 Control file badmimetypes and badmimetypes.cdb

    The control file control/badmimetypes.cdb is populated by the additional program qmail-badmimetypes which takes the input of control/badmimetypes. New MIME signatures can be added/removed on-the-fly. Bad MIME Type signatures have to have the length of at least 9 significant characters.

    The currently included MIME signatures are:

    TVqQAAMAA TVpQAAIAA TVpAALQAc TVpyAXkAX TVrmAU4AA TVrhARwAk TVoFAQUAA TVoAAAQAA TVoIARMAA TVouARsAA TVrQAT8AA # *.zip # UEsDBAkAA # *.z (gnu-zip) # H4sIADWWb # double Base 64 Windows Executable VFZxUUFBT # triple Base 64 Windows Executable VkZaeFVVR # Pif File TVoAAAEAA # Bagle Virus ZGltIGZpb

    Adding new badmimetypes is simple:

    1. Send an E-Mail to a Unix account with corresponding attachment (i.e. *.zip).
    2. Use an editor to view the E-Mail and spot the corresponding BASE64 encoded content-type.
    3. Take the first nine significant characters (for type "zip" its "UEsDBAkAA") and include them into control/badmimetypes.
    4. Run qmail-badmimetypes .

    Comments (starting with "#") are allowed in badmimetypes; the length of the signature will be truncated to nine characters.

    7.3 The BADLOADERTYPE-Filter

    The badloadertype filter becomes active if

    The BADLOADERTYPE mechanism deals in particular with "transport stealth" worms, ie. UPX encoded Windows executables.

    7.3.1 Control file badloadertypes and badloadertypes.cdb

    badloadertypes.cdb is populated by the additional program qmail-badloadertypes which takes the input of control/badloadertypes The badloadertype mechanism looks for five significant strings in the BASE64 encoded data-stream which is matched against an entry in control/badloadertypes.cdb. badloadertype signatures can be added/removed on-the-fly employing qmail-badloadertypes.

    The currently included Windows OS badloadertype signatures are:

    Mi5kb MzIuZ MyLmR MyLkR

    Comments (starting with "#") are allowed in badloadertypes; the length of the signature will be truncated to five characters.

    Caution: Unlike the badmimetype, the badloadertype signatures are placed anywhere in the BASE64 encoded datastream and are difficult to find out. In order to make the search efficient, a common character has to be providen in the environment variable BADLOADERTYPE. The provided pattern look basically for a string like "32.dll" as a subpart of "Kernel32.dll" which is an indication for an executable for the Windows OS. However, there is a small chance for false positives. Some - lets say - Word document attached as BASE64 MIME part in the message containing the buzz words "kernel32.dll" might become flagged and finally rejected as well.

    7.4 Employing an AV Scanner with QHPSI

    Unlike all other AV Scanners currently in use for Qmail, with Qmail High Performance Scanner Interface (QHPSI) there is no need for any other umbrella program, neither qmail-scanner, AMAViS, qscanq or whatsoever. Further, no additional MIME analyzing program like reformime, metamail, or ripmime is required. Even better, no "staging" area for temporary files are needed, except the one, the AV Scanners requires for itself.

    Today's AV Scanners - and in particular Clam AV - are able to read the BASE64 encoded message and eventually dig out the files in archives, ie. in zip format. In order to use an AV Scanner with QHPSI, the AV Scanner has to have the following qualifications:

    The QHPSI allows to use the following environment variables:

    The AV Scanner is directly called in the start scripts of Qmail (i.e. the run script for qmail-smtpd) or by means of tcpserver or sslserver's capabilities. Here is a typical example, how to customize QHPSI together with Clam AV (clamd/clamdscan) for a rules.smptd.tcp control file:

    ... allow,QHPSI='clamdscan',QHPSIARG1='--disable-summary'

    Comments:

    Note:

    #!/bin/sh export QHPSI='clamdscan' export QHPSIARG1='--disable-summary' exec /var/qmail/bin/qmail-queue

    The quality of virus scanning of ClamAV is questionable. Currently, ClamAV's version is 0.99.2 (January, 2017). It seems the development is stalled somehow. Virus detection - regarding new virii - is bad.

    7.4.1 QHPSI SMTP Reply messages

    Results:

    7.4.2 QHPSI logging

    Here is a sample of Clam AV without and with the argument "--disable-summary":

    @... tcpserver: pid 49943 from 192.168.192.11 @... tcpserver: ok 49943 qmailer.fehnet.de:192.168.192.2:25 arkon.fehnet.de:192.168.192.11::1074 @... /var/qmail/queue/mess/4/89439: Worm.Klez.H FOUND @... @... ----------- SCAN SUMMARY ----------- @... Infected files: 1 @... Time: 0.099 sec (0 m 0 s) @ Reject::DATA::Virus_Infected: S:192.168.192.11:arkon.fehnet.de H:mail.fehnet.de F:me T:erwin 'clamdscan'

    Note: Even in case no virus is detected, the "SCAN SUMMARY" is provided.

    @... tcpserver: pid 49989 from 192.168.192.11 @... tcpserver: ok 49989 qmailer.fehnet.de:192.168.192.2:25 arkon.fehnet.de:192.168.192.11::1077 @... /var/qmail/queue/mess/4/89543: Worm.Klez.H FOUND @ Reject::DATA::Virus_Infected: S:192.168.192.11:arkon.fehnet.de H:mail.fehnet.de F:me T:erwin 'clamdscan' @... tcpserver: end 49989 status 256

    Attention:

    Note: As with this writing, clamav 0.8x is broken, since it writes all logs to STDOUT instead of STDERR; thus no scanning messages will appear in the qmail-smtpd log.

    7.4.3 QHPSI performance improvements for Virus Scanning

    The badmimtypes and badloadertypes mechanism provides a wire-speed filtering of incoming emails. However, typically all not-filtered emails are subject of the AV Scannner as defined via the QHPSI. Almost all worms and virii are transported as BASE64 encoded attachments (except some trojans, encapsulated as HTML files). By means of the environment variable

    one can advice QHPSI to scan only those emails which contain a BASE64 encoded attachment.

    Calling an AV-scanner is resource intensive. On the one hand, it is impossible to include a virus in 'small' messages (see SQL-Slammer); on the other hand, it is unlikely, that a 'large' email is used to transport a virus; since this is not efficient.

    QHPSI can be advised to invoke the virus scanner only under the following conditions:

    Note: Phishing emails might be small. Depending on your AV scanner, phishing mails may be detected.

    7.5 Spam Prevention

    While classical spam prevention is closely connected understand and do an interpretation of the content of the email message, the much more effective and efficient mechanism is to recognize and deal with the sending conditions of spam mails:

    1. Spam (and virus mails) are send from bot-net computers; however this is less frequent now (2021).
    2. Some spam mails are send via misconfigured MTAs (open relays).
    3. Some spam mails are send over 'legitimate' MTAs.

    Once, a handle regarding sending from bot-nets is given, control can be re-established. Two means are used for this purpose:

    Both methods work equally well; but both have their pros and cons. Using rblsmtpd Greetdelay is supported and works incredible well; without the need to maintain a state table for SMTP connections.

    7.5.1 Relay-Black-Lists (RBL) (rblsmtpd)

    rblsmtpd is typically invoked before qmail-smtpd and one or several Relay-Blacklists (RBL) or even Anti-Relay-Blacklists can be looked up. Please read rblsmtpd for more details how to set up.

    7.5.2 X-RBL-Info Header (rblsmtpd)

    Instead of rejecting emails on behalf of a bad RBL repudiation, it is possible to include received information in the received email's header for further filtering. Now, rblsmtpd has to be setup in interrogation mode by means of the option -i. The provided environment variable RBLSMTPD is now in turn filled with the evaluated RBL lookup information. qmail-smtpd will include this now in the email's header:

    Received: (qmail 9477 invoked from network); 7 Feb 2013 03:39:16 -0000 Received: from 79-101-71-86.dynamic.isp.telekom.rs (79.101.71.86) by mail.fehcom.net with ESMTP; 7 Feb 2013 03:39:16 -0000 X-Rbl-Info: http://www.spamhaus.org/query/bl?ip=79.101.71.86

    This information can be used by a MUA/LDA to filter the mail.

    Note: Currently only ucspi-tcp6 supports this with its rblsmtpd program invoked in interrogation mode.

    7.5.3 Greetdelay (rblsmtpd)

    Greetdelay is the preferred method to reduce Malware, spam, and email forgery. Over the last decade, it has not dropped in efficiency. Unlike other means, it tackles the source of the those unwanted email: the bot-nets and infected PCs (or today: even IoT devices).

    The figure below originates from 2007 and shows a substantial reduction of ill-legitimated emails and also infected mails:

    Figure: qmail-smtpd's Greetdelay effectiveness [Greedelay@GUUG FFG 2007].

    The Greetdelay option is now part of rblsmtpd and is typically invoked thru tcpserver's or sslserver's cdb per host. Typically, one would use:

    ... =:allow,GREETDELAY='60' :deny

    7.6 Greylisting in qmail-smtpd

    In s/qmail 4.1 the module qmail-postgrey available and included as opt-in for qmail-smtpd. Thus, we need to do the following:

    1. Setting up a Greylisting daemon.
    2. Calling qmail-postgrey and instructing it to communicate with the daemon.

    7.6.1 Setting up the Postgrey daemon

    qmail-postgrey is compatible with David Schweikert's Postgrey daemon, which is commonly used for Postfix as well, using its policy server.

    Postgrey depends on PERL and the BerkeleyDB, but there exist preconfigured packages to be easy installable on different Unix OS.

    Next we have to customize Postgrey. Here, I use the standard Daemontools run script to fire up the service:

    #!/bin/sh HOST_IP="127.0.0.1" HOST_PORT="60000" PIDFILE_DIR="/var/qmail/etc/" WHITELIST_CLIENTS="/var/qmail/etc/whitelist_clients" WHITELIST_RECIPIENTS="/var/qmail/etc/whitelist_recipients" touch $WHITELIST_CLIENTS touch $WHITELIST_RECIPIENTS mkdir -p /var/spool/postfix/postgrey chown postgrey /var/spool/postfix/postgrey chmod +s /var/spool/postfix/postgrey DBDIR_PATH="/var/qmail/etc/" POSTGREY_DIR="/var/qmail/bin" # Assuming postgrey is in the $PATH exec 2>&1 exec ${POSTGREY_DIR}/postgrey --inet="$HOST_IP:$HOST_PORT" \\ --whitelist-clients="$WHITELIST_CLIENTS" \\ --whitelist-recipients="$WHITELIST_RECIPIENTS" \\ --dbdir="$DBDIR_PATH" \\ --pidfile="$PIDFILE_DIR"

    Of course, Postgrey uses Postfix' conventions, but as seen above, can be easily adjusted to the s/qmail environment.

    It should be noted, that particular Whitelist Clients and Whitelist Recipients can be specified, but using sslserver's CDB the need is pretty much close to zero.

    The implementation of the Postgrey daemon includes housekeeping procedures and doesn't need additional efforts. In practice, the service runs reliably, given my small environment.

    7.6.2 s/qmail's qmail-postgrey

    The qmail-postgrey client included in s/qmail follows the (not well defined) Postgrey API and talks natively to the Postgrey server.

    There are two things, which need to be considered:

    1. qmail-postgrey needs to be called.
    2. qmail-postgrey needs to be customized to contact the Postgrey server.

    This is actually done in one step using the environment variable POSTGREY sslserver's CDB providing a connection IP address and the port (separated by a semi-colon!), the servers listens to:

    =:allow,POSTGREY="127.0.0.1;60000"

    Here, we call qmail-postgrey for any unspecified connections from the CDB. Alternatively, you can define POSTGREY als exported variable in your run script. In order to avoid qmail-postgrey to become called, specify on individual connections POSTGREY="-". You can of course alternatively use an IPv6 address (even ::1, or fe80::1%eth0;59999) to setup the service and some other arbitrary port.

    Note: Postgrey is in-effective for authenticated connections like Submission or any other authenticated SMTP connections.

    7.7 Preventing email forgery

    Email forgery, thus using forged or special crafted SMTP Return-Path (and of course email header) addresses is quite common. Therefore, mechanisms like RMX, SPF, DKIM, DMARC have been invented which work more or less well; however since those mechanisms are not mandatory for SMTP traffic (neither generating nor evaluating the required) information, those can be considered as add-on.

    Two mechanisms are used in the wild:

    7.7.1 SPF query

    Details about the SPF query and setup are given here.

    7.7.2 'Mail From: Address Verification' (MAV)

    The abuse or SMTP Return-Path addresses within s/qmail's administrative domain can be omitted using the 'Mail From: Address Verification' (MAV) mechanism which works for email received by qmail-smtpd from a MUA belonging to you administrative domain, considered to be RELAYCLIENTS:

    Upon reception of RELAYCLIENT email, a href="./man/qmail-smtpd.html">qmail-smtpd can be instructed to do the following:

    Thus, MAV binds the IP/FQDN of the MUA or the provided user information to a valid SMTP Mail From: envelope address. In order to invoke MAV for qmail-smtpd, the environment variable LOCALMFCHECK needs to be defined. The following cases can be considered:

    1. LOCALMFCHECK='!': The control file mailfromrules.cdb is evaluated and the MAV is facilitated employing the environment variables TCP(6)REMOTEINFO, TCP(6)REMOTIP, or TCP(6)REMOTEHOST as key for the comparison.
    2. LOCALMFCHECK='=': TCP(6)REMOTEINFO (i.e. set by Auth) has to match the 'Mail From:' envelope address (case insensitive).
    3. LOCALMFCHECK='?': The email address embedded in the DN of a X.509 client certificate is used and compared against the 'Mail From:' envelope address.
    4. LOCALMFCHCEK='example.com': The domain part of the 'Mail From:' envelope address is compared against that given value.

    In order to set-up specific bindings, the file mailfromrules needs to be populated. It follows roughly the conventions of the tcpserver' cdb:

    jsmith@virtualdomain.com&john.smith@virtualdomain.com joe@18.23.0.32&joe@example.com 18.23&@example.com =.heaven.mil&God@heaven.mil,st.peter@heaven.mil,-angles@heaven.mil fe80:&user@myhost.local 2001::feh:abc9:&me@fehnet.com

    The file mailfromrules needs to converted into a binary format prior of usage. This can be accomplished with qmail-mfrules. Changes can be realized while qmail-smtpd is running and are in effect on-the-fly.

    If the MAV match fails, the SMTP client receives the generic message

    553 sorry, invalid sender address specified ... (#5.7.1)

    is issued and email sending is prohibited. The environment variable REPLYMAV can be used to include additional custom information (instead of the dots).

    7.7.3 DNS qualification of HELO and Return-Path in SMTP Envelope

    The HELO/EHLO greeting of the sending's MTA as well as the domain part of the provided 'Return-Path' (aka 'Mail From:' address) to include a resolvable FQDN. qmail-smtpd is able to perform a DNS lookup on both SMTP envelope informations (see 3.5 qmail-smtpd).

    Together, with the SPF settings, the following environment variables assure a particular DNS qualification, if provided in the rules.smtpd.tcp file and converted to a cdb:

    ... =:allow,MFDNSCHECK="",HELOCHECK='A',SPF='3' :deny

    The :deny rule in rules.smtpd.tcp requires, that tcpserver or sslserver is invoked with the options '-Rp' in order to do DNS lookup for the connection IP address in the the DNS branch ip6.arpa or in-addr.arpa and it validation (paranoid setting) against the forwarding branch.

    7.8 Interrogating SMTP envelope and connection variables

    For special purposes, it might be necessary to have knowledge of the SMTP envelope information while qmail-smtpd is running and it puts the following informations into the environment - as soon as available:

    The provided qmail-queue.scan script makes use of these variables. You may also populate the DELIVERTO environment variable -- read by qmail-smtpd -- to include additional recipients.

    In case of the SSL/TLS session further environment variables a la mod_ssl are available.

    7.9 Qmail QUEUE_EXTRA

    Bruce Guenter's Qmail QUEUE_EXTRA patch has almost the rank of a recommended patch, because its used by many Qmail extensions like the Qmail-Scanner and qmail-qfilter.

    The actual use is controlled via the content of environment variable "QMAILQUEUE", which usually set in tcpserver or sslserver's cdb; ie. rules.smtpd.tcp or globally defined in the qmail-smtpd's run script. A typical use is:

    12.34.56:allow,RELAYCLIENT="" :allow,QMAILQUEUE="bin/qmail-qfilter"

    which advices qmail-smtpd to use the executable qmail-qfilter as first stage queueing program instead of qmail-queue itself.

    In order to reject during the SMTP DATA phase, vanilla qmail requires that the qmail-queue replacement returns RC=31.
    However, s/qmail enhances this mechanism with the following additional return codes:

    Those return codes can be extensibly used in a qmail-queue wrapper-script (see below).

    Note: The QUEUE_EXTRA patch is not applied against qmail-smtpd but rather against the module qmail.c itself, since it is just an extension to the general queue call-mechanism.

    7.9.1 qmail-queue.scan Replacement

    The qmail-queue.scan script can be used by the QUEUE_EXTRA mechanism to allow a per (recipient) domain

    For high volume/high performance scanning, the incoming message is copied to a tmp directory which typically should be raised on a ramdisk. All scanning actions can be realized now in memory which significantly reduces disk I/0.

    You can define individual SpamAssassin detection thresholds per domain using the additional control file:

    Here, you include the recipients's domains, followed by a colon, and the spam threshold for this domain:

    example.com:10 yourdomain.com:8

    qmail-smtpd is able to understand the (tagged) messages identified as infected or as spam and will issue a useful SMTP return code.