#!/bin/sh # security-audit.sh, v0.02 # Purpose: perform a general security check on the system # Written and Copyright 2000 by Bill Jonas, bill@billjonas.com # Certain commands written and Copyright 1995 by AEleen Frish in # _Essential System Administration_, published by O'Reilly. # This script and arrangement of the commands is licensed under the GNU GPL. # Please see http://www.gnu.org/copyleft/gpl.html for details # Please note: # Because the program is licensed free of charge, there is NO WARRANTY for the # program, to the extent permitted by applicable law. Except when otherwise # stated in writing the copyright holders and/or other parties provide the # program "AS IS" WITHOUT WARRANTY OF ANY KIND, either expressed or implied # including, but not limited to, the implied warranties of merchantability and # fitness for a particular purpose. The entire risk as to the quality and # performance of the program is with you. Should the program prove defective, # you assume the cost of all necessary servicing, repair or correction. # Test for root, because this won't work properly without superuser status. # You can delete or comment out the following lines, but you'll break # quite a few things. if [ $UID != 0 ]; then echo "Error: Please become root before running this program." echo "Aborting." exit 1 fi # Try to create a unique report filename and retry if it's not unique RPTTMPFILE="/tmp/security-report.$(date +%Y%m%d%H%M%S)" while [ -f $RPTTMPFILE ]; do RPTTMPFILE="/tmp/security-report.$(date +%Y%m%d%H%M%S)" done # Header lines in the report file echo "System security report for $(hostname -f), $(date +%D)" >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "---" >> $RPTTMPFILE # Do a basic /etc/passwd and /etc/shadow check echo "" echo -n "Checking the /etc/passwd and /etc/shadow files... " echo "" >> $RPTTMPFILE EXTRA_ROOT_ACCTS=$(grep ':00*:' /etc/passwd | grep -v '^root:') if [ "$EXTRA_ROOT_ACCTS" != "" ] # If the string is of non-zero length then echo "Extraneous root accounts:" >> $RPTTMPFILE echo $EXTRA_ROOT_ACCTS >> $RPTTMPFILE else echo "No extraneous superuser accounts found on the system." >> $RPTTMPFILE fi echo "" >> $RPTTMPFILE PWDLESS_ACCTS_PASSWD=$(grep '^[^:]*::' /etc/passwd) if [ -f /etc/shadow ] then PWDLESS_ACCTS_SHADOW=$(grep '^[^:]*::' /etc/shadow) fi if [ "$PWDLESS_ACCTS_PASSWD" != "" -a "$PWDLESS_ACCTS_SHADOW" != "" ] then echo "Accounts with no password:" >> $RPTTMPFILE echo $PWDLESS_ACCTS_PASSWD >> $RPTTMPFILE echo $PWDLESS_ACCTS_SHADOW >> $RPTTMPFILE else echo "No accounts were found to be lacking passwords." >> $RPTTMPFILE fi echo "" >> $RPTTMPFILE echo "---" >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "done." # Check ownership and permissions on a few key directories echo "" echo -n "Checking critical system directories... " for DIR in "/etc" "/bin" "/usr/bin" "/usr/local/bin" "/sbin" "/usr/sbin" "/usr/local/sbin"; do # Test the permissions DIRTEST=$(ls -ld $DIR | grep "^d.w..-..-.") (( [ "$DIRTEST" != "" ] && [ -d $DIR -a -O $DIR -a -G $DIR ] ) && ( echo "$DIR is owned by root.root and is writable only by owner (Good)." >> $RPTTMPFILE )) || ( echo "$DIR possibly has incorrect ownership and/or permissions." >> $RPTTMPFILE ; echo "Please check and CORRECT, if necessary:" >> $RPTTMPFILE ; ls -ld $DIR >> $RPTTMPFILE ) # An explanation of the above: If the string $DIRTEST is not null, then grep # returned a value, which means the permissions are good. Then we test to see # if the file is a directory and is owned by the EUID and is owned by the EGID; # if this is the case, then ownership and permissions are correct, so print a # success message to the report file. If anything failed, so state, and print # the directory listing, encouraging the user to look at this and correct it. done echo "done." echo "" >> $RPTTMPFILE echo "---" >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "" echo -n "Gathering network information about the system... " if [ -x /usr/bin/nmap ] then echo "According to nmap:" >> $RPTTMPFILE nmap localhost | grep -v "^Starting nmap" | grep -v "^Nmap run" | grep -v "^$" >> $RPTTMPFILE else echo "Nmap is not installed, nmap tests not run." >> $RPTTMPFILE fi echo "" >> $RPTTMPFILE echo "Netstat thinks the following TCP and UDP ports are open on your system:" >> $RPTTMPFILE netstat -aut >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "---" >> $RPTTMPFILE echo "done." echo "" echo -n "Finding all SUID files... " echo "" >> $RPTTMPFILE echo "Files which are SUID, and the packages to which they belong:" >> $RPTTMPFILE echo "" >> $RPTTMPFILE # Find files which are regular files and have the SUID bit set for SUID_FILE in $(find / -type f -perm -4000 -print 2> /dev/null); do # Print the file name and other status information echo "$SUID_FILE is set UID $(ls -l $SUID_FILE | awk '{print $3}') and belongs to package $(dpkg -S $SUID_FILE | awk '{print $1}' | sed -e "s/:$//")." >> $RPTTMPFILE done echo "done." echo "" echo -n "Finding all SGID files... " echo "" >> $RPTTMPFILE echo "" >> $RPTTMPFILE echo "Files which are SGID, and the packages to which they belong:" >> $RPTTMPFILE echo "" >> $RPTTMPFILE # Find files which are regular files and have the SGID bit set for SGID_FILE in $(find / -type f -perm -2000 -print 2> /dev/null); do # Print the file name and other status information echo "$SGID_FILE is set GID $(ls -l $SGID_FILE | awk '{print $3}') and belongs to package $(dpkg -S $SGID_FILE | awk '{print $1}' | sed -e "s/:$//")." >> $RPTTMPFILE done echo "done." echo "" echo -n "Finished. Hit to view the log (q when you are finished): " read less $RPTTMPFILE echo "" echo -n "Save log to $HOME/security-report.$(date +%Y.%m.%d)? (y/N) " read REPLY if [ "$REPLY" = "y" -o "$REPLY" = "Y" ] then echo "" echo "Saving report to $HOME/security-report.$(date +%Y.%m.%d)..." cp -i $RPTTMPFILE $HOME/security-report.$(date +%Y.%m.%d) else echo "" echo "Log not saved." fi rm $RPTTMPFILE echo "" echo "Done." echo ""