#!/usr/bin/env bash # Version 4.2 ##**************************************************************************** ### WARNING - THIS VARIABLE MUST BE SET IN ORDER FOR THE SCRIPT TO RUN ### # Set this variable for your system. The first one is for a FreeBSD-6.2 system. # Most *.nix and Debian users will use the second. Mandriva users will # probably need the third one. If none are correct, simply enter your own. # You must only uncomment ONE selection. # SIG_DB="/var/db/clamav" # SIG_DB="/var/lib/clamav" # SIG_DB="/usr/local/share/clamav" ## *************************************************************************## # The basic PATH setting. Should really be set directly in CRON. Default is # set for BASH. Comment it out and uncomment the second one for tcsh or csh. # This script was written in and for Bash. There are no guarantees that # another shell will work, although it might. # For bash shell: export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin # For tcsh or csh shells you may need to use this instead. Comment out above # and uncomment this. Modify as required. # set PATH = (/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin) ## ************************************************************************ ## # Uncomment this on to enable logging. It is off by default. # LOG=1 ## Log directories - Set to suit your system if [ $LOG ]; then C_LOG="/var/log/curl.log" C_TMP="/var/log/curl-tmp.log" R_LOG="/var/log/rsync.log" W_LOG="/var/log/wget.log" fi ## *************************************************************************## # Set the clam user and group identification C_USER="clamav" C_GROUP="clamav" ## ************************************************************************ ## # Check your clamd.conf file for the correct setting of the following. If this # is commented out or incorrect, the auto reload feature of this script # is disbled. We will attempt to gather the PID from the systme directly. You # can use a path setting if this does not work on your system. (option 2) # To turn auto reload off, comment out "RELOAD" below. RELOAD="YES" # Set this to the location of your 'clamd.pid' file'. C_PID=/var/run/clamav/clamd.pid if [ "$RELOAD" == "YES" ]; then if [ -e $C_PID ]; then CLAMD_PID=`cat $C_PID` elif which pidof > /dev/null; then CLAMD_PID=`pidof clamd` elif ps -U $C_USER | awk '/clamd/ { print $1 }' > /dev/null; then CLAMD_PID=`ps -U clamav | awk '/clamd/ { print $1 }'` fi fi ## *************************************************************************## # Uncomment to install the optional MSRBL-SPAM-CR.ndb definition file. # CR="yes" ## *************************************************************************## ## ## ## DO NOT ALTER ANYTHING BELOW UNLESS YOU UNDERSTAND WHAT YOU ARE DOING ## ## ## ## *************************************************************************## # Declare statements - Should not be altered ! declare -a DIRLIST declare -a DL_ERROR declare -a MSRBL_LIST declare -a remove_CR_files declare -a ZIPFILES declare -i DIRLIST_COUNT declare -i FAILED declare -i INSTALLED declare -i LIMIT declare -i MSRBL_COUNT declare -i NO_UPDATE declare -i ZIPFILES_COUNT ##**************************************************************************** # Sanesecurity URL's SS_URL=" http://www.sanesecurity.com/clamav/phishsigs/phish.ndb.gz http://www.sanesecurity.com/clamav/scamsigs/scam.ndb.gz " # MSRBL_RSYNC if [ $CR ]; then MSRBL_RSYNC=" rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM.ndb rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-Images.hdb rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM-CR.ndb " else MSRBL_RSYNC=" rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM.ndb rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-Images.hdb " fi # MSRBL URL's if [ $CR ]; then MSRBL_URL=" http://download.mirror.msrbl.com/MSRBL-Images.hdb http://download.mirror.msrbl.com/MSRBL-SPAM.ndb http://download.mirror.msrbl.com/MSRBL-SPAM-CR.ndb " else MSRBL_URL=" http://download.mirror.msrbl.com/MSRBL-Images.hdb http://download.mirror.msrbl.com/MSRBL-SPAM.ndb " fi # Securiteinfo URL's SI_URL=" http://clamav.securiteinfo.com/vx.hdb.gz http://clamav.securiteinfo.com/honeynet.hdb.gz http://clamav.securiteinfo.com/securiteinfo.hdb.gz " # Malware URL's MW_URL=" http://www.malware.com.br/cgi/submit?action=list_clamav " # Malware file name == should end in '.db' MW_FILE="mbl.db" # Set the TMP directory. The script will create it if does not exist. T_DIR=$SIG_DB/tmp # Make sure we can find the program paths # We will test for 'which' first if ! which which > /dev/null; then echo " Cannot find 'which' If you are running this program from CRON you probably need to set the path in the CRON file. You might check out this URL for further information: http://www.unixgeeks.org/security/newbie/unix/cron-1.html " exit fi # Make sure the required programs are present! if which curl >/dev/null; then DL_AGENT="curl" if [ $LOG ]; then CMD=" --verbose --remote-name --location --remote-time" else CMD=" --silent --remote-name --location --remote-time" fi elif which wget >/dev/null; then DL_AGENT="wget" if [ $LOG ]; then CMD=" -a $W_LOG -N " else CMD=" -q -N " fi else echo "Neither curl or wget can be found. Exiting program" fi if which rsync >/dev/null; then RSY="YES" else unset RSY fi # We will exit if one of the four named programs are not found. for f in clamscan gunzip cmp do if ! which $f > /dev/null; then echo " Cannot find: $f We have to exit " exit fi done ## The following should not be altered unless you are sure of what you ## are doing! ## ********************** FUNCTIONS *************************************** # This is the change_owner function. function change_owner () { for O in $1 do chown $C_USER:$C_GROUP $O done } ##************************************************************************** # This is the check_install function. function check_install () { echo "" cd $T_DIR ## Create an array of the files to be checked LIMIT=0 for F in *.ndb *.hdb *.db do if [[ -e $F ]] then DIRLIST[$LIMIT]=$F LIMIT=$(( LIMIT+1 )) fi done ## Reset the LIMIT variable and start checking the files. LIMIT=0 DIRLIST_COUNT=${#DIRLIST[*]} FAILED=0 NO_UPDATE=0 while [ "$LIMIT" -lt "$DIRLIST_COUNT" ] do clamscan --quiet --no-summary -d ${DIRLIST[$LIMIT]} /dev/null 2>&1 EC=$? # case $EC in [0]*) # Clamscan did not report any errors. # Now check to see if this is a newer signature file. # cmp will respond with '0' if the files are identical. # 1 if they are different. # 2 if the file does not exist. # We will trap the exit code in variable 'CEC'. # We are using the 's' flag to slightly improve speed. # Remove them for more detailed output # First make sure the file is larger than 0 if [ -s ${DIRLIST[$LIMIT]} ]; then cmp -s ${DIRLIST[$LIMIT]} $SIG_DB/${DIRLIST[$LIMIT]} CEC=$? else # The file has a 0 length -- bad CEC=9 fi ;; # *) # Clamscan reported an error -- probably error 50. # Therefore we will not attempt to install this file. # The actual error code will be printed out in the event of a problem. # The failed file will be erased. # Comment out the line below beginning with 'rm' to save it. # The variable $MVEC will be set to 'X' -- no-op echo -e "\n \a" echo " ********** WARNING **********" echo "Unable to install: ${DIRLIST[$LIMIT]}" echo "Clamscan exited with error code "$EC echo "Try downloading and installing the file again." echo -e "\n" FAILED=$((FAILED+1)) rm -f ${DIRLIST[$LIMIT]} MVEC="X" CEC=9 ;; esac # # Process the cmp exit code # case $CEC in [0]*) # The files are identical # Update the 'NO_UPDATE' counter. # Delete the file # The variable $MVEC will be set to 'X' -- no-op echo "No update available ${DIRLIST[$LIMIT]}" NO_UPDATE=$((NO_UPDATE+1)) rm -f ${DIRLIST[$LIMIT]} MVEC="X" ;; # [1]*) # The files are different # We will install the file # Trap the 'mv' exit code in 'MVEC' mv -f ${DIRLIST[$LIMIT]} $SIG_DB/${DIRLIST[$LIMIT]} MVEC=$? ;; # [2]*) # Error code 2 usually means that file(2) does not exist. # We will attempt to install file(1). # Trap the 'mv' exit code in 'MVEC' mv -f ${DIRLIST[$LIMIT]} $SIG_DB/${DIRLIST[$LIMIT]} MVEC=$? ;; # [9]*) # Bad news # Something was wrong with the file. Probably 0 length : ;; *) # cmp encountered a problem. # We will not try to install the file. # The file will be erased. # The variable $MVEC will be set to 'X' -- no-op # Incrementing the 'FAILED' counter echo "cmp issued error code $CEC" echo "Unable to update ${DIRLIST[$LIMIT]} at this time" echo "Try again later" MVEC="X" rm -f ${DIRLIST[$LIMIT]} FAILED=$((FAILED+1)) ;; esac # # Process the mv exit code # case $MVEC in [0]*) # Everything went well. The file installed correctly. # Increment the 'INSTALLED' counter. echo "Installed: ........ ${DIRLIST[$LIMIT]}" INSTALLED=$((INSTALLED+1)) ;; # X*) # Nothing happens here. # For possible future use! : ;; # *) # OPPS, something went wrong. # We are unable to install the file # The file will be deleted # Increment the 'FAILED' counter echo "mv issued error code $MVEC" echo "Unable to install at this time!" echo "Please try again later" if [ ${DIRLIST[$LIMIT]}]; then rm -f ${DIRLIST[$LIMIT]} FAILED=$((FAILED+1)) fi esac # Increment the 'LIMIT' counter. LIMIT=$((LIMIT+1)) # Clear the 'MVEC' flag -- set to NULL unset MVEC done } ##************************************************************************** # This function checks for errors with curl. wget or rsync function dl_error () { echo -e "\n" echo " *******************WARNING******************** $1 issued error code # $2 Unable to download file $3 " } # This is the check_dir function # Make sure our tmp and work directories exist function check_dir () { for D in $T_DIR do if [ ! -d ${D} ]; then mkdir -p -m 0755 ${D} MEC=$? case $MEC in [0]*) # No problems : ;; *) # Something happened - the directory structure could not be created. # The program is being forced to exit. # This might be a file permission problem. echo "Unable to create $D" echo "Check your system and rerun script" echo "Exiting ..." exit ;; esac change_owner ${D} fi done } ##************************************************************************** # This is the get_files function. function get_files () { # We now download the MSRBL files using the the specified program. cd $T_DIR if [ $LOG ]; then echo "Logging is enabled" else echo "Logging has been disabled" fi # if [ $RSY ]; then echo "Using Rsync to download the MSRBL files." for D in $MSRBL_RSYNC do FN=`basename $D` if [ $LOG ]; then rsync -tuv $D $T_DIR >>$R_LOG else rsync -tu $D $T_DIR fi EC=$? if [ $EC -gt 0 ]; then dl_error "rsync" $EC $FN fi done # If 'rsync' is not available else echo " Using $DL_AGENT to download the MSRBL files." for D in $MSRBL_URL do FN=`basename $D` if [[ "$DL_AGENT" == "curl" ]]; then if [ $LOG ]; then curl $CMD -z "$FN" $D >> $C_TMP 2>&1 if [[ -e $C_TMP ]]; then cat $C_TMP >> $C_LOG rm -f $C_TMP fi else curl $CMD -z "$FN" $D fi elif [[ "$DL_AGENT" == "wget" ]]; then wget $CMD $D else echo " We don't seem to have a download agent. Sorry, but we have to exit " exit fi EC=$? if [ $EC -gt 0 ]; then dl_error $DL_AGENT $EC $FN fi unset EC done fi # Get everything else except the Malware files echo "Using $DL_AGENT to download Sanesecurity, Securiteinfo and Malware files" for D in $SI_URL $SS_URL do FN=`basename $D` if [[ "$DL_AGENT" == "curl" ]]; then if [ $LOG ]; then curl $CMD -z "$FN" $D >> $C_TMP 2>&1 if [[ -e $C_TMP ]]; then cat $C_TMP >> $C_LOG rm -f $C_TMP fi else curl $CMD -z "$FN" $D fi elif [[ "$DL_AGENT" == "wget" ]]; then wget $CMD $D else echo " We don't seem to have a download agent. Sorry, but we have to exit " exit fi EC=$? if [ $EC -gt 0 ]; then dl_error $DL_AGENT $EC $FN fi unset EC done # Get the Malware files for D in $MW_URL do FN=$MW_FILE if [[ "$DL_AGENT" == "curl" ]]; then if [ $LOG ]; then curl -L -v --output "$MW_FILE" -z "$MW_FILE" $D >> $C_TMP 2>&1 cat $C_TMP >> $C_LOG rm -f $C_TMP else curl -L -s --output "$MW_FILE" -z "$MW_FILE" $D fi elif [[ "$DL_AGENT" == "wget" ]]; then if [ $LOG ]; then wget -a $W_LOG -O - $MW_URL > $T_DIR/$MW_FILE else wget -q -O - $MW_URL > $T_DIR/$MW_FILE fi else echo " We don't seem to have a download agent. Sorry, but we have to exit " exit fi EC=$? if [ $EC -gt 0 ]; then dl_error $DL_AGENT $EC $FN fi done } ##************************************************************************** # This is the unzip function function unzip () { cd $T_DIR chown $C_USER:$C_GROUP $T_DIR/* ZIPFILES=( *.gz ) LIMIT=0 ZIPFILES_COUNT=${#ZIPFILES[*]} while [ ${LIMIT} -lt ${ZIPFILES_COUNT} ]; do # Get the files name and strip the '.gz' extension NoGZ=${ZIPFILES[$LIMIT]/%.gz/} # Save the original gunzip file and its unzipped version gunzip -qfN <${ZIPFILES[$LIMIT]}> $NoGZ GZEC=$? case $GZEC in [0]*) # No problems. : ;; # [1]*) # Gunzip has a problem. # Check the error code and try again! echo "gunzip issued error code $GZEC" echo "Unable to gunzip ${ZIPFILES[$LIMIT]}" echo "Please try again later" ;; # [2]*) # Gunzip issued a warning. We will attempt to continue. echo "gunzip issued warning code $GZEC" echo "We will attempt to continue" ;; esac # LIMIT=$((LIMIT+1)) done } ##************************************************************************** # This is the move_work function function move_work () { cd $T_DIR # Copy the 'MSRBL' files back. I need to figure out a way around this # procedure when I get some free time. # First, check to see if they even exist. if [ "$SIG_DB/MSRBL*" ]; then LIMIT=0 # Load the array MSRBL_LIST=( $SIG_DB/MSRBL* ) # Initialise the MSRBL_COUNT variable MSRBL_COUNT=${#MSRBL_LIST[*]} # Process the data while [ $LIMIT -lt $MSRBL_COUNT ]; do if [ -e "${MSRBL_LIST[$LIMIT]}" ]; then # Strip the path from the file CF=${MSRBL_LIST[$LIMIT]#$SIG_DB/} # Copy it back to the tmp directory cp -p ${MSRBL_LIST[$LIMIT]} $T_DIR/$CF fi LIMIT=$((LIMIT+1)) done else # Guess they do not exist : fi } ##************************************************************************** # This is the reload function function reload_db () { if [ -z "$CLAMD_PID" ]; then # CLAM_PID not set echo " CLAM_PID not set. Unable to restart clamd." return else kill -USR2 $CLAMD_PID echo " Database Reloaded" fi } ## ************************************************************************* function summary () { # If a file has been installed, start here. if [ $INSTALLED ]; then if [ "$RELOAD" == "YES" ]; then reload_db echo " Files saved to: $SIG_DB Installed: $INSTALLED Not Updated: $NO_UPDATE Failed: $FAILED " else INSTALLED=0 echo " Apparently clamd is not running, or you have the reload function disabled in this script. The database has not been reloaded. Please check your system and try again. Installed: $INSTALLED Not Updated: $NO_UPDATE Failed: $FAILED " fi fi # If a new file has not been installed, we branch here. if ! [ $INSTALLED ]; then INSTALLED=0 echo " Reloading of the database not required. Installed: $INSTALLED Not Updated: $NO_UPDATE Failed: $FAILED " fi } ##************************************************************************** function chg_owner () { cd $SIG_DB chown $C_USER:$C_GROUP * } ## ************************************************************************* function set_dir () { # See if the database directory has been set. Exit with warning if not! if ! [ $SIG_DB ]; then echo " **************************************************************************** You must set the variable 'SIG_DB' in this file for it to operate correctly. The variable is located near line # 12 of this file. Read the documentation that precedes it to insure it is set correctly. You can install the optional MSRBL-SPAM-CR.ndb file. Uncomment line 78. See http://en.wikipedia.org/wiki/Challenge-response_spam_filtering. Auto reloading of the database is controled by the 'RELOAD' variable on line 59. If you know the location of the clamd.pic file, modify line 63. The script will attempt to locate the PID even if you do not enter a correct value if the RELOAD flag is set. This program probable needs to be run as root. If you need to precede scamp.sh with 'sh' on the command line, you probably have the shebang set incorrectly. Correct that rather than using a hack to get this script to work correctly. Check the documentation at the end of this script for further details. You can also turn on logging if desired -- line # 34. Make sure your user and group settings are correct lines 47 & 48. Check your documentation if in doubt. If activating the logging feature, check lines 39, 40 & 41. Also, pay attention to the path setting -- starts at line 22. Also, read the documentation located at the end of this script. Good luck! **************************************************************************** " exit fi } ## *************************************************************************## # Remove the MSRBL-SPAM-CR.ndb files if they are not to be installed function remove_CR_files () { if ! [ $CR ]; then if [ -e $T_DIR/MSRBL-SPAM-CR.ndb -o -e $SIG_DB/MSRBL-SPAM-CR.ndb ]; then rm -f $T_DIR/MSRBL-SPAM-CR.ndb $SIG_DB/MSRBL-SPAM-CR.ndb fi fi } ## Start Program ## set_dir check_dir remove_CR_files get_files unzip check_install move_work chg_owner summary exit # SCRIPT DOCUMENTATION # Version 4.1 # Author: Gerard Seibert # Contact: gerard@seibercom.net # You may need to set the 'shebang' to the actual location of Bash on your # system if this script will not start. Usually, /usr/bin/bash on most *.nix # systems and /usr/local/bin/bash on FreeBSD machines. If in doubt, use: # which bash # to locate it and then use that output for the shebang. Be sure to leave # the '#!' characters, sans quotation marks, present. # This is a complete rewrite of the original 'scamp.sh' program. # The end user is responsible for properly configuring this script. # That will consist of mostly setting the "SIG_DB" setting located on # line 12. # The clamav group and user settings may need to be modified. # Check to insure that the PID specified in this file matches the one # in your clamd.conf file. Failure to set this variable correctly will # cause the script to not issue a reload command to clamd. Commenting # out this variable out has the effect of disabling auto reloading. A # warning message will be displayed in the script's summary upon # completion. Variable located on line 58. # Installing the MSRBL-SPAM-CR.ndb file is optional. It is turned off # by default. Uncomment line 79 to turn it on. # Check out the following URL for further information. # http://en.wikipedia.org/wiki/Challenge-response_spam_filtering # Logging is off by default. It appears to cause problems on certain # systems. It may be enabled by uncommenting the variable located on # line 23. If changed, make sure the paths for the logs are correct. # This program should probably be run from CRON. # Running as 'root' from CRON every four (4) hours will suffice. # You should set a default 'PATH' in your CRON file. Insure that the # path setting in this script is correct for your system. # Check out # for further details. # Example (root's CRON) # min hour mday month wday command # 1 */4 * * * /*path*/*to*/scamp.sh # Any problems or questions regarding this script should be directed # to me at the email address listed above. Be sure to include your # system OS type and version + Bash version + this script's version + # error messages + logs, etc. # The author assumes no responsibility for any problems that might # result from the use of this script on a user's computer. The end user # has the right to make any modifications to this script that they so # feel inclined to make. # Files updated: # honeynet.hdb.gz (securiteinfo.com) # mbl.db (Malware)) # MSRBL-Images.hdb (MSRBL.com) # MSRBL-SPAM.ndb (MSRBL.com) # MSRBL-SPAM-CR.ndb (MSRBL.com) # phish.ndb.gz (sanesecurity.com) # scam.ndb.gz (sanesecurity.com) # securiteinfo.hdb.gz (securiteinfo.com) # vx.hdb.gz (securiteinfo.com) # If 'rsync' is installed on your system, it will be used in place of # 'wget' or 'curl' to download files from 'MSRBL'. # You will probably need to chmod this script to 0755 # This script must be run as root. # You need 'wget' and 'gzip' installed. # Having 'rsync' installed would also be helpful. # This script was developed under Bash 3.x and FreeBSD 6.x and is not # guaranteed to work on other systems. The author greatly appreciates # any assistance from users of other operating systems who wish to # contribute to this project. Patches or suggestions are appreciated. # Money is even more appreciated. :-D # I would like to thank Garfield McBroom for his invaluable assistance # in getting this to run on a "Novell/ Suse SLES 10" system. # Tested on: # 1) FreeBSD 6.x # 2) Novell/ Suse SLES 10 # 3) debian etch # 4) centos 4 ##******************************************************************** ## VARIABLES MEANING (Basically, only the static ones) # C_GROUP Clam group # C_PID Location of clamd.pid file (user supplied)) # C_TMP Location of the curl temporary log file # C_USER Clam user # CLAMD_PID Location of the Clamd PID file (MUST match clamd.conf setting) # CMD Holds the basic flags for each download agent # CR Install the optional MSRBL-SPAM-CR.ndb file # DL_AGENT Indicates whether we are using wget or curl # LOG Turns logging on or off # MSBRL_URL MSBRL files downloaded with wget # MSRBL_RSYNC MSRBL files downloaded with rsync # MW_URL Maleware URL's # PATH Basic PATH setting. Should really be set in CRON # R_LOG Rsync log file # RELOAD Controls whether the database is reloaded # RSY If true then rsync is installed # SI_URL Securiteinfo URL's # SIG_DB Location of the Clamav database (MUST BE SET) # SS_URL Sanesecurity URL's # T_DIR Temporary directory # W_LOG Wget log file # We are so out of here. # A South American scientist from Argentina, after a lengthy study, has # discovered that people with insufficient sexual activity read their e-mail # with their hand on the mouse. Do not bother taking it off now; it is too late.