Wednesday, July 20, 2016

HowTo: Configure Exim to scan zip attachments for malicious files

This post provides a quick way of configuring zip attachment scanning to Exim. I've drawn this example from a number of questions across the web and hopefully enhanced the experience by sharpening up the scripting and explaining in more detail what is happening. 

I'd intended today to cleave this information into the Making a Mailserver (Part 5) - Wonderful Spam part of my series on setting up a personal mailserver. However it seemed better to split this howto out as a separate entity to avoid confusion and lessen the difficulty of an already complex series.

We will only scan the contents of the zip file and look at file extensions. We won't extract files and scan the files in any way. Extracting and scanning for filetypes or passing through an anti-virus application is a better way of identifying malicious files. Scanning files is a CPU intensive activity and fraught with new complications such as whether your anti-virus application just introduced a new attack vector into your environment, I'm looking at you, Symantec.

The reality is that mass email Malware (not Spear Phishing for example) relies on the fact that people blindly double-click on the file they received, rather than following complicated manoeuvres to rename or open a file according to the attacker's in-message instructions. In that light, simply checking the extensions within a zip file is good enough for me.

Dropping emails with files that are not zipped

This is easily customised with Exim's ACLs.

deny message = Please don't email me attachments 
 demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url:wsf:docm:hta:jse
Mind out for the line wrapping above, that should just be two lines with "deny message ..." and "demime ..." as the start of each line. It should be obvious to you how to add or remove extensions from demime.

This is a hard drop. The sender is told to go away, rather than to try again later.

Each demime entry is the file extension of a file attachment. Notice that I have not put zip, tar and tgz in there. Zip files we check next.

Zip files are still a normal part of day to day email, we can't just drop them. Dmarc xml for example is sent as a zip attachment.

Dropping emails with zipfiles that contain malicious attachments

Again, we are in the check_data ACL.

deny message = Please don't email me attachments
     log_message = DENY: zip with blocked content
     demime      = zip
     condition   = ${run{/etc/exim4/ $message_id}{0}{1}}
Mind out for line wrapping, this is a four line stanza, the last line is the "condition" line.

Again, this is a hard drop. The sender is told to go away, rather than to try again later. The log_message is what you will see in the /var/log/exim4/rejectlog. "demime" looks for an attachment with the ".zip" extension and triggers the rule which fires the "condition".

The "condition" runs a shell script that must return either 0 or 1. "0" means no problem while "1" triggers the "deny".

The script itself you can download from my git location here. Verify that logger, grep, unzip and ls are installed and that the path to them has been correctly set in the script according to your system. You can easily add or remove file extensions in that script.

You might notice that I drop when a zip file is seen in a zip file. That's an overly cautious approach, but I see no genuine reason for that to occur. It certainly could occur, if someone zips you up a pile of files that also includes a zip archive. You might want to remove that from the script or even extract and scan the zip in the zip, it's easily done and it's your call.


I recommend initially to tail the /var/log/exim4/rejectlog file and watch for messages being dropped. Look at the "rejected after DATA" information, this is where the log_message output is appended.

Check daily the messages that are being dropped, I recommend a grep such as:
# grep -E 'DATA|X-Spam-Score|Subject:|To:' /var/log/exim4/rejectlog

If something goes wrong in your shell script, it will exit with a non zero value and trigger the Exim ACL deny. Be careful to check that the script runs cleanly.

Temporarily uncomment the "#$cmd_logger" messages and watch your syslog (normally /var/log/syslog) for the pass and fail messages. The logger messages give you more detail on what and why something was denied. If you have systemd, then the "service exim4 status" command will give you a recent history of messages that Exim wrote to syslog.


To date I've never received Malware delivered in ".tar" or ".tgz" files. When that day comes, I am going to write new deny rules to inspect the contents just as I do with ".zip". I'll probably blog about that here!

No comments:

Post a Comment