Blocking Windows Worms at the Server with Procmail on a VPS Scott Wiersdorf Wed Sep 25 13:06:12 MDT 2002 Updated: Fri Sep 19 09:43:59 MDT 2003 Author's Note: I have not maintained this file for at least 6 months; this means that I have found better (or at least, less labor intensive for me) alternatives for blocking email with malicious content (I currently use Clam Anti-Virus). The following links point to sites that actively maintain their lists or heuristics. None of the below are true "anti-virus" in the sense that they scan mime parts for virus- or worm-specific contents; rather, they scan mail for recognizably unsafe constructs (generically) and block them. My own humble list of worm recipes (the bulk of this document) may serve as a starting point for those new to procmail, but for more complete anti-worm protection, the seeker is directed to Nancy McGough's list first (the other links below may also be found on her site). **************************************************** For other trusted heuristics, please see some of the following: Nancy McGough's http://www.ii.com/internet/robots/procmail/qs/#viruses Dallman Ross's http://www.spamless.us/pub/procmail/virussnag John Conover's http://www.johncon.com/john/QuarantineAttachments/ Robert Allerstorfer's http://antivirus.softlabs.info/ **************************************************** Danger! Achtung! Aviso! If you are unsure about changes you make to your recipes, always put in a safety net at the top of your (first) recipe file: :0c: /var/mail/backup This will put copies of all mail in ~/var/mail/backup. You may wish to read the procmailex(5) manpage which gives an example of how to keep only the last 32 (or whatever you specify) messages. Careless procmail rules with no safety net (e.g., /dev/null has no safety net) may result in lost email messages! We are not responsible for lost or damaged mail. If you doubt the safety of these procmail recipes, do not use them. **************************************************** For VPS v1: Install procmail and the sendmail extensions: % vinstall procmail % vinstall sendmail Follow the instructions in the procmail 'filtering' man page to make procmail the local delivery agent for sendmail: % man filtering Create ~/etc/procmailrc as instructed in the filtering(5) manpage, which will be your global procmail file. All messages destined for local delivery on your server will be filtered through this recipe file. Mail just passing through your server (e.g., an alias or virtmap that points to an email account that does not reside on your server) will not be handled through these recipes. For VPS v2: Add the following line to your /etc/mail/(hostname).mc file: FEATURE(`local_procmail_lmtp')dnl MAILER(local) Then rebuild your sendmail configuration file: # make (hostname).cf That should be all. You can include this in your procmailrc file with: INCLUDERC=worms.txt ######################################################## LOGFILEOLD=$LOGFILE LOGABSTRACTOLD=$LOGABSTRACT VERBOSEOLD=$VERBOSE VERBOSE=off LOGABSTRACT=all COMSAT=no ######################################################## NL=" " WORMY=/var/log/worms LOGFILE=$WORMY.log ## anonymous .exe attachments ## this recipe comes from impsec.org's sanitizer ruleset :0 * > 20000 * H ?? !^Subject: * H ?? ^Content-Type:.*multipart/mixed; { :0 * B ?? ^Content-Disposition:.*\.exe * B ?? ^Content-Type:.*\.exe { LOG="Anonymous Executable worm${NL}" :0: $WORMY } } ## sircam ## this recipe comes from impsec.org's sanitizer ruleset :0 * > 130000 * ^Content-Type:.*multipart/mixed; { :0 * B ?? ^Content-Disposition: attachment; * B ?? ^Content-Transfer-Encoding: base64 * B ?? AAAAGgU0NhbTMyABCDTUlN|AAAAAaBTQ2FtMzIAEINNSU1F|ABkAAAABoFNDYW0zMgAQg01J { LOG="Sircam${NL}" :0: $WORMY } } ## badtrans :0 * > 40000 * < 50000 * ^Subject: Re: * 1^1 ^Content-Type:.*multipart/.*boundary="====_ABC1234567890DEF_====" * 1^1 ^Content-Type:.*multipart/.*multipart/ { :0 * B ?? ^Content-Type: audio/x-wav; * B ?? .*name=".*\.(doc|mp3|txt|zip)\.(scr|pif)" { LOG="Badtrans${NL}" :0: $WORMY } } ## goner :0 * B ?? ^Content-Type: .*(application|multipart) * B ?? name=\".*gone\.src { LOG="Goner${NL}" :0: $WORMY } ## nimda :0 * B ?? ^Content-Type: .*audio/x-wav; * B ?? name=\"readme\.exe\" { LOG="Nimda${NL}" :0: $WORMY } ## klez :0 * > 100000 * ^Content-Type:.*multipart/alternative; { :0 ## the following rule is a single line ## beginning with 135 and ending with ItE * B ?? 135AAItEjhyJRI8ci0SOGIlEjxiLRI4UiUSPFItEjhCJRI8Qi0SODIlEjwyLRI4IiUSPCItE { LOG="Klez${NL}" :0: $WORMY } } ## hybris :0 * 1^0 ^From: .*hahaha@sexyfun\.net * 1^0 B ?? ^Content-Type: application/octet-stream; name="sexy.*\.scr" { LOG="Hybris${NL}" :0: $WORMY } ## sobig :0 * > 70000 * 1^0 ^X-MailScanner: Found to be clean * B ?? ^TYg45jEaa7EKGvkUwszJYGUwjTJWkCSxN9IbQBPZPwxmHINeoyVswne23sTxda { LOG="SoBig${NL}" :0: $WORMY } ######################################################## LOGABSTRACT=$LOGABSTRACTOLD VERBOSE=$VERBOSEOLD LOGFILE=$LOGFILEOLD ######################################################## All email messages destined for delivery on your server containing certain instances of sircam, badtrans, klez, goner, nimda, and others will be saved in your servers ~/var/log/worms file (which will be created if it does not exist). You should periodically check ~/var/log/worms.log to see how many messages are being caught. If a legitimate message is trapped by accident, you can retrieve it from ~/var/log/worms. You should periodically delete or compress ~/var/log/worms and ~/var/log/worms.log. You can do this with savelogs: % vinstall savelogs ## compress % savelogs --log='/var/log/worms*' ## delete % savelogs --log='/var/log/worms*' --process=delete or from cron (every Friday at 2:05 am): 5 2 * * 5 $HOME/usr/local/bin/savelogs --log='/var/log/worms*' or compress them only if they're bigger than 20 megs: 5 2 * * 5 $HOME/usr/local/bin/savelogs --log='/var/log/worms*' --size=20000 If you're feeling (overly) confident that these recipes are working well, you may remove the trailing colon ":" from ":0B:" in each recipe and replace "/var/log/worms" with "/dev/null". This will remove the need for compressing or deleting the /var/log/worms file, but the /var/log/worms.log file will still need to be handled.