security revision 1.9
11.1Scgd#!/bin/sh - 21.1Scgd# 31.9Scgd# from: @(#)security 8.1 (Berkeley) 6/9/93 41.9Scgd# $Id: security,v 1.9 1994/06/15 04:28:20 cgd Exp $ 51.1Scgd# 61.1Scgd 71.9ScgdPATH=/sbin:/usr/sbin:/bin:/usr/bin 81.1Scgd 91.9Scgdumask 077 101.1Scgd 111.9ScgdERR=/tmp/_secure1.$$ 121.9ScgdTMP1=/tmp/_secure2.$$ 131.9ScgdTMP2=/tmp/_secure3.$$ 141.9ScgdTMP3=/tmp/_secure4.$$ 151.9ScgdLIST=/tmp/_secure5.$$ 161.9ScgdOUTPUT=/tmp/_secure6.$$ 171.9Scgd 181.9Scgdtrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0 191.9Scgd 201.9Scgd# Check the master password file syntax. 211.9ScgdMP=/etc/master.passwd 221.9Scgdawk -F: '{ 231.9Scgd if ($0 ~ /^[ ]*$/) { 241.9Scgd printf("Line %d is a blank line.\n", NR); 251.9Scgd next; 261.9Scgd } 271.9Scgd if (NF != 10) 281.9Scgd printf("Line %d has the wrong number of fields.\n", NR); 291.9Scgd if ($1 !~ /^[A-Za-z0-9]*$/) 301.9Scgd printf("Login %s has non-alphanumeric characters.\n", $1); 311.9Scgd if (length($1) > 8) 321.9Scgd printf("Login %s has more than 8 characters.\n", $1); 331.9Scgd if ($2 == "") 341.9Scgd printf("Login %s has no password.\n", $1); 351.9Scgd if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == "")) 361.9Scgd printf("Login %s is off but still has a valid shell.\n", $1); 371.9Scgd if ($3 == 0 && $1 != "root" && $1 != "toor") 381.9Scgd printf("Login %s has a user id of 0.\n", $1); 391.9Scgd if ($3 < 0) 401.9Scgd printf("Login %s has a negative user id.\n", $1); 411.9Scgd if ($4 < 0) 421.9Scgd printf("Login %s has a negative group id.\n", $1); 431.9Scgd}' < $MP > $OUTPUT 441.9Scgdif [ -s $OUTPUT ] ; then 451.9Scgd printf "\nChecking the $MP file:\n" 461.9Scgd cat $OUTPUT 471.9Scgdfi 481.9Scgd 491.9Scgdawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT 501.9Scgdif [ -s $OUTPUT ] ; then 511.9Scgd printf "\n$MP has duplicate user names.\n" 521.9Scgd column $OUTPUT 531.9Scgdfi 541.9Scgd 551.9Scgdawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | 561.9Scgduniq -d -f 1 | awk '{ print $2 }' > $TMP2 571.9Scgdif [ -s $TMP2 ] ; then 581.9Scgd printf "\n$MP has duplicate user id's.\n" 591.9Scgd while read uid; do 601.9Scgd grep -w $uid $TMP1 611.9Scgd done < $TMP2 | column 621.9Scgdfi 631.9Scgd 641.9Scgd# Backup the master password file; a special case, the normal backup 651.9Scgd# mechanisms also print out file differences and we don't want to do 661.9Scgd# that because this file has encrypted passwords in it. 671.9ScgdCUR=/var/backups/`basename $MP`.current 681.9ScgdBACK=/var/backups/`basename $MP`.backup 691.9Scgdif [ -s $CUR ] ; then 701.9Scgd if cmp -s $CUR $MP; then 711.9Scgd : 721.9Scgd else 731.9Scgd cp -p $CUR $BACK 741.9Scgd cp -p $MP $CUR 751.9Scgd chown root.wheel $CUR 761.9Scgd fi 771.9Scgdelse 781.9Scgd cp -p $MP $CUR 791.9Scgd chown root.wheel $CUR 801.9Scgdfi 811.9Scgd 821.9Scgd# Check the group file syntax. 831.9ScgdGRP=/etc/group 841.9Scgdawk -F: '{ 851.9Scgd if ($0 ~ /^[ ]*$/) { 861.9Scgd printf("Line %d is a blank line.\n", NR); 871.9Scgd next; 881.9Scgd } 891.9Scgd if (NF != 4) 901.9Scgd printf("Line %d has the wrong number of fields.\n", NR); 911.9Scgd if ($1 !~ /^[A-za-z0-9]*$/) 921.9Scgd printf("Group %s has non-alphanumeric characters.\n", $1); 931.9Scgd if (length($1) > 8) 941.9Scgd printf("Group %s has more than 8 characters.\n", $1); 951.9Scgd if ($3 !~ /[0-9]*/) 961.9Scgd printf("Login %s has a negative group id.\n", $1); 971.9Scgd}' < $GRP > $OUTPUT 981.9Scgdif [ -s $OUTPUT ] ; then 991.9Scgd printf "\nChecking the $GRP file:\n" 1001.9Scgd cat $OUTPUT 1011.9Scgdfi 1021.9Scgd 1031.9Scgdawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT 1041.9Scgdif [ -s $OUTPUT ] ; then 1051.9Scgd printf "\n$GRP has duplicate group names.\n" 1061.9Scgd column $OUTPUT 1071.9Scgdfi 1081.9Scgd 1091.9Scgd# Check for root paths, umask values in startup files. 1101.9Scgd# The check for the root paths is problematical -- it's likely to fail 1111.9Scgd# in other environments. Once the shells have been modified to warn 1121.9Scgd# of '.' in the path, the path tests should go away. 1131.9Scgd> $OUTPUT 1141.9Scgdrhome=/root 1151.9Scgdumaskset=no 1161.9Scgdlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login" 1171.9Scgdfor i in $list ; do 1181.9Scgd if [ -f $i ] ; then 1191.9Scgd if egrep umask $i > /dev/null ; then 1201.9Scgd umaskset=yes 1211.9Scgd fi 1221.9Scgd egrep umask $i | 1231.9Scgd awk '$2 % 100 < 20 \ 1241.9Scgd { print "Root umask is group writeable" } 1251.9Scgd $2 % 10 < 2 \ 1261.9Scgd { print "Root umask is other writeable" }' >> $OUTPUT 1271.9Scgd /bin/csh -f -s << end-of-csh > /dev/null 2>&1 1281.9Scgd unset path 1291.9Scgd source $i 1301.9Scgd /bin/ls -ldgT \$path > $TMP1 1311.9Scgdend-of-csh 1321.9Scgd awk '{ 1331.9Scgd if ($10 ~ /^\.$/) { 1341.9Scgd print "The root path includes ."; 1351.9Scgd next; 1361.9Scgd } 1371.9Scgd } 1381.9Scgd $1 ~ /^d....w/ \ 1391.9Scgd { print "Root path directory " $10 " is group writeable." } \ 1401.9Scgd $1 ~ /^d.......w/ \ 1411.9Scgd { print "Root path directory " $10 " is other writeable." }' \ 1421.9Scgd < $TMP1 >> $OUTPUT 1431.9Scgd fi 1441.9Scgddone 1451.9Scgdif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1461.9Scgd printf "\nChecking root csh paths, umask values:\n$list\n" 1471.9Scgd if [ -s $OUTPUT ]; then 1481.9Scgd cat $OUTPUT 1491.9Scgd fi 1501.9Scgd if [ $umaskset = "no" ] ; then 1511.9Scgd printf "\nRoot csh startup files do not set the umask.\n" 1521.9Scgd fi 1531.9Scgdfi 1541.9Scgd 1551.9Scgd> $OUTPUT 1561.9Scgdrhome=/root 1571.9Scgdumaskset=no 1581.9Scgdlist="${rhome}/.profile" 1591.9Scgdfor i in $list; do 1601.9Scgd if [ -f $i ] ; then 1611.9Scgd if egrep umask $i > /dev/null ; then 1621.9Scgd umaskset=yes 1631.9Scgd fi 1641.9Scgd egrep umask $i | 1651.9Scgd awk '$2 % 100 < 20 \ 1661.9Scgd { print "Root umask is group writeable" } \ 1671.9Scgd $2 % 10 < 2 \ 1681.9Scgd { print "Root umask is other writeable" }' >> $OUTPUT 1691.9Scgd /bin/sh << end-of-sh > /dev/null 2>&1 1701.9Scgd PATH= 1711.9Scgd . $i 1721.9Scgd list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\` 1731.9Scgd /bin/ls -ldgT \$list > $TMP1 1741.9Scgdend-of-sh 1751.9Scgd awk '{ 1761.9Scgd if ($10 ~ /^\.$/) { 1771.9Scgd print "The root path includes ."; 1781.9Scgd next; 1791.9Scgd } 1801.9Scgd } 1811.9Scgd $1 ~ /^d....w/ \ 1821.9Scgd { print "Root path directory " $10 " is group writeable." } \ 1831.9Scgd $1 ~ /^d.......w/ \ 1841.9Scgd { print "Root path directory " $10 " is other writeable." }' \ 1851.9Scgd < $TMP1 >> $OUTPUT 1861.9Scgd 1871.9Scgd fi 1881.9Scgddone 1891.9Scgdif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1901.9Scgd printf "\nChecking root sh paths, umask values:\n$list\n" 1911.9Scgd if [ -s $OUTPUT ]; then 1921.9Scgd cat $OUTPUT 1931.9Scgd fi 1941.9Scgd if [ $umaskset = "no" ] ; then 1951.9Scgd printf "\nRoot sh startup files do not set the umask.\n" 1961.9Scgd fi 1971.9Scgdfi 1981.9Scgd 1991.9Scgd# Root and uucp should both be in /etc/ftpusers. 2001.9Scgdif egrep root /etc/ftpusers > /dev/null ; then 2011.9Scgd : 2021.9Scgdelse 2031.9Scgd printf "\nRoot not listed in /etc/ftpusers file.\n" 2041.9Scgdfi 2051.9Scgdif egrep uucp /etc/ftpusers > /dev/null ; then 2061.9Scgd : 2071.9Scgdelse 2081.9Scgd printf "\nUucp not listed in /etc/ftpusers file.\n" 2091.9Scgdfi 2101.9Scgd 2111.9Scgd# Uudecode should not be in the /etc/aliases file. 2121.9Scgdif egrep 'uudecode|decode' /etc/aliases; then 2131.9Scgd printf "\nThere is an entry for uudecode in the /etc/aliases file.\n" 2141.9Scgdfi 2151.9Scgd 2161.9Scgd# Files that should not have + signs. 2171.9Scgdlist="/etc/hosts.equiv /etc/hosts.lpd" 2181.9Scgdfor f in $list ; do 2191.9Scgd if egrep '\+' $f > /dev/null ; then 2201.9Scgd printf "\nPlus sign in $f file.\n" 2211.9Scgd fi 2221.9Scgddone 2231.9Scgd 2241.9Scgd# Check for special users with .rhosts files. Only root and toor should 2251.9Scgd# have a .rhosts files. Also, .rhosts files should not plus signs. 2261.9Scgdawk -F: '$1 != "root" && $1 != "toor" && \ 2271.9Scgd ($3 < 100 || $1 == "ftp" || $1 == "uucp") \ 2281.9Scgd { print $1 " " $6 }' /etc/passwd | 2291.9Scgdwhile read uid homedir; do 2301.9Scgd if [ -f ${homedir}/.rhosts ] ; then 2311.9Scgd rhost=`ls -ldgT ${homedir}/.rhosts` 2321.9Scgd printf "$uid: $rhost\n" 2331.9Scgd fi 2341.9Scgddone > $OUTPUT 2351.9Scgdif [ -s $OUTPUT ] ; then 2361.9Scgd printf "\nChecking for special users with .rhosts files.\n" 2371.9Scgd cat $OUTPUT 2381.9Scgdfi 2391.9Scgd 2401.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2411.9Scgdwhile read uid homedir; do 2421.9Scgd if [ -f ${homedir}/.rhosts ] && \ 2431.9Scgd egrep '\+' ${homedir}/.rhosts > /dev/null ; then 2441.9Scgd printf "$uid: + in .rhosts file.\n" 2451.9Scgd fi 2461.9Scgddone > $OUTPUT 2471.9Scgdif [ -s $OUTPUT ] ; then 2481.9Scgd printf "\nChecking .rhosts files syntax.\n" 2491.9Scgd cat $OUTPUT 2501.9Scgdfi 2511.9Scgd 2521.9Scgd# Check home directories. Directories should not be owned by someone else 2531.9Scgd# or writeable. 2541.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2551.9Scgdwhile read uid homedir; do 2561.9Scgd if [ -d ${homedir}/ ] ; then 2571.9Scgd file=`ls -ldgT ${homedir}` 2581.9Scgd printf "$uid $file\n" 2591.9Scgd fi 2601.9Scgddone | 2611.9Scgdawk '$1 != $4 && $4 != "root" \ 2621.9Scgd { print "user " $1 " home directory is owned by " $4 } 2631.9Scgd $2 ~ /^-....w/ \ 2641.9Scgd { print "user " $1 " home directory is group writeable" } 2651.9Scgd $2 ~ /^-.......w/ \ 2661.9Scgd { print "user " $1 " home directory is other writeable" }' > $OUTPUT 2671.9Scgdif [ -s $OUTPUT ] ; then 2681.9Scgd printf "\nChecking home directories.\n" 2691.9Scgd cat $OUTPUT 2701.9Scgdfi 2711.9Scgd 2721.9Scgd# Files that should not be owned by someone else or readable. 2731.9Scgdlist=".netrc .rhosts" 2741.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2751.9Scgdwhile read uid homedir; do 2761.9Scgd for f in $list ; do 2771.9Scgd file=${homedir}/${f} 2781.9Scgd if [ -f $file ] ; then 2791.9Scgd printf "$uid $f `ls -ldgT $file`\n" 2801.9Scgd fi 2811.9Scgd done 2821.9Scgddone | 2831.9Scgdawk '$1 != $5 && $5 != "root" \ 2841.9Scgd { print "user " $1 " " $2 " file is owned by " $5 } 2851.9Scgd $3 ~ /^-...r/ \ 2861.9Scgd { print "user " $1 " " $2 " file is group readable" } 2871.9Scgd $3 ~ /^-......r/ \ 2881.9Scgd { print "user " $1 " " $2 " file is other readable" } 2891.9Scgd $3 ~ /^-....w/ \ 2901.9Scgd { print "user " $1 " " $2 " file is group writeable" } 2911.9Scgd $3 ~ /^-.......w/ \ 2921.9Scgd { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 2931.9Scgd 2941.9Scgd# Files that should not be owned by someone else or writeable. 2951.9Scgdlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \ 2961.9Scgd .profile .tcshrc" 2971.9Scgdawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2981.9Scgdwhile read uid homedir; do 2991.9Scgd for f in $list ; do 3001.9Scgd file=${homedir}/${f} 3011.9Scgd if [ -f $file ] ; then 3021.9Scgd printf "$uid $f `ls -ldgT $file`\n" 3031.9Scgd fi 3041.9Scgd done 3051.9Scgddone | 3061.9Scgdawk '$1 != $5 && $5 != "root" \ 3071.9Scgd { print "user " $1 " " $2 " file is owned by " $5 } 3081.9Scgd $3 ~ /^-....w/ \ 3091.9Scgd { print "user " $1 " " $2 " file is group writeable" } 3101.9Scgd $3 ~ /^-.......w/ \ 3111.9Scgd { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 3121.9Scgdif [ -s $OUTPUT ] ; then 3131.9Scgd printf "\nChecking dot files.\n" 3141.9Scgd cat $OUTPUT 3151.9Scgdfi 3161.9Scgd 3171.9Scgd# Mailboxes should be owned by user and unreadable. 3181.9Scgdls -l /var/mail | sed 1d | \ 3191.9Scgdawk '$3 != $9 \ 3201.9Scgd { print "user " $9 " mailbox is owned by " $3 } 3211.9Scgd $1 != "-rw-------" \ 3221.9Scgd { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 3231.9Scgdif [ -s $OUTPUT ] ; then 3241.9Scgd printf "\nChecking mailbox ownership.\n" 3251.9Scgd cat $OUTPUT 3261.9Scgdfi 3271.9Scgd 3281.9Scgd# File systems should not be globally exported. 3291.9Scgdawk '{ 3301.9Scgd readonly = 0; 3311.9Scgd for (i = 2; i <= NF; ++i) { 3321.9Scgd if ($i ~ /-ro/) 3331.9Scgd readonly = 1; 3341.9Scgd else if ($i !~ /^-/) 3351.9Scgd next; 3361.9Scgd } 3371.9Scgd if (readonly) 3381.9Scgd print "File system " $1 " globally exported, read-only." 3391.9Scgd else 3401.9Scgd print "File system " $1 " globally exported, read-write." 3411.9Scgd}' < /etc/exports > $OUTPUT 3421.9Scgdif [ -s $OUTPUT ] ; then 3431.9Scgd printf "\nChecking for globally exported file systems.\n" 3441.9Scgd cat $OUTPUT 3451.9Scgdfi 3461.9Scgd 3471.9Scgd# Display any changes in setuid files and devices. 3481.9Scgdprintf "\nChecking setuid files and devices:\n" 3491.9Scgd(find / ! -fstype local -a -prune -o \ 3501.9Scgd \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \ 3511.9Scgd ! -type s \) | \ 3521.9Scgdsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 3531.9Scgd 3541.9Scgd# Display any errors that occurred during system file walk. 3551.9Scgdif [ -s $OUTPUT ] ; then 3561.9Scgd printf "Setuid/device find errors:\n" 3571.9Scgd cat $OUTPUT 3581.9Scgd printf "\n" 3591.9Scgdfi 3601.9Scgd 3611.9Scgd# Display any changes in the setuid file list. 3621.9Scgdegrep -v '^[bc]' $LIST > $TMP1 3631.9Scgdif [ -s $TMP1 ] ; then 3641.9Scgd # Check to make sure uudecode isn't setuid. 3651.9Scgd if grep -w uudecode $TMP1 > /dev/null ; then 3661.9Scgd printf "\nUudecode is setuid.\n" 3671.9Scgd fi 3681.9Scgd 3691.9Scgd CUR=/var/backups/setuid.current 3701.9Scgd BACK=/var/backups/setuid.backup 3711.9Scgd 3721.9Scgd if [ -s $CUR ] ; then 3731.9Scgd if cmp -s $CUR $TMP1 ; then 3741.9Scgd : 3751.9Scgd else 3761.9Scgd > $TMP2 3771.9Scgd join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 3781.9Scgd if [ -s $OUTPUT ] ; then 3791.9Scgd printf "Setuid additions:\n" 3801.9Scgd tee -a $TMP2 < $OUTPUT 3811.9Scgd printf "\n" 3821.9Scgd fi 3831.9Scgd 3841.9Scgd join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 3851.9Scgd if [ -s $OUTPUT ] ; then 3861.9Scgd printf "Setuid deletions:\n" 3871.9Scgd tee -a $TMP2 < $OUTPUT 3881.9Scgd printf "\n" 3891.9Scgd fi 3901.9Scgd 3911.9Scgd sort +9 $TMP2 $CUR $TMP1 | \ 3921.9Scgd sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 3931.9Scgd if [ -s $OUTPUT ] ; then 3941.9Scgd printf "Setuid changes:\n" 3951.9Scgd column -t $OUTPUT 3961.9Scgd printf "\n" 3971.9Scgd fi 3981.9Scgd 3991.9Scgd cp $CUR $BACK 4001.9Scgd cp $TMP1 $CUR 4011.9Scgd fi 4021.9Scgd else 4031.9Scgd printf "Setuid additions:\n" 4041.9Scgd column -t $TMP1 4051.9Scgd printf "\n" 4061.9Scgd cp $TMP1 $CUR 4071.9Scgd fi 4081.9Scgdfi 4091.9Scgd 4101.9Scgd# Check for block and character disk devices that are readable or writeable 4111.9Scgd# or not owned by root.operator. 4121.9Scgd>$TMP1 4131.9ScgdDISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd" 4141.9Scgdfor i in $DISKLIST; do 4151.9Scgd egrep "^b.*/${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 4161.9Scgd egrep "^c.*/r${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 4171.9Scgddone 4181.9Scgd 4191.9Scgdawk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \ 4201.9Scgd { printf("Disk %s is user %s, group %s, permissions %s.\n", \ 4211.9Scgd $11, $3, $4, $1); }' < $TMP1 > $OUTPUT 4221.9Scgdif [ -s $OUTPUT ] ; then 4231.9Scgd printf "\nChecking disk ownership and permissions.\n" 4241.9Scgd cat $OUTPUT 4251.9Scgd printf "\n" 4261.9Scgdfi 4271.9Scgd 4281.9Scgd# Display any changes in the device file list. 4291.9Scgdegrep '^[bc]' $LIST | sort +10 > $TMP1 4301.9Scgdif [ -s $TMP1 ] ; then 4311.9Scgd CUR=/var/backups/device.current 4321.9Scgd BACK=/var/backups/device.backup 4331.9Scgd 4341.9Scgd if [ -s $CUR ] ; then 4351.9Scgd if cmp -s $CUR $TMP1 ; then 4361.9Scgd : 4371.9Scgd else 4381.9Scgd > $TMP2 4391.9Scgd join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 4401.9Scgd if [ -s $OUTPUT ] ; then 4411.9Scgd printf "Device additions:\n" 4421.9Scgd tee -a $TMP2 < $OUTPUT 4431.9Scgd printf "\n" 4441.9Scgd fi 4451.9Scgd 4461.9Scgd join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 4471.9Scgd if [ -s $OUTPUT ] ; then 4481.9Scgd printf "Device deletions:\n" 4491.9Scgd tee -a $TMP2 < $OUTPUT 4501.9Scgd printf "\n" 4511.9Scgd fi 4521.9Scgd 4531.9Scgd # Report any block device change. Ignore character 4541.9Scgd # devices, only the name is significant. 4551.9Scgd cat $TMP2 $CUR $TMP1 | \ 4561.9Scgd sed -e '/^c/d' | \ 4571.9Scgd sort +10 | \ 4581.9Scgd sed -e 's/[ ][ ]*/ /g' | \ 4591.9Scgd uniq -u > $OUTPUT 4601.9Scgd if [ -s $OUTPUT ] ; then 4611.9Scgd printf "Block device changes:\n" 4621.9Scgd column -t $OUTPUT 4631.9Scgd printf "\n" 4641.9Scgd fi 4651.9Scgd 4661.9Scgd cp $CUR $BACK 4671.9Scgd cp $TMP1 $CUR 4681.9Scgd fi 4691.9Scgd else 4701.9Scgd printf "Device additions:\n" 4711.9Scgd column -t $TMP1 4721.9Scgd printf "\n" 4731.9Scgd cp $TMP1 $CUR 4741.9Scgd fi 4751.9Scgdfi 4761.9Scgd 4771.9Scgd# Check special files. 4781.9Scgd# Check system binaries. 4791.9Scgd# 4801.9Scgd# Create the mtree tree specifications using: 4811.9Scgd# 4821.9Scgd# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 4831.9Scgd# chown root.wheel DIR.SECURE 4841.9Scgd# chmod 600 DIR.SECURE 4851.9Scgd# 4861.9Scgd# Note, this is not complete protection against Trojan horsed binaries, as 4871.9Scgd# the hacker can modify the tree specification to match the replaced binary. 4881.9Scgd# For details on really protecting yourself against modified binaries, see 4891.9Scgd# the mtree(8) manual page. 4901.9Scgdif cd /etc/mtree; then 4911.9Scgd mtree -e -p / -f /etc/mtree/special > $OUTPUT 4921.9Scgd if [ -s $OUTPUT ] ; then 4931.9Scgd printf "\nChecking special files and directories.\n" 4941.9Scgd cat $OUTPUT 4951.9Scgd fi 4961.9Scgd 4971.9Scgd > $OUTPUT 4981.9Scgd for file in *.secure; do 4991.9Scgd tree=`sed -n -e '3s/.* //p' -e 3q $file` 5001.9Scgd mtree -f $file -p $tree > $TMP1 5011.9Scgd if [ -s $TMP1 ]; then 5021.9Scgd printf "\nChecking $tree:\n" >> $OUTPUT 5031.9Scgd cat $TMP1 >> $OUTPUT 5041.9Scgd fi 5051.9Scgd done 5061.9Scgd if [ -s $OUTPUT ] ; then 5071.9Scgd printf "\nChecking system binaries:\n" 5081.9Scgd cat $OUTPUT 5091.9Scgd fi 5101.9Scgdfi 5111.9Scgd 5121.9Scgd# List of files that get backed up and checked for any modifications. Each 5131.9Scgd# file is expected to have two backups, /var/backups/file.{current,backup}. 5141.9Scgd# Any changes cause the files to rotate. 5151.9Scgdif [ -s /etc/changelist ] ; then 5161.9Scgd for file in `cat /etc/changelist`; do 5171.9Scgd CUR=/var/backups/`basename $file`.current 5181.9Scgd BACK=/var/backups/`basename $file`.backup 5191.9Scgd if [ -s $file ]; then 5201.9Scgd if [ -s $CUR ] ; then 5211.9Scgd diff $CUR $file > $OUTPUT 5221.9Scgd if [ -s $OUTPUT ] ; then 5231.9Scgd printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file 5241.9Scgd cat $OUTPUT 5251.9Scgd cp -p $CUR $BACK 5261.9Scgd cp -p $file $CUR 5271.9Scgd chown root.wheel $CUR $BACK 5281.9Scgd fi 5291.9Scgd else 5301.9Scgd cp -p $file $CUR 5311.9Scgd chown root.wheel $CUR 5321.9Scgd fi 5331.9Scgd fi 5341.9Scgd done 5351.9Scgdfi 536