1341415c8Sbostic#!/bin/sh - 2341415c8Sbostic# 3*de0b4677Sbostic# @(#)security 8.1 (Berkeley) 06/09/93 4341415c8Sbostic# 5e4e6515bSbostic 6efff9fd4SbosticPATH=/sbin:/usr/sbin:/bin:/usr/bin 7341415c8Sbostic 82e01ce9eSbosticumask 077 99f40dbdcSbostic 106c152fbeSbosticERR=/tmp/_secure1.$$ 116c152fbeSbosticTMP1=/tmp/_secure2.$$ 126c152fbeSbosticTMP2=/tmp/_secure3.$$ 132e01ce9eSbosticTMP3=/tmp/_secure4.$$ 142e01ce9eSbosticLIST=/tmp/_secure5.$$ 152e01ce9eSbosticOUTPUT=/tmp/_secure6.$$ 16efff9fd4Sbostic 172e01ce9eSbostictrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0 18efff9fd4Sbostic 198f0ba418Sbostic# Check the master password file syntax. 202e01ce9eSbosticMP=/etc/master.passwd 212e01ce9eSbosticawk -F: '{ 222e01ce9eSbostic if ($0 ~ /^[ ]*$/) { 232e01ce9eSbostic printf("Line %d is a blank line.\n", NR); 242e01ce9eSbostic next; 252e01ce9eSbostic } 262e01ce9eSbostic if (NF != 10) 272e01ce9eSbostic printf("Line %d has the wrong number of fields.\n", NR); 28c7ce5722Sbostic if ($1 !~ /^[A-Za-z0-9]*$/) 298b53557dSbostic printf("Login %s has non-alphanumeric characters.\n", $1); 302e01ce9eSbostic if (length($1) > 8) 312e01ce9eSbostic printf("Login %s has more than 8 characters.\n", $1); 322e01ce9eSbostic if ($2 == "") 332e01ce9eSbostic printf("Login %s has no password.\n", $1); 342e01ce9eSbostic if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == "")) 352e01ce9eSbostic printf("Login %s is off but still has a valid shell.\n", $1); 362e01ce9eSbostic if ($3 == 0 && $1 != "root" && $1 != "toor") 372e01ce9eSbostic printf("Login %s has a user id of 0.\n", $1); 382e01ce9eSbostic if ($3 < 0) 392e01ce9eSbostic printf("Login %s has a negative user id.\n", $1); 402e01ce9eSbostic if ($4 < 0) 41c7ce5722Sbostic printf("Login %s has a negative group id.\n", $1); 422e01ce9eSbostic}' < $MP > $OUTPUT 432e01ce9eSbosticif [ -s $OUTPUT ] ; then 442e01ce9eSbostic printf "\nChecking the $MP file:\n" 452e01ce9eSbostic cat $OUTPUT 462e01ce9eSbosticfi 47fe22c88eSbostic 482e01ce9eSbosticawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT 492e01ce9eSbosticif [ -s $OUTPUT ] ; then 502e01ce9eSbostic printf "\n$MP has duplicate user names.\n" 512e01ce9eSbostic column $OUTPUT 522e01ce9eSbosticfi 53f4e62e4fSbostic 542e01ce9eSbosticawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | 552e01ce9eSbosticuniq -d -f 1 | awk '{ print $2 }' > $TMP2 562e01ce9eSbosticif [ -s $TMP2 ] ; then 572e01ce9eSbostic printf "\n$MP has duplicate user id's.\n" 582e01ce9eSbostic while read uid; do 592e01ce9eSbostic grep -w $uid $TMP1 602e01ce9eSbostic done < $TMP2 | column 612e01ce9eSbosticfi 622e01ce9eSbostic 6317aa77b0Sbostic# Backup the master password file; a special case, the normal backup 6417aa77b0Sbostic# mechanisms also print out file differences and we don't want to do 6517aa77b0Sbostic# that because this file has encrypted passwords in it. 6617aa77b0SbosticCUR=/var/backups/`basename $MP`.current 6717aa77b0SbosticBACK=/var/backups/`basename $MP`.backup 6817aa77b0Sbosticif [ -s $CUR ] ; then 6917aa77b0Sbostic if cmp -s $CUR $MP; then 7017aa77b0Sbostic : 7117aa77b0Sbostic else 7217aa77b0Sbostic cp -p $CUR $BACK 7317aa77b0Sbostic cp -p $MP $CUR 7417aa77b0Sbostic chown root.wheel $CUR 7517aa77b0Sbostic fi 7617aa77b0Sbosticelse 7717aa77b0Sbostic cp -p $MP $CUR 7817aa77b0Sbostic chown root.wheel $CUR 7917aa77b0Sbosticfi 8017aa77b0Sbostic 812e01ce9eSbostic# Check the group file syntax. 822e01ce9eSbosticGRP=/etc/group 832e01ce9eSbosticawk -F: '{ 842e01ce9eSbostic if ($0 ~ /^[ ]*$/) { 852e01ce9eSbostic printf("Line %d is a blank line.\n", NR); 862e01ce9eSbostic next; 872e01ce9eSbostic } 882e01ce9eSbostic if (NF != 4) 892e01ce9eSbostic printf("Line %d has the wrong number of fields.\n", NR); 90f5577ccbSbostic if ($1 !~ /^[A-za-z0-9]*$/) 918b53557dSbostic printf("Group %s has non-alphanumeric characters.\n", $1); 922e01ce9eSbostic if (length($1) > 8) 932e01ce9eSbostic printf("Group %s has more than 8 characters.\n", $1); 942e01ce9eSbostic if ($3 !~ /[0-9]*/) 95c7ce5722Sbostic printf("Login %s has a negative group id.\n", $1); 962e01ce9eSbostic}' < $GRP > $OUTPUT 972e01ce9eSbosticif [ -s $OUTPUT ] ; then 982e01ce9eSbostic printf "\nChecking the $GRP file:\n" 992e01ce9eSbostic cat $OUTPUT 1002e01ce9eSbosticfi 1012e01ce9eSbostic 1022e01ce9eSbosticawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT 1032e01ce9eSbosticif [ -s $OUTPUT ] ; then 1042e01ce9eSbostic printf "\n$GRP has duplicate group names.\n" 1052e01ce9eSbostic column $OUTPUT 1062e01ce9eSbosticfi 1072e01ce9eSbostic 1082e01ce9eSbostic# Check for root paths, umask values in startup files. 1098f0ba418Sbostic# The check for the root paths is problematical -- it's likely to fail 1108f0ba418Sbostic# in other environments. Once the shells have been modified to warn 1118f0ba418Sbostic# of '.' in the path, the path tests should go away. 1122e01ce9eSbostic> $OUTPUT 1132e01ce9eSbosticrhome=/root 1142e01ce9eSbosticumaskset=no 1152e01ce9eSbosticlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login" 1162e01ce9eSbosticfor i in $list ; do 1172e01ce9eSbostic if [ -f $i ] ; then 1182e01ce9eSbostic if egrep umask $i > /dev/null ; then 1192e01ce9eSbostic umaskset=yes 1202e01ce9eSbostic fi 1212e01ce9eSbostic egrep umask $i | 1222e01ce9eSbostic awk '$2 % 100 < 20 \ 1232e01ce9eSbostic { print "Root umask is group writeable" } 1242e01ce9eSbostic $2 % 10 < 2 \ 1252e01ce9eSbostic { print "Root umask is other writeable" }' >> $OUTPUT 1262e01ce9eSbostic /bin/csh -f -s << end-of-csh > /dev/null 2>&1 1272e01ce9eSbostic unset path 1282e01ce9eSbostic source $i 1292e01ce9eSbostic /bin/ls -ldgT \$path > $TMP1 1302e01ce9eSbosticend-of-csh 1312e01ce9eSbostic awk '{ 132f5577ccbSbostic if ($10 ~ /^\.$/) { 1332e01ce9eSbostic print "The root path includes ."; 1342e01ce9eSbostic next; 1352e01ce9eSbostic } 1362e01ce9eSbostic } 1372e01ce9eSbostic $1 ~ /^d....w/ \ 1382e01ce9eSbostic { print "Root path directory " $10 " is group writeable." } \ 1392e01ce9eSbostic $1 ~ /^d.......w/ \ 1402e01ce9eSbostic { print "Root path directory " $10 " is other writeable." }' \ 1412e01ce9eSbostic < $TMP1 >> $OUTPUT 1422e01ce9eSbostic fi 1432e01ce9eSbosticdone 1442e01ce9eSbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1452e01ce9eSbostic printf "\nChecking root csh paths, umask values:\n$list\n" 1462e01ce9eSbostic if [ -s $OUTPUT ]; then 1472e01ce9eSbostic cat $OUTPUT 1482e01ce9eSbostic fi 1492e01ce9eSbostic if [ $umaskset = "no" ] ; then 1502e01ce9eSbostic printf "\nRoot csh startup files do not set the umask.\n" 1512e01ce9eSbostic fi 1522e01ce9eSbosticfi 1532e01ce9eSbostic 1542e01ce9eSbostic> $OUTPUT 1552e01ce9eSbosticrhome=/root 1562e01ce9eSbosticumaskset=no 1572e01ce9eSbosticlist="${rhome}/.profile" 1582e01ce9eSbosticfor i in $list; do 1592e01ce9eSbostic if [ -f $i ] ; then 1602e01ce9eSbostic if egrep umask $i > /dev/null ; then 1612e01ce9eSbostic umaskset=yes 1622e01ce9eSbostic fi 1632e01ce9eSbostic egrep umask $i | 1642e01ce9eSbostic awk '$2 % 100 < 20 \ 1652e01ce9eSbostic { print "Root umask is group writeable" } \ 1662e01ce9eSbostic $2 % 10 < 2 \ 1672e01ce9eSbostic { print "Root umask is other writeable" }' >> $OUTPUT 1682e01ce9eSbostic /bin/sh << end-of-sh > /dev/null 2>&1 1692e01ce9eSbostic PATH= 1702e01ce9eSbostic . $i 1712e01ce9eSbostic list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\` 1722e01ce9eSbostic /bin/ls -ldgT \$list > $TMP1 1732e01ce9eSbosticend-of-sh 1742e01ce9eSbostic awk '{ 175f5577ccbSbostic if ($10 ~ /^\.$/) { 1762e01ce9eSbostic print "The root path includes ."; 1772e01ce9eSbostic next; 1782e01ce9eSbostic } 1792e01ce9eSbostic } 1802e01ce9eSbostic $1 ~ /^d....w/ \ 1812e01ce9eSbostic { print "Root path directory " $10 " is group writeable." } \ 1822e01ce9eSbostic $1 ~ /^d.......w/ \ 1832e01ce9eSbostic { print "Root path directory " $10 " is other writeable." }' \ 1842e01ce9eSbostic < $TMP1 >> $OUTPUT 1852e01ce9eSbostic 1862e01ce9eSbostic fi 1872e01ce9eSbosticdone 1882e01ce9eSbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then 1892e01ce9eSbostic printf "\nChecking root sh paths, umask values:\n$list\n" 1902e01ce9eSbostic if [ -s $OUTPUT ]; then 1912e01ce9eSbostic cat $OUTPUT 1922e01ce9eSbostic fi 1932e01ce9eSbostic if [ $umaskset = "no" ] ; then 1942e01ce9eSbostic printf "\nRoot sh startup files do not set the umask.\n" 1952e01ce9eSbostic fi 1962e01ce9eSbosticfi 1972e01ce9eSbostic 1982e01ce9eSbostic# Root and uucp should both be in /etc/ftpusers. 1992e01ce9eSbosticif egrep root /etc/ftpusers > /dev/null ; then 2002e01ce9eSbostic : 2012e01ce9eSbosticelse 2022e01ce9eSbostic printf "\nRoot not listed in /etc/ftpusers file.\n" 2032e01ce9eSbosticfi 2042e01ce9eSbosticif egrep uucp /etc/ftpusers > /dev/null ; then 2052e01ce9eSbostic : 2062e01ce9eSbosticelse 2072e01ce9eSbostic printf "\nUucp not listed in /etc/ftpusers file.\n" 2082e01ce9eSbosticfi 2092e01ce9eSbostic 2108f0ba418Sbostic# Uudecode should not be in the /etc/aliases file. 2117fc7eaa2Sbosticif egrep 'uudecode|decode' /etc/aliases; then 2122e01ce9eSbostic printf "\nThere is an entry for uudecode in the /etc/aliases file.\n" 2132e01ce9eSbosticfi 2142e01ce9eSbostic 215e4bdd3a8Sbostic# Files that should not have + signs. 216353a346cSbosticlist="/etc/hosts.equiv /etc/hosts.lpd" 217353a346cSbosticfor f in $list ; do 218e4bdd3a8Sbostic if egrep '\+' $f > /dev/null ; then 219e4bdd3a8Sbostic printf "\nPlus sign in $f file.\n" 2202e01ce9eSbostic fi 221353a346cSbosticdone 222f4e62e4fSbostic 223e4e6515bSbostic# Check for special users with .rhosts files. Only root and toor should 224e4bdd3a8Sbostic# have a .rhosts files. Also, .rhosts files should not plus signs. 2252e01ce9eSbosticawk -F: '$1 != "root" && $1 != "toor" && \ 2262e01ce9eSbostic ($3 < 100 || $1 == "ftp" || $1 == "uucp") \ 2272e01ce9eSbostic { print $1 " " $6 }' /etc/passwd | 228f4e62e4fSbosticwhile read uid homedir; do 229f4e62e4fSbostic if [ -f ${homedir}/.rhosts ] ; then 230e4e6515bSbostic rhost=`ls -ldgT ${homedir}/.rhosts` 2312e01ce9eSbostic printf "$uid: $rhost\n" 232f4e62e4fSbostic fi 2332e01ce9eSbosticdone > $OUTPUT 2342e01ce9eSbosticif [ -s $OUTPUT ] ; then 2352e01ce9eSbostic printf "\nChecking for special users with .rhosts files.\n" 2362e01ce9eSbostic cat $OUTPUT 2372e01ce9eSbosticfi 238f4e62e4fSbostic 2392e01ce9eSbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 2402e01ce9eSbosticwhile read uid homedir; do 2412e01ce9eSbostic if [ -f ${homedir}/.rhosts ] && \ 242e4bdd3a8Sbostic egrep '\+' ${homedir}/.rhosts > /dev/null ; then 243e4bdd3a8Sbostic printf "$uid: + in .rhosts file.\n" 2442e01ce9eSbostic fi 2452e01ce9eSbosticdone > $OUTPUT 2462e01ce9eSbosticif [ -s $OUTPUT ] ; then 2472e01ce9eSbostic printf "\nChecking .rhosts files syntax.\n" 2482e01ce9eSbostic cat $OUTPUT 2492e01ce9eSbosticfi 2502e01ce9eSbostic 2518f0ba418Sbostic# Check home directories. Directories should not be owned by someone else 2528f0ba418Sbostic# or writeable. 2532e01ce9eSbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 254e4e6515bSbosticwhile read uid homedir; do 255e4e6515bSbostic if [ -d ${homedir}/ ] ; then 256e4e6515bSbostic file=`ls -ldgT ${homedir}` 2572e01ce9eSbostic printf "$uid $file\n" 258e4e6515bSbostic fi 2592e01ce9eSbosticdone | 2602e01ce9eSbosticawk '$1 != $4 && $4 != "root" \ 2612e01ce9eSbostic { print "user " $1 " home directory is owned by " $4 } 2622e01ce9eSbostic $2 ~ /^-....w/ \ 2632e01ce9eSbostic { print "user " $1 " home directory is group writeable" } 2642e01ce9eSbostic $2 ~ /^-.......w/ \ 2652e01ce9eSbostic { print "user " $1 " home directory is other writeable" }' > $OUTPUT 2662e01ce9eSbosticif [ -s $OUTPUT ] ; then 2672e01ce9eSbostic printf "\nChecking home directories.\n" 2682e01ce9eSbostic cat $OUTPUT 2692e01ce9eSbosticfi 270e4e6515bSbostic 271f4e62e4fSbostic# Files that should not be owned by someone else or readable. 2722e01ce9eSbosticlist=".netrc .rhosts" 2732e01ce9eSbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 274f4e62e4fSbosticwhile read uid homedir; do 2752e01ce9eSbostic for f in $list ; do 2762e01ce9eSbostic file=${homedir}/${f} 2772e01ce9eSbostic if [ -f $file ] ; then 2782e01ce9eSbostic printf "$uid $f `ls -ldgT $file`\n" 279f4e62e4fSbostic fi 2802e01ce9eSbostic done 2812e01ce9eSbosticdone | 2822e01ce9eSbosticawk '$1 != $5 && $5 != "root" \ 2832e01ce9eSbostic { print "user " $1 " " $2 " file is owned by " $5 } 2842e01ce9eSbostic $3 ~ /^-...r/ \ 2852e01ce9eSbostic { print "user " $1 " " $2 " file is group readable" } 2862e01ce9eSbostic $3 ~ /^-......r/ \ 2872e01ce9eSbostic { print "user " $1 " " $2 " file is other readable" } 2882e01ce9eSbostic $3 ~ /^-....w/ \ 2892e01ce9eSbostic { print "user " $1 " " $2 " file is group writeable" } 2902e01ce9eSbostic $3 ~ /^-.......w/ \ 2912e01ce9eSbostic { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 292f4e62e4fSbostic 293f4e62e4fSbostic# Files that should not be owned by someone else or writeable. 2942e01ce9eSbosticlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \ 2952e01ce9eSbostic .profile .tcshrc" 2962e01ce9eSbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 297f4e62e4fSbosticwhile read uid homedir; do 2982e01ce9eSbostic for f in $list ; do 2992e01ce9eSbostic file=${homedir}/${f} 3002e01ce9eSbostic if [ -f $file ] ; then 3012e01ce9eSbostic printf "$uid $f `ls -ldgT $file`\n" 302f4e62e4fSbostic fi 3032e01ce9eSbostic done 3042e01ce9eSbosticdone | 3052e01ce9eSbosticawk '$1 != $5 && $5 != "root" \ 3062e01ce9eSbostic { print "user " $1 " " $2 " file is owned by " $5 } 3072e01ce9eSbostic $3 ~ /^-....w/ \ 3082e01ce9eSbostic { print "user " $1 " " $2 " file is group writeable" } 3092e01ce9eSbostic $3 ~ /^-.......w/ \ 3102e01ce9eSbostic { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 3112e01ce9eSbosticif [ -s $OUTPUT ] ; then 3122e01ce9eSbostic printf "\nChecking dot files.\n" 3132e01ce9eSbostic cat $OUTPUT 314f4e62e4fSbosticfi 315f4e62e4fSbostic 3168f0ba418Sbostic# Mailboxes should be owned by user and unreadable. 3172e01ce9eSbosticls -l /var/mail | sed 1d | \ 3182e01ce9eSbosticawk '$3 != $9 \ 3192e01ce9eSbostic { print "user " $9 " mailbox is owned by " $3 } 3202e01ce9eSbostic $1 != "-rw-------" \ 3212e01ce9eSbostic { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 3222e01ce9eSbosticif [ -s $OUTPUT ] ; then 3232e01ce9eSbostic printf "\nChecking mailbox ownership.\n" 3242e01ce9eSbostic cat $OUTPUT 325f4e62e4fSbosticfi 326fe22c88eSbostic 3278f0ba418Sbostic# File systems should not be globally exported. 328e4e6515bSbosticawk '{ 329e4e6515bSbostic readonly = 0; 330e4e6515bSbostic for (i = 2; i <= NF; ++i) { 331e4e6515bSbostic if ($i ~ /-ro/) 332e4e6515bSbostic readonly = 1; 333e4e6515bSbostic else if ($i !~ /^-/) 334e4e6515bSbostic next; 335e4e6515bSbostic } 336e4e6515bSbostic if (readonly) 337e4e6515bSbostic print "File system " $1 " globally exported, read-only." 338e4e6515bSbostic else 339e4e6515bSbostic print "File system " $1 " globally exported, read-write." 3402e01ce9eSbostic}' < /etc/exports > $OUTPUT 3412e01ce9eSbosticif [ -s $OUTPUT ] ; then 3422e01ce9eSbostic printf "\nChecking for globally exported file systems.\n" 3432e01ce9eSbostic cat $OUTPUT 3442e01ce9eSbosticfi 345e4e6515bSbostic 3468f0ba418Sbostic# Display any changes in setuid files and devices. 3472e01ce9eSbosticprintf "\nChecking setuid files and devices:\n" 3482e01ce9eSbostic(find / ! -fstype local -a -prune -o \ 3492e01ce9eSbostic \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \ 3502e01ce9eSbostic ! -type s \) | \ 3512e01ce9eSbosticsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 352341415c8Sbostic 3536c152fbeSbostic# Display any errors that occurred during system file walk. 3542e01ce9eSbosticif [ -s $OUTPUT ] ; then 3552e01ce9eSbostic printf "Setuid/device find errors:\n" 3562e01ce9eSbostic cat $OUTPUT 3572e01ce9eSbostic printf "\n" 358341415c8Sbosticfi 3599f40dbdcSbostic 3606c152fbeSbostic# Display any changes in the setuid file list. 3612e01ce9eSbosticegrep -v '^[bc]' $LIST > $TMP1 3622e01ce9eSbosticif [ -s $TMP1 ] ; then 3632e01ce9eSbostic # Check to make sure uudecode isn't setuid. 3642e01ce9eSbostic if grep -w uudecode $TMP1 > /dev/null ; then 3652e01ce9eSbostic printf "\nUudecode is setuid.\n" 3662e01ce9eSbostic fi 3672e01ce9eSbostic 3682e01ce9eSbostic CUR=/var/backups/setuid.current 3692e01ce9eSbostic BACK=/var/backups/setuid.backup 370fe22c88eSbostic 3716c152fbeSbostic if [ -s $CUR ] ; then 3722e01ce9eSbostic if cmp -s $CUR $TMP1 ; then 373fe22c88eSbostic : 374fe22c88eSbostic else 3752e01ce9eSbostic > $TMP2 3762e01ce9eSbostic join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 3772e01ce9eSbostic if [ -s $OUTPUT ] ; then 3782e01ce9eSbostic printf "Setuid additions:\n" 3792e01ce9eSbostic tee -a $TMP2 < $OUTPUT 3802e01ce9eSbostic printf "\n" 3819f40dbdcSbostic fi 382341415c8Sbostic 3832e01ce9eSbostic join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 3842e01ce9eSbostic if [ -s $OUTPUT ] ; then 3852e01ce9eSbostic printf "Setuid deletions:\n" 3862e01ce9eSbostic tee -a $TMP2 < $OUTPUT 3872e01ce9eSbostic printf "\n" 388fe22c88eSbostic fi 389fe22c88eSbostic 3902e01ce9eSbostic sort +9 $TMP2 $CUR $TMP1 | \ 3912e01ce9eSbostic sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 3922e01ce9eSbostic if [ -s $OUTPUT ] ; then 3932e01ce9eSbostic printf "Setuid changes:\n" 3942e01ce9eSbostic column -t $OUTPUT 3952e01ce9eSbostic printf "\n" 396fe22c88eSbostic fi 397fe22c88eSbostic 3982e01ce9eSbostic cp $CUR $BACK 3992e01ce9eSbostic cp $TMP1 $CUR 400fe22c88eSbostic fi 401fe22c88eSbostic else 4022e01ce9eSbostic printf "Setuid additions:\n" 4038d53afbfSbostic column -t $TMP1 4042e01ce9eSbostic printf "\n" 4052e01ce9eSbostic cp $TMP1 $CUR 406fe22c88eSbostic fi 407fe22c88eSbosticfi 408fe22c88eSbostic 4098f0ba418Sbostic# Check for block and character disk devices that are readable or writeable 4108d53afbfSbostic# or not owned by root.operator. 411cc8fcf7bSbostic>$TMP1 412cc8fcf7bSbosticDISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd" 413cc8fcf7bSbosticfor i in $DISKLIST; do 414cc8fcf7bSbostic egrep "^b.*/${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 415cc8fcf7bSbostic egrep "^c.*/r${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 416cc8fcf7bSbosticdone 417e4e6515bSbostic 4188d53afbfSbosticawk '$3 != "root" || $4 != "operator" || $1 !~ /.rw-r-----/ \ 4198d53afbfSbostic { printf("Disk %s is user %s, group %s, permissions %s.\n", \ 4208d53afbfSbostic $11, $3, $4, $1); }' < $TMP1 > $OUTPUT 4212e01ce9eSbosticif [ -s $OUTPUT ] ; then 4222e01ce9eSbostic printf "\nChecking disk ownership and permissions.\n" 4232e01ce9eSbostic cat $OUTPUT 4242e01ce9eSbostic printf "\n" 4252e01ce9eSbosticfi 426e4e6515bSbostic 4276c152fbeSbostic# Display any changes in the device file list. 4288f0ba418Sbosticegrep '^[bc]' $LIST | sort +10 > $TMP1 4292e01ce9eSbosticif [ -s $TMP1 ] ; then 4302e01ce9eSbostic CUR=/var/backups/device.current 4312e01ce9eSbostic BACK=/var/backups/device.backup 4326c152fbeSbostic 4336c152fbeSbostic if [ -s $CUR ] ; then 4342e01ce9eSbostic if cmp -s $CUR $TMP1 ; then 4356c152fbeSbostic : 4366c152fbeSbostic else 4372e01ce9eSbostic > $TMP2 4382e01ce9eSbostic join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 4392e01ce9eSbostic if [ -s $OUTPUT ] ; then 4402e01ce9eSbostic printf "Device additions:\n" 4412e01ce9eSbostic tee -a $TMP2 < $OUTPUT 4422e01ce9eSbostic printf "\n" 4436c152fbeSbostic fi 4446c152fbeSbostic 4452e01ce9eSbostic join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 4462e01ce9eSbostic if [ -s $OUTPUT ] ; then 4472e01ce9eSbostic printf "Device deletions:\n" 4482e01ce9eSbostic tee -a $TMP2 < $OUTPUT 4492e01ce9eSbostic printf "\n" 4506c152fbeSbostic fi 4516c152fbeSbostic 4528d53afbfSbostic # Report any block device change. Ignore character 4538d53afbfSbostic # devices, only the name is significant. 4548d53afbfSbostic cat $TMP2 $CUR $TMP1 | \ 4558d53afbfSbostic sed -e '/^c/d' | \ 4568d53afbfSbostic sort +10 | \ 4572e01ce9eSbostic sed -e 's/[ ][ ]*/ /g' | \ 4588d53afbfSbostic uniq -u > $OUTPUT 4592e01ce9eSbostic if [ -s $OUTPUT ] ; then 4608d53afbfSbostic printf "Block device changes:\n" 4612e01ce9eSbostic column -t $OUTPUT 4622e01ce9eSbostic printf "\n" 4636c152fbeSbostic fi 4646c152fbeSbostic 4652e01ce9eSbostic cp $CUR $BACK 4662e01ce9eSbostic cp $TMP1 $CUR 4676c152fbeSbostic fi 4686c152fbeSbostic else 4692e01ce9eSbostic printf "Device additions:\n" 4708d53afbfSbostic column -t $TMP1 4712e01ce9eSbostic printf "\n" 4722e01ce9eSbostic cp $TMP1 $CUR 4736c152fbeSbostic fi 4746c152fbeSbosticfi 4756c152fbeSbostic 476bfcfc884Sbostic# Check special files. 477bfcfc884Sbostic# Check system binaries. 478bfcfc884Sbostic# 479efff9fd4Sbostic# Create the mtree tree specifications using: 480efff9fd4Sbostic# 4812e01ce9eSbostic# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 4822e01ce9eSbostic# chown root.wheel DIR.SECURE 4832e01ce9eSbostic# chmod 600 DIR.SECURE 484efff9fd4Sbostic# 485efff9fd4Sbostic# Note, this is not complete protection against Trojan horsed binaries, as 486efff9fd4Sbostic# the hacker can modify the tree specification to match the replaced binary. 487efff9fd4Sbostic# For details on really protecting yourself against modified binaries, see 488efff9fd4Sbostic# the mtree(8) manual page. 489efff9fd4Sbosticif cd /etc/mtree; then 4902e01ce9eSbostic mtree -e -p / -f /etc/mtree/special > $OUTPUT 4912e01ce9eSbostic if [ -s $OUTPUT ] ; then 4922e01ce9eSbostic printf "\nChecking special files and directories.\n" 4932e01ce9eSbostic cat $OUTPUT 4942e01ce9eSbostic fi 4952e01ce9eSbostic 4962e01ce9eSbostic > $OUTPUT 497efff9fd4Sbostic for file in *.secure; do 498efff9fd4Sbostic tree=`sed -n -e '3s/.* //p' -e 3q $file` 4992e01ce9eSbostic mtree -f $file -p $tree > $TMP1 5002e01ce9eSbostic if [ -s $TMP1 ]; then 5012e01ce9eSbostic printf "\nChecking $tree:\n" >> $OUTPUT 5022e01ce9eSbostic cat $TMP1 >> $OUTPUT 5032e01ce9eSbostic fi 504efff9fd4Sbostic done 5052e01ce9eSbostic if [ -s $OUTPUT ] ; then 5062e01ce9eSbostic printf "\nChecking system binaries:\n" 5072e01ce9eSbostic cat $OUTPUT 5082e01ce9eSbostic fi 509efff9fd4Sbosticfi 51017aa77b0Sbostic 51117aa77b0Sbostic# List of files that get backed up and checked for any modifications. Each 51217aa77b0Sbostic# file is expected to have two backups, /var/backups/file.{current,backup}. 51317aa77b0Sbostic# Any changes cause the files to rotate. 51417aa77b0Sbosticif [ -s /etc/changelist ] ; then 51517aa77b0Sbostic for file in `cat /etc/changelist`; do 51617aa77b0Sbostic CUR=/var/backups/`basename $file`.current 51717aa77b0Sbostic BACK=/var/backups/`basename $file`.backup 51817aa77b0Sbostic if [ -s $file ]; then 51917aa77b0Sbostic if [ -s $CUR ] ; then 52017aa77b0Sbostic diff $CUR $file > $OUTPUT 52117aa77b0Sbostic if [ -s $OUTPUT ] ; then 52217aa77b0Sbostic printf "\n======\n%s diffs (OLD < > NEW)\n======\n" $file 52317aa77b0Sbostic cat $OUTPUT 52417aa77b0Sbostic cp -p $CUR $BACK 52517aa77b0Sbostic cp -p $file $CUR 52617aa77b0Sbostic chown root.wheel $CUR $BACK 52717aa77b0Sbostic fi 52817aa77b0Sbostic else 52917aa77b0Sbostic cp -p $file $CUR 53017aa77b0Sbostic chown root.wheel $CUR 53117aa77b0Sbostic fi 53217aa77b0Sbostic fi 53317aa77b0Sbostic done 53417aa77b0Sbosticfi 535