142328Sbostic#!/bin/sh - 242328Sbostic# 3*53130Sbostic# @(#)security 5.16 (Berkeley) 04/06/92 442328Sbostic# 553105Sbostic 653105Sbostic# Script to check basic system security. Checks included are: 7*53130Sbostic# Password and group file check. 8*53130Sbostic# Root umask, dot in root's path. 9*53130Sbostic# Root and uucp in /etc/ftpusers. 10*53130Sbostic# Entry for uudecode in /etc/aliases, if uudecode is setuid. 11*53130Sbostic# Hosts.equiv syntax. 12*53130Sbostic# Special users that have .rhosts files, .rhosts file syntax. 1353105Sbostic# Home directory and dot-file ownership and permissions. 1453105Sbostic# Mailbox ownership and permissions. 15*53130Sbostic# Globally exported NFS file systems. 1653105Sbostic# Changes in setuid and device files. 1753105Sbostic# Block and character disk device ownership and permissions. 18*53130Sbostic# File list from /etc/mtree/special. 1953105Sbostic# System binaries as described by files in /etc/mtree. 2053105Sbostic 2152578SbosticPATH=/sbin:/usr/sbin:/bin:/usr/bin 2242328Sbostic 23*53130Sbosticumask 077 2452215Sbostic 2553098SbosticERR=/tmp/_secure1.$$ 2653098SbosticTMP1=/tmp/_secure2.$$ 2753098SbosticTMP2=/tmp/_secure3.$$ 28*53130SbosticTMP3=/tmp/_secure4.$$ 29*53130SbosticLIST=/tmp/_secure5.$$ 30*53130SbosticOUTPUT=/tmp/_secure6.$$ 3152578Sbostic 32*53130Sbostictrap 'rm -f $ERR $TMP1 $TMP2 $TMP3 $LIST $OUTPUT' 0 3352578Sbostic 34*53130Sbostic# Check the password file syntax. 35*53130SbosticMP=/etc/master.passwd 36*53130Sbosticawk -F: '{ 37*53130Sbostic if ($0 ~ /^[ ]*$/) { 38*53130Sbostic printf("Line %d is a blank line.\n", NR); 39*53130Sbostic next; 40*53130Sbostic } 41*53130Sbostic if (NF != 10) 42*53130Sbostic printf("Line %d has the wrong number of fields.\n", NR); 43*53130Sbostic if ($1 !~ /[A-za-z0-9]*/) 44*53130Sbostic printf("Login %s has non-numeric characters.\n", $1); 45*53130Sbostic if (length($1) > 8) 46*53130Sbostic printf("Login %s has more than 8 characters.\n", $1); 47*53130Sbostic if ($2 == "") 48*53130Sbostic printf("Login %s has no password.\n", $1); 49*53130Sbostic if (length($2) != 13 && ($10 ~ /.*sh$/ || $10 == "")) 50*53130Sbostic printf("Login %s is off but still has a valid shell.\n", $1); 51*53130Sbostic if ($3 == 0 && $1 != "root" && $1 != "toor") 52*53130Sbostic printf("Login %s has a user id of 0.\n", $1); 53*53130Sbostic if ($3 < 0) 54*53130Sbostic printf("Login %s has a negative user id.\n", $1); 55*53130Sbostic if ($4 < 0) 56*53130Sbostic printf("Login %s has a negative user id.\n", $1); 57*53130Sbostic}' < $MP > $OUTPUT 58*53130Sbosticif [ -s $OUTPUT ] ; then 59*53130Sbostic printf "\nChecking the $MP file:\n" 60*53130Sbostic cat $OUTPUT 61*53130Sbosticfi 6242328Sbostic 63*53130Sbosticawk -F: '{ print $1 }' $MP | sort | uniq -d > $OUTPUT 64*53130Sbosticif [ -s $OUTPUT ] ; then 65*53130Sbostic printf "\n$MP has duplicate user names.\n" 66*53130Sbostic column $OUTPUT 67*53130Sbosticfi 6852573Sbostic 69*53130Sbosticawk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | 70*53130Sbosticuniq -d -f 1 | awk '{ print $2 }' > $TMP2 71*53130Sbosticif [ -s $TMP2 ] ; then 72*53130Sbostic printf "\n$MP has duplicate user id's.\n" 73*53130Sbostic while read uid; do 74*53130Sbostic grep -w $uid $TMP1 75*53130Sbostic done < $TMP2 | column 76*53130Sbosticfi 7753104Sbostic 78*53130Sbostic# Check the group file syntax. 79*53130SbosticGRP=/etc/group 80*53130Sbosticawk -F: '{ 81*53130Sbostic if ($0 ~ /^[ ]*$/) { 82*53130Sbostic printf("Line %d is a blank line.\n", NR); 83*53130Sbostic next; 84*53130Sbostic } 85*53130Sbostic if (NF != 4) 86*53130Sbostic printf("Line %d has the wrong number of fields.\n", NR); 87*53130Sbostic if ($1 !~ /[A-za-z0-9]*/) 88*53130Sbostic printf("Group %s has non-numeric characters.\n", $1); 89*53130Sbostic if (length($1) > 8) 90*53130Sbostic printf("Group %s has more than 8 characters.\n", $1); 91*53130Sbostic if ($3 !~ /[0-9]*/) 92*53130Sbostic printf("Login %s has a negative user id.\n", $1); 93*53130Sbostic}' < $GRP > $OUTPUT 94*53130Sbosticif [ -s $OUTPUT ] ; then 95*53130Sbostic printf "\nChecking the $GRP file:\n" 96*53130Sbostic cat $OUTPUT 97*53130Sbosticfi 98*53130Sbostic 99*53130Sbosticawk -F: '{ print $1 }' $GRP | sort | uniq -d > $OUTPUT 100*53130Sbosticif [ -s $OUTPUT ] ; then 101*53130Sbostic printf "\n$GRP has duplicate group names.\n" 102*53130Sbostic column $OUTPUT 103*53130Sbosticfi 104*53130Sbostic 105*53130Sbostic# Check for root paths, umask values in startup files. 106*53130Sbostic> $OUTPUT 107*53130Sbosticrhome=/root 108*53130Sbosticumaskset=no 109*53130Sbosticlist="/etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login" 110*53130Sbosticfor i in $list ; do 111*53130Sbostic if [ -f $i ] ; then 112*53130Sbostic if egrep umask $i > /dev/null ; then 113*53130Sbostic umaskset=yes 11453104Sbostic fi 115*53130Sbostic egrep umask $i | 116*53130Sbostic awk '$2 % 100 < 20 \ 117*53130Sbostic { print "Root umask is group writeable" } 118*53130Sbostic $2 % 10 < 2 \ 119*53130Sbostic { print "Root umask is other writeable" }' >> $OUTPUT 120*53130Sbostic /bin/csh -f -s << end-of-csh > /dev/null 2>&1 121*53130Sbostic unset path 122*53130Sbostic source $i 123*53130Sbostic /bin/ls -ldgT \$path > $TMP1 124*53130Sbosticend-of-csh 125*53130Sbostic awk '{ 126*53130Sbostic if ($10 ~ /\./) { 127*53130Sbostic print "The root path includes ."; 128*53130Sbostic next; 129*53130Sbostic } 130*53130Sbostic } 131*53130Sbostic $1 ~ /^d....w/ \ 132*53130Sbostic { print "Root path directory " $10 " is group writeable." } \ 133*53130Sbostic $1 ~ /^d.......w/ \ 134*53130Sbostic { print "Root path directory " $10 " is other writeable." }' \ 135*53130Sbostic < $TMP1 >> $OUTPUT 136*53130Sbostic fi 137*53130Sbosticdone 138*53130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then 139*53130Sbostic printf "\nChecking root csh paths, umask values:\n$list\n" 140*53130Sbostic if [ -s $OUTPUT ]; then 141*53130Sbostic cat $OUTPUT 142*53130Sbostic fi 143*53130Sbostic if [ $umaskset = "no" ] ; then 144*53130Sbostic printf "\nRoot csh startup files do not set the umask.\n" 145*53130Sbostic fi 146*53130Sbosticfi 14753104Sbostic 148*53130Sbostic> $OUTPUT 149*53130Sbosticrhome=/root 150*53130Sbosticumaskset=no 151*53130Sbosticlist="${rhome}/.profile" 152*53130Sbosticfor i in $list; do 153*53130Sbostic if [ -f $i ] ; then 154*53130Sbostic if egrep umask $i > /dev/null ; then 155*53130Sbostic umaskset=yes 156*53130Sbostic fi 157*53130Sbostic egrep umask $i | 158*53130Sbostic awk '$2 % 100 < 20 \ 159*53130Sbostic { print "Root umask is group writeable" } \ 160*53130Sbostic $2 % 10 < 2 \ 161*53130Sbostic { print "Root umask is other writeable" }' >> $OUTPUT 162*53130Sbostic /bin/sh << end-of-sh > /dev/null 2>&1 163*53130Sbostic PATH= 164*53130Sbostic . $i 165*53130Sbostic list=\`echo \$PATH | /usr/bin/sed -e 's/:/ /g'\` 166*53130Sbostic /bin/ls -ldgT \$list > $TMP1 167*53130Sbosticend-of-sh 168*53130Sbostic awk '{ 169*53130Sbostic if ($10 ~ /\./) { 170*53130Sbostic print "The root path includes ."; 171*53130Sbostic next; 172*53130Sbostic } 173*53130Sbostic } 174*53130Sbostic $1 ~ /^d....w/ \ 175*53130Sbostic { print "Root path directory " $10 " is group writeable." } \ 176*53130Sbostic $1 ~ /^d.......w/ \ 177*53130Sbostic { print "Root path directory " $10 " is other writeable." }' \ 178*53130Sbostic < $TMP1 >> $OUTPUT 179*53130Sbostic 180*53130Sbostic fi 181*53130Sbosticdone 182*53130Sbosticif [ $umaskset = "no" -o -s $OUTPUT ] ; then 183*53130Sbostic printf "\nChecking root sh paths, umask values:\n$list\n" 184*53130Sbostic if [ -s $OUTPUT ]; then 185*53130Sbostic cat $OUTPUT 186*53130Sbostic fi 187*53130Sbostic if [ $umaskset = "no" ] ; then 188*53130Sbostic printf "\nRoot sh startup files do not set the umask.\n" 189*53130Sbostic fi 190*53130Sbosticfi 191*53130Sbostic 192*53130Sbostic# Root and uucp should both be in /etc/ftpusers. 193*53130Sbosticif egrep root /etc/ftpusers > /dev/null ; then 194*53130Sbostic : 195*53130Sbosticelse 196*53130Sbostic printf "\nRoot not listed in /etc/ftpusers file.\n" 197*53130Sbosticfi 198*53130Sbosticif egrep uucp /etc/ftpusers > /dev/null ; then 199*53130Sbostic : 200*53130Sbosticelse 201*53130Sbostic printf "\nUucp not listed in /etc/ftpusers file.\n" 202*53130Sbosticfi 203*53130Sbostic 204*53130Sbostic# Uudecode should not be in the aliases file. 205*53130Sbosticif grep -w uudecode /etc/aliases; then 206*53130Sbostic printf "\nThere is an entry for uudecode in the /etc/aliases file.\n" 207*53130Sbosticfi 208*53130Sbostic 209*53130Sbostic# Check for plus signs in /etc/hosts.equiv. 210*53130Sbosticif egrep '\+|^$' /etc/hosts.equiv > /dev/null ; then 211*53130Sbostic printf "\nEmpty line or + in /etc/hosts.equiv file.\n" 212*53130Sbosticfi 213*53130Sbostic 214*53130Sbostic# Check for special users with .rhosts files. Only root and toor should 215*53130Sbostic# have a .rhosts files. Also, .rhosts files should not have blank lines 216*53130Sbostic# or plus signs. 217*53130Sbosticawk -F: '$1 != "root" && $1 != "toor" && \ 218*53130Sbostic ($3 < 100 || $1 == "ftp" || $1 == "uucp") \ 219*53130Sbostic { print $1 " " $6 }' /etc/passwd | 220*53130Sbosticwhile read uid homedir; do 221*53130Sbostic if [ -f ${homedir}/.rhosts ] ; then 222*53130Sbostic rhost=`ls -ldgT ${homedir}/.rhosts` 223*53130Sbostic printf "$uid: $rhost\n" 224*53130Sbostic fi 225*53130Sbosticdone > $OUTPUT 226*53130Sbosticif [ -s $OUTPUT ] ; then 227*53130Sbostic printf "\nChecking for special users with .rhosts files.\n" 228*53130Sbostic cat $OUTPUT 229*53130Sbosticfi 230*53130Sbostic 231*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 232*53130Sbosticwhile read uid homedir; do 233*53130Sbostic if [ -f ${homedir}/.rhosts ] && \ 234*53130Sbostic egrep '\+|^$' ${homedir}/.rhosts > /dev/null ; then 235*53130Sbostic printf "$uid: empty line or + in .rhosts file.\n" 236*53130Sbostic fi 237*53130Sbosticdone > $OUTPUT 238*53130Sbosticif [ -s $OUTPUT ] ; then 239*53130Sbostic printf "\nChecking .rhosts files syntax.\n" 240*53130Sbostic cat $OUTPUT 241*53130Sbosticfi 242*53130Sbostic 243*53130Sbostic# Check home directories, dot files. 24453105Sbostic# Directories should not be owned by someone else or writeable. 245*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 24653105Sbosticwhile read uid homedir; do 24753105Sbostic if [ -d ${homedir}/ ] ; then 24853105Sbostic file=`ls -ldgT ${homedir}` 249*53130Sbostic printf "$uid $file\n" 25053105Sbostic fi 251*53130Sbosticdone | 252*53130Sbosticawk '$1 != $4 && $4 != "root" \ 253*53130Sbostic { print "user " $1 " home directory is owned by " $4 } 254*53130Sbostic $2 ~ /^-....w/ \ 255*53130Sbostic { print "user " $1 " home directory is group writeable" } 256*53130Sbostic $2 ~ /^-.......w/ \ 257*53130Sbostic { print "user " $1 " home directory is other writeable" }' > $OUTPUT 258*53130Sbosticif [ -s $OUTPUT ] ; then 259*53130Sbostic printf "\nChecking home directories.\n" 260*53130Sbostic cat $OUTPUT 261*53130Sbosticfi 26253105Sbostic 26353104Sbostic# Files that should not be owned by someone else or readable. 264*53130Sbosticlist=".netrc .rhosts" 265*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 26653104Sbosticwhile read uid homedir; do 267*53130Sbostic for f in $list ; do 268*53130Sbostic file=${homedir}/${f} 269*53130Sbostic if [ -f $file ] ; then 270*53130Sbostic printf "$uid $f `ls -ldgT $file`\n" 271*53130Sbostic fi 272*53130Sbostic done 273*53130Sbosticdone | 274*53130Sbosticawk '$1 != $5 && $5 != "root" \ 275*53130Sbostic { print "user " $1 " " $2 " file is owned by " $5 } 276*53130Sbostic $3 ~ /^-...r/ \ 277*53130Sbostic { print "user " $1 " " $2 " file is group readable" } 278*53130Sbostic $3 ~ /^-......r/ \ 279*53130Sbostic { print "user " $1 " " $2 " file is other readable" } 280*53130Sbostic $3 ~ /^-....w/ \ 281*53130Sbostic { print "user " $1 " " $2 " file is group writeable" } 282*53130Sbostic $3 ~ /^-.......w/ \ 283*53130Sbostic { print "user " $1 " " $2 " file is other writeable" }' > $OUTPUT 28453104Sbostic 28553104Sbostic# Files that should not be owned by someone else or writeable. 286*53130Sbosticlist=".bashrc .cshrc .emacsrc .exrc .forward .klogin .login .logout \ 287*53130Sbostic .profile .tcshrc" 288*53130Sbosticawk -F: '{ print $1 " " $6 }' /etc/passwd | \ 28953104Sbosticwhile read uid homedir; do 290*53130Sbostic for f in $list ; do 291*53130Sbostic file=${homedir}/${f} 292*53130Sbostic if [ -f $file ] ; then 293*53130Sbostic printf "$uid $f `ls -ldgT $file`\n" 294*53130Sbostic fi 295*53130Sbostic done 296*53130Sbosticdone | 297*53130Sbosticawk '$1 != $5 && $5 != "root" \ 298*53130Sbostic { print "user " $1 " " $2 " file is owned by " $5 } 299*53130Sbostic $3 ~ /^-....w/ \ 300*53130Sbostic { print "user " $1 " " $2 " file is group writeable" } 301*53130Sbostic $3 ~ /^-.......w/ \ 302*53130Sbostic { print "user " $1 " " $2 " file is other writeable" }' >> $OUTPUT 303*53130Sbosticif [ -s $OUTPUT ] ; then 304*53130Sbostic printf "\nChecking dot files.\n" 305*53130Sbostic cat $OUTPUT 306*53130Sbosticfi 30753104Sbostic 30853104Sbostic# Check mailbox ownership and permissions. 309*53130Sbosticls -l /var/mail | sed 1d | \ 310*53130Sbosticawk '$3 != $9 \ 311*53130Sbostic { print "user " $9 " mailbox is owned by " $3 } 312*53130Sbostic $1 != "-rw-------" \ 313*53130Sbostic { print "user " $9 " mailbox is " $1 ", group " $4 }' > $OUTPUT 314*53130Sbosticif [ -s $OUTPUT ] ; then 315*53130Sbostic printf "\nChecking mailbox ownership.\n" 316*53130Sbostic cat $OUTPUT 317*53130Sbosticfi 31853104Sbostic 31953105Sbostic# Check for globally exported file systems. 32053105Sbosticawk '{ 32153105Sbostic readonly = 0; 32253105Sbostic for (i = 2; i <= NF; ++i) { 32353105Sbostic if ($i ~ /-ro/) 32453105Sbostic readonly = 1; 32553105Sbostic else if ($i !~ /^-/) 32653105Sbostic next; 32753105Sbostic } 32853105Sbostic if (readonly) 32953105Sbostic print "File system " $1 " globally exported, read-only." 33053105Sbostic else 33153105Sbostic print "File system " $1 " globally exported, read-write." 332*53130Sbostic}' < /etc/exports > $OUTPUT 333*53130Sbosticif [ -s $OUTPUT ] ; then 334*53130Sbostic printf "\nChecking for globally exported file systems.\n" 335*53130Sbostic cat $OUTPUT 336*53130Sbosticfi 33753105Sbostic 33853098Sbostic# Display setuid and device changes. 339*53130Sbosticprintf "\nChecking setuid files and devices:\n" 340*53130Sbostic(find / ! -fstype local -a -prune -o \ 341*53130Sbostic \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \ 342*53130Sbostic ! -type s \) | \ 343*53130Sbosticsort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT 34442328Sbostic 34553098Sbostic# Display any errors that occurred during system file walk. 346*53130Sbosticif [ -s $OUTPUT ] ; then 347*53130Sbostic printf "Setuid/device find errors:\n" 348*53130Sbostic cat $OUTPUT 349*53130Sbostic printf "\n" 35042328Sbosticfi 35142328Sbostic 35253098Sbostic# Display any changes in the setuid file list. 353*53130Sbosticegrep -v '^[bc]' $LIST > $TMP1 35452215Sbostic 355*53130Sbosticif [ -s $TMP1 ] ; then 356*53130Sbostic # Check to make sure uudecode isn't setuid. 357*53130Sbostic if grep -w uudecode $TMP1 > /dev/null ; then 358*53130Sbostic printf "\nUudecode is setuid.\n" 359*53130Sbostic fi 360*53130Sbostic 361*53130Sbostic CUR=/var/backups/setuid.current 362*53130Sbostic BACK=/var/backups/setuid.backup 363*53130Sbostic 36453098Sbostic if [ -s $CUR ] ; then 365*53130Sbostic if cmp -s $CUR $TMP1 ; then 36652573Sbostic : 36752573Sbostic else 368*53130Sbostic > $TMP2 369*53130Sbostic join -110 -210 -v2 $CUR $TMP1 > $OUTPUT 370*53130Sbostic if [ -s $OUTPUT ] ; then 371*53130Sbostic printf "Setuid additions:\n" 372*53130Sbostic tee -a $TMP2 < $OUTPUT 373*53130Sbostic printf "\n" 37452573Sbostic fi 37552573Sbostic 376*53130Sbostic join -110 -210 -v1 $CUR $TMP1 > $OUTPUT 377*53130Sbostic if [ -s $OUTPUT ] ; then 378*53130Sbostic printf "Setuid deletions:\n" 379*53130Sbostic tee -a $TMP2 < $OUTPUT 380*53130Sbostic printf "\n" 38152573Sbostic fi 38252573Sbostic 383*53130Sbostic sort +9 $TMP2 $CUR $TMP1 | \ 384*53130Sbostic sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT 385*53130Sbostic if [ -s $OUTPUT ] ; then 386*53130Sbostic printf "Setuid changes:\n" 387*53130Sbostic column -t $OUTPUT 388*53130Sbostic printf "\n" 38952573Sbostic fi 39052573Sbostic 391*53130Sbostic cp $CUR $BACK 392*53130Sbostic cp $TMP1 $CUR 39352573Sbostic fi 39452573Sbostic else 395*53130Sbostic printf "Setuid additions:\n" 396*53130Sbostic cat $TMP1 397*53130Sbostic printf "\n" 398*53130Sbostic cp $TMP1 $CUR 39952573Sbostic fi 40052215Sbosticfi 40152215Sbostic 40253105Sbostic# Check for readable/writeable block and character disk devices. 403*53130Sbosticegrep '^b' $LIST > $TMP1 404*53130Sbosticegrep '^c.*/rdk[0-9][0-9]*[a-h]$' $LIST >> $TMP1 405*53130Sbosticegrep '^c.*/rfd[0-9][0-9]*[a-h]$' $LIST >> $TMP1 406*53130Sbosticegrep '^c.*/rhd[0-9][0-9]*[a-h]$' $LIST >> $TMP1 407*53130Sbosticegrep '^c.*/rhk[0-9][0-9]*[a-h]$' $LIST >> $TMP1 408*53130Sbosticegrep '^c.*/rhp[0-9][0-9]*[a-h]$' $LIST >> $TMP1 409*53130Sbosticegrep '^c.*/rjb[0-9][0-9]*[a-h]$' $LIST >> $TMP1 410*53130Sbosticegrep '^c.*/rkra[0-9][0-9]*[a-h]$' $LIST >> $TMP1 411*53130Sbosticegrep '^c.*/rra[0-9][0-9]*[a-h]$' $LIST >> $TMP1 412*53130Sbosticegrep '^c.*/rrb[0-9][0-9]*[a-h]$' $LIST >> $TMP1 413*53130Sbosticegrep '^c.*/rrd[0-9][0-9]*[a-h]$' $LIST >> $TMP1 414*53130Sbosticegrep '^c.*/rrl[0-9][0-9]*[a-h]$' $LIST >> $TMP1 415*53130Sbosticegrep '^c.*/rrx[0-9][0-9]*[a-h]$' $LIST >> $TMP1 416*53130Sbosticegrep '^c.*/rrz[0-9][0-9]*[a-h]$' $LIST >> $TMP1 417*53130Sbosticegrep '^c.*/rsd[0-9][0-9]*[a-h]$' $LIST >> $TMP1 418*53130Sbosticegrep '^c.*/rup[0-9][0-9]*[a-h]$' $LIST >> $TMP1 419*53130Sbosticegrep '^c.*/rwd[0-9][0-9]*[a-h]$' $LIST >> $TMP1 42053105Sbostic 421*53130Sbosticawk '$4 != "operator" \ 422*53130Sbostic { print "Disk " $11 " not owned by group operator." } 423*53130Sbostic $1 !~ /.rw-r-----/ \ 424*53130Sbostic { print "Disk " $11 " is " $1 ", group " $4 }' < $TMP1 > $OUTPUT 425*53130Sbosticif [ -s $OUTPUT ] ; then 426*53130Sbostic printf "\nChecking disk ownership and permissions.\n" 427*53130Sbostic cat $OUTPUT 428*53130Sbostic printf "\n" 429*53130Sbosticfi 43053105Sbostic 431*53130Sbosticegrep '^[bcs]' $LIST | sort +10 > $TMP1 43253098Sbostic# Display any changes in the device file list. 433*53130Sbosticif [ -s $TMP1 ] ; then 434*53130Sbostic CUR=/var/backups/device.current 435*53130Sbostic BACK=/var/backups/device.backup 43653098Sbostic 43753098Sbostic if [ -s $CUR ] ; then 438*53130Sbostic if cmp -s $CUR $TMP1 ; then 43953098Sbostic : 44053098Sbostic else 441*53130Sbostic > $TMP2 442*53130Sbostic join -111 -211 -v2 $CUR $TMP1 > $OUTPUT 443*53130Sbostic if [ -s $OUTPUT ] ; then 444*53130Sbostic printf "Device additions:\n" 445*53130Sbostic tee -a $TMP2 < $OUTPUT 446*53130Sbostic printf "\n" 44753098Sbostic fi 44853098Sbostic 449*53130Sbostic join -111 -211 -v1 $CUR $TMP1 > $OUTPUT 450*53130Sbostic if [ -s $OUTPUT ] ; then 451*53130Sbostic printf "Device deletions:\n" 452*53130Sbostic tee -a $TMP2 < $OUTPUT 453*53130Sbostic printf "\n" 45453098Sbostic fi 45553098Sbostic 456*53130Sbostic sort +10 $TMP2 $CUR $TMP1 | \ 457*53130Sbostic sed -e 's/[ ][ ]*/ /g' | \ 458*53130Sbostic awk '{ \ 459*53130Sbostic printf("%s %s %s %s %s %s %s %s %s %s %s\n", \ 460*53130Sbostic $7, $8, $9, $10, $1, $2, $3, $4, $5, $6, $11); \ 461*53130Sbostic }' | uniq -f 4 -u | \ 462*53130Sbostic awk '{ \ 463*53130Sbostic printf("%s %s %s %s %s %s %s %s %s %s %s\n", \ 464*53130Sbostic $5, $6, $7, $8, $9, $10, $1, $2, $3, $4, $11); \ 465*53130Sbostic }' > $OUTPUT 466*53130Sbostic if [ -s $OUTPUT ] ; then 467*53130Sbostic printf "Device changes:\n" 468*53130Sbostic column -t $OUTPUT 469*53130Sbostic printf "\n" 47053098Sbostic fi 47153098Sbostic 472*53130Sbostic cp $CUR $BACK 473*53130Sbostic cp $TMP1 $CUR 47453098Sbostic fi 47553098Sbostic else 476*53130Sbostic printf "Device additions:\n" 477*53130Sbostic cat $TMP1 478*53130Sbostic printf "\n" 479*53130Sbostic cp $TMP1 $CUR 48053098Sbostic fi 48153098Sbosticfi 48253098Sbostic 48352578Sbostic# Check the system binaries. 48452578Sbostic# Create the mtree tree specifications using: 48552578Sbostic# 486*53130Sbostic# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure 487*53130Sbostic# chown root.wheel DIR.SECURE 488*53130Sbostic# chmod 600 DIR.SECURE 48952578Sbostic# 49052578Sbostic# Note, this is not complete protection against Trojan horsed binaries, as 49152578Sbostic# the hacker can modify the tree specification to match the replaced binary. 49252578Sbostic# For details on really protecting yourself against modified binaries, see 49352578Sbostic# the mtree(8) manual page. 494*53130Sbostic# Check for special files. 495*53130Sbostic 49652578Sbosticif cd /etc/mtree; then 497*53130Sbostic mtree -e -p / -f /etc/mtree/special > $OUTPUT 498*53130Sbostic if [ -s $OUTPUT ] ; then 499*53130Sbostic printf "\nChecking special files and directories.\n" 500*53130Sbostic cat $OUTPUT 501*53130Sbostic fi 502*53130Sbostic 503*53130Sbostic > $OUTPUT 50452578Sbostic for file in *.secure; do 50552578Sbostic tree=`sed -n -e '3s/.* //p' -e 3q $file` 506*53130Sbostic mtree -f $file -p $tree > $TMP1 507*53130Sbostic if [ -s $TMP1 ]; then 508*53130Sbostic printf "\nChecking $tree:\n" >> $OUTPUT 509*53130Sbostic cat $TMP1 >> $OUTPUT 510*53130Sbostic fi 51152578Sbostic done 512*53130Sbostic if [ -s $OUTPUT ] ; then 513*53130Sbostic printf "\nChecking system binaries:\n" 514*53130Sbostic cat $OUTPUT 515*53130Sbostic fi 51652578Sbosticfi 517