#!/bin/sh # Post.Office Anti-Virus Solution # Copyright by Joe Savelberg -- jmsc@euregio.net # version 0.8 -- 2004-02-11 @ 06:30 GMT # http://www.euregio.net/joe/postoffice/ # Use at own risk. Virex does delete viruses # # Install this script in your root home directory # chmod 755 to make it executable # Use chown root:wheel to execute the script as root # Install a cron job to run this script every minute # example for /etc/crontab: # */1 * * * * root ~root/viruscheck.sh > /dev/null 2>&1 # # If you are using the "daemonized" version of the script you don't # have to use a cron job to execute the script but you can still do # so to continue your anti-virus protection in order keep the system # running should the daemon ever crash. # Show your support by donating something through PayPal # https://www.paypal.com/xclick/business=jmsc%40euregio.net&item_name=Post.Office+Tools&cn=Comments+or+Suggestions&tax=0¤cy_code=USD # General Options # virexon=[yes|no] -- uses Virex command line scanner to scan files # virusliston=[yes|no] -- uses grep to check for common virus attachments taken from a virus.list file # mimeon=[yes|no] -- uses grep to scan for unwelcome MIME attachment suffixes # uuencodeon=[yes|no] -- uses grep to scan for unwelcome UUencode attachment suffixes # subjectrewrite=[yes|no] -- rewrites the subject line with a warning for .exe, .zip, .dll, .com, .shs # debugon=[yes|no] -- writes more information to the log file to see what's going on. # logroll=[yes|no] -- appends the current date to the log file thereby providing an easy log rolling facility virexon="yes" virusliston="yes" mimeon="yes" uuencodeon="yes" subjectrewrite="yes" debugon="yes" logroll="yes" # Location and name of this script virexscript="/var/root/virexscript.sh" # Location of your Virex command line scanner virexpath="/usr/local/vscanx/vscanx" virexoptions="--analyse --secure --delete --allole --ignore-links --noexpire --atime-preserve --recursive --manalyse --panalyse --unzip" # Location of your Post.Office Mailbox folder (auto-detect): # mailboxdir="/var/spool/mailbox" mailboxdir=`grep "MailboxDir" /etc/post.office.conf | cut -d "=" -f 2` # Location where you want to move messages with attachments: quarantine="/quarantine/" # Location of your virus file name list. # This list contains common attachment file names used by viruses. # Newer viruses use random attachment names and cannot be effectively # moved with this system. # A sample virus list can be found at http://www.euregio.net/joe/virus.list viruslist="/virus.list" # Maximum file size to scan -- to prevent scanning really large attachements with virex and/or munpack # Common virus file sizes are less than 350000 bytes maxfilesize="300000" # Unix "munpack" utility ((C) Copyright 1993,1994 by Carnegie Mellon University, All Rights Reserved) # the munpack binary is included in CGVirusscan: http://www.macosxunleashed.com/article.php?sid=2 # Follow the instructions in CGVirusscan where to place munpack # Use munpack to extract attachments from messages # provides better virus scanning for Virex munpackon="yes|no" munpackon="no" munpack="/usr/local/bin/munpack" # Listing of Mailboxes you would like to exclude from the scan # example: "Joe_Savelberg|FirstName_Lastname|abc*" # Uses egrep to filter out those directories. If you leave this # empty, then the script won't work correctly. You could put a # dummy/fake account into this if you want to scan all other # accounts. excludemaildir="Postmaster|SpamChecker|Administrator" # Setting up the correct paths to logs and temporary files # Normally, you don't have to change these virextime="/tmp/virex.time" scanlist="/tmp/virex.list" virexlog="/var/log/virex.log" # Limiting the script CPU time to 5 minutes ulimit -t 300 if [ "$logroll" = "yes" ] ; then virexlog="${virexlog}.`date "+%Y%m%d"`" fi if [ "$debugon" = "yes" ] ; then echo "`date` [Start] virex" >> $virexlog fi # Checking if the virex script is already running to prevent too many simultaneous executions grepproc=$(ps -ax | grep "sh $virexscript" | grep -v "grep sh $virexscript" | wc -l) if [ $grepproc -gt 2 ] then if [ "$debugon" = "yes" ] ; then echo "`date` too many virex processes: ${grepproc}" echo "`date` [End] too many virex processes: ${grepproc}" >> $virexlog fi exit fi # Setting start time of the execution startdate=`date "+%m%d%H%M.%S"` folderdepth=$(echo $mailboxdir | cut -d "=" -f 2 | tr "/" "\n" | wc -l) let folderdepth=folderdepth+4 maxfilesize=$(echo $maxfilesize) # Creating reference timestamp if necessary if [ ! -f $virextime ] then echo "`date` [Info] creating reference timestamp" >> $virexlog touch -t 0001010000 $virextime fi # Checking for new message files since last execution scanlist=`find $mailboxdir -type f -newer $virextime -print | grep "@" | egrep -v "$excludemaildir"` # Setting the time stamp to now which will be used as starting point for the next execution touch -t $startdate $virextime if [ "$debugon" = "yes" ] ; then echo "`date` [Info] Starting Anti-Virus Scan" >> $virexlog fi for i in $scanlist do echo "`date` [Info] Processing: $i" >> $virexlog filedeleted="no" filesize=$(wc -c $i | tr -s " " "-" | cut -d "-" -f 2) if [ "$debugon" = "yes" ] ; then echo "`date` [Info] File Size: $filesize" >> $virexlog fi if [ "$virexon" = "yes" ] ; then if [ $filesize -lt $maxfilesize ] then # Starting Virus scanning using Virex with or without munpack if [ "$debugon" = "yes" ] ; then echo "currently checking: $i" fi if [ "$munpackon" = "yes" ] then # Using munpack to extract the attachments to a temporary directory # If a virus is found, the original message is deleted. tmpfile=`echo $i | cut -d "/" -f $folderdepth` mkdir -p /tmp/virex/$tmpfile munout=`$munpack -C /tmp/virex/$tmpfile $i` output=`$virexpath $virexoptions /tmp/virex/${tmpfile}/*` shoulddelete=`echo "$output" | grep "Found"` if [ -n "${shoulddelete}" ] then filedeleted="yes" echo "`date` [Virex/munpack] Deleting $i" >> $virexlog echo "`date` [Virex/munpack] $shoulddelete" >> $virexlog rm $i else if [ "$debugon" = "yes" ] ; then echo "`date` [Virex/munpack] clean" >> $virexlog fi fi cd /tmp/virex/ rm -R $tmpfile #echo $output >> $virexlog else # Using vscanx directly on the message file. Can be faster than using munpack # However Virex doesn't work with some encoded attachments output=`$virexpath $virexoptions $i` shoulddelete=`echo "$output" | grep "Found"` if [ -n "${shoulddelete}" ] then filedeleted="yes" echo "`date` [Virex] Deleting $i" >> $virexlog echo "`date` [Virex] $shoulddelete" >> $virexlog else if [ "$debugon" = "yes" ] ; then echo "`date` [Virex] clean" >> $virexlog fi fi fi fi fi # Checking for know virus attachment names from $viruslist if [ "$virusliston" = "yes" ] ; then if [ "$filedeleted" = "no" ] then output=`grep -l -i -f $viruslist $i` if [ -n "${output}" ] then filedeleted="yes" mv $i $quarantine echo `date` "[Virus-List] Moved ${i} to ${quarantine}" >> $virexlog else if [ "$debugon" = "yes" ] ; then echo "`date` [Virex-List] clean" >> $virexlog fi fi fi fi # check for mime attachments names # this checks for common file name suffixes which we don't allow in # attachments because they are too dangerous. if [ "$mimeon" = "yes" ] ; then if [ "$filedeleted" = "no" ] then output=`egrep -l -i '(Content-(Disposition:\sattachment;|Type:).*|\s+)(file)?name\s*=\s*"?.*\.(lnk|bat|chm|cmd|vxd|pif|scr|hta|jse?|sh[mb]|vb[esx]|ws[fh])"?\s*' $i` if [ -n "${output}" ] then filedeleted="yes" mv $i $quarantine echo `date` "[MIME-Attach] Moved ${i} to ${quarantine}" >> $virexlog else if [ "$debugon" = "yes" ] ; then echo "`date` [MIME-Attach] clean" >> $virexlog fi fi fi fi # check for uuencoded attachments # this checks for common file name suffixes which we don't allow in # uuencoded attachments because they are too dangerous. if [ "$uuencodeon" = "yes" ] ; then if [ "$filedeleted" = "no" ] then output=`egrep -l -i 'begin [0-9]{1,4} .*\.(lnk|bat|chm|cmd|vxd|pif|scr|hta|jse?|sh[mb]|vb[esx]|ws[fh])' $i` if [ -n "${output}" ] then filedeleted="yes" mv $i $quarantine echo `date` "[UUencode-Attach] Moved ${i} to ${quarantine}" >> $virexlog else if [ "$debugon" = "yes" ] ; then echo "`date` [UUencode-Attach] clean" >> $virexlog fi fi fi fi # now lets check for exe, dll, shs, com, and zip files which are still welcome # but the subject will be rewritten to alert the user if [ "$subjectrewrite" = "yes" ] ; then if [ "$filedeleted" = "no" ] then attachmime=`egrep -l -i '(Content-(Disposition:\sattachment;|Type:).*|\s+)(file)?name\s*=\s*"?.*\.(exe|com|shs|dll|zip)"?\s*' $i` attachuuencode=`egrep -l -i 'begin [0-9]{1,4} .*\.(exe|com|shs|dll|zip)' $i ` manualcheck=`egrep -l -i 'filename=\s*".*\.(exe|com|shs|dll|zip)"' $i ` output=`echo $attachmime $attachuuencode $manualcheck | tr " " "\n" | sort | uniq` if [ "$debugon" = "yes" ] ; then echo "Output: $output" fi if [ -n "${output}" ] then filedeleted="yes" tmp=`grep "Subject: \[Careful: Attachment\] " $i` if [ -z "$tmp" ] then mytmp=`sed 's/Subject: /Subject: [Careful: Attachment] /g' $i` echo -n "$mytmp" > $i echo "`date` [Subject-Rewrite] Rewrote subject: $i" >> $virexlog else if [ "$debugon" = "yes" ] ; then echo "`date` [Subject-Rewrite] clean" >> $virexlog fi fi fi fi fi done if [ "$debugon" = "yes" ] ; then echo "`date` [End] virex - started at $startdate" >> $virexlog fi #end