home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
c
/
cops_104.zip
/
cops_104
/
suid.chk
< prev
next >
Wrap
Text File
|
1992-03-10
|
7KB
|
250 lines
:
#
# Usage: suid.chk [-s secure_dir] [-S start_dir] [-m user] [-o file] [-n] [-x]
#
#
# Shell script intended to be run periodically by cron in order
# to spot changes in files with the suid or sgid bits set.
#
# suid.chk 840919 Prentiss Riddle
#
# This changes into the $SECURE directory first, then
# uses find(1) to search the directories in $SEARCH for all
# files with the 4000 or 2000 permission bits set. $STOP is a file
# containing "ls -lga" output for known setuid or setgid programs.
# Any additions or changes to this list represent potential security
# problems, so they are reported to the users named in $INFORM.
#
# [-m user] mail to user specified here.
#
# [-n] Do *not* follow NFS mounted partitions. This probably won't
# work on most machines -- check the string; this works on a
# sun: "-type d \( -fstype nfs -prune \)"; you can send me
# what works on your machine.
#
# [-o file] Write results to this file instead of mailing.
#
# [-s secure_dir] Set the secure dir, good for running this in cron --
# else it'll think it's "/", and you'll chmod that to 700 :-)
#
# [-S search_dir] Start the "find" here, instead of the default "/"
#
# [-x] Look for strangely named files, too. Really primative right
# now; I'm pondering what to do with this. Ideally, you'd pass
# all the files through a filter (preferably perl), but then I'd
# have to rethink the general suid finding stuff, or do a separate
# find. Yuck, both ways. I have a perl filter that does the
# right thing, or close to it; it's in "extra_src/bad_dir.pl".
# You say something like: "find $1 -exec perl ./bad_dir.pl {} \;"
#
# Lots of changes by dan:
# Changed the program/doc names and some of the temp files to
# make it fit in with the rest of the programs, flags SUID shell
# scripts and world writeable SUID files, too, added command line
# flags, look for strange files, etc.
# CHANGE THIS LINE!
INFORM="foo@bar.edu"
#
TEST=/bin/test
ECHO=/bin/echo
LS=/bin/ls
CAT=/bin/cat
CP=/bin/cp
MAIL=/bin/mail
CHMOD=/bin/chmod
SORT=/usr/bin/sort
COMM=/usr/bin/comm
FIND=/usr/bin/find
RM=/bin/rm
MV=/bin/mv
AWK=/bin/awk
SED=/bin/sed
GREP=/bin/grep
EGREP=/usr/bin/egrep
YPCAT=/usr/bin/ypcat
DATE=/bin/date
NONFS=false
# Arg stuff:
while $TEST $# != 0 ; do
case "$1" in
-m) INFORM=$2 ; shift ;;
-n) NONFS=true ;;
-o) OUTFILE=$2 ; shift ;;
-s) SECURE=$2 ; shift ;;
-S) SEARCH=$2 ; shift ;;
-x) STRANGE=true ;;
*) $ECHO "Usage $0 [-s secure_dir] [-m user] [-o outfile] [-n] [-x]" ; exit 2 ; ;;
esac
shift
done
# Checking for non-executable SUID files;
#
# simple way; just see if file says it's a script -- this is a *definite*
# no-no, and the default:
# type_filter="$GREP script"
#
# Safer/paranoid way; anything but an executable is flagged (may not be
# good over NFS mounts with different binaries...
# type_filter="$GREP -v xecut"
#
# You may want to grep out "ermission" string, too, in case NFS mount
# stuff that you can't read gives you "permission denied", even as root:
# type_filter="$EGREP"' -v '"xecut|ermiss"
#
type_filter="$GREP script"
# did you use the -s option?
if $TEST -z "$SECURE" ; then
SECURE=.
fi
if $TEST -z "$SEARCH" ; then
SEARCH=/
fi
#
# Warning messages used below:
WARN_NEW="These files are newly setuid/setgid"
WARN_NO="These files are no longer setuid/setgid"
# Strange stuff; "..." directories, etc.
if $TEST "$STRANGE" = "true" ; then
STRANGE_DIRS="-o -type d ( ! -name '.' -a ! -name '..' \
-a ! -name '[A-z0-9]*' -a ! -name '.[A-z0-9]*' )"
WARN_NO=$WARN_NO"/strange"
WARN_NEW=$WARN_NEW"/strange"
fi
# Yellow Pages check further down...
etc_passwd=/etc/passwd
STOP=./suid.stop
TEMPOLD=./fsold$$
TEMPCUR=./fscur$$
TEMPNEW=./fsnew$$
TEMPGON=./fsgon$$
TEMPM=./fsm$$
umask 077
OLDCWD=`pwd`
if $TEST ! -d "$SECURE" ; then
$ECHO "Error -- Security directory $SECURE doesn't exist"
exit 1
fi
$CHMOD 700 $SECURE
cd $SECURE
#
# The actual Find! Never thought you'd make it, eh?
#
if $TEST "$NONFS" = "false" ; then
$FIND $SEARCH -type f \( -perm -4000 -o -perm -2000 \) $STRANGE_DIRS \
-exec $LS -ldga {} \; | $SORT > $TEMPCUR
else
# this is the trouble spot:
$FIND $SEARCH -type d \( -fstype nfs -prune \) -o \
-type f \( -perm -4000 -o -perm -2000 \) $STRANGE_DIRS \
-exec $LS -ldga {} \; | $SORT > $TEMPCUR
fi
# find the setuid programs and sort
# compare with the sorted stop list
if $TEST ! -f "$STOP" ; then
$CP /dev/null $TEMPOLD
else
$SORT <$STOP >$TEMPOLD
fi
$COMM -13 $TEMPOLD $TEMPCUR | $SORT +8 >$TEMPNEW
$COMM -23 $TEMPOLD $TEMPCUR | $SORT +8 >$TEMPGON
# report changes
if $TEST -s $TEMPNEW -o -f $TEMPGON; then
# YP? Thanks again, to Rob Kolstad...
# Scratch files for testing:
yp_passwd=./ypsuid.$$
# generic test to check for yp use?
if $TEST -f $YPCAT -a -s $YPCAT ; then
$YPCAT passwd > $yp_passwd
if $TEST $? -eq 0 ; then
etc_passwd=$yp_passwd
fi
fi
# get the hostname:
if $TEST -s /bin/hostname ; then
HOSTNAME=`/bin/hostname`
elif $TEST -s /bin/uname ; then
HOSTNAME=`/bin/uname -n`
elif $TEST -s /usr/bin/uuname ; then
HOSTNAME=`/usr/bin/uuname -l`
fi
if $TEST -z "$HOSTNAME" ; then
HOSTNAME="foobar"
fi
$ECHO >>$TEMPM
$ECHO ATTENTION: >> $TEMPM
$ECHO "SUID Security Report for "`$DATE`>> $TEMPM
$ECHO "from host $HOSTNAME" >> $TEMPM
$ECHO >>$TEMPM
# NEW STUFF... $TEMPNEW holds the new SUID files; stuff the results in $TEMPM:
for i in `$AWK '{print $NF}' $TEMPNEW`
do
# don't want SUID files to be world writable!
./is_able $i w w >> $TEMPM
type=`file "$i" | $SED 's/.*://' | $type_filter`
if $TEST -n "$type" ; then
owner=`$LS -ldga $i | $AWK '{print $3}'`
uid=`$AWK -F: '/^'"$owner"'/{print $3}' $etc_passwd`
# set to nobody, if can't find 'em in the password file
if $TEST -z "$uid" ; then
uid="-2"
fi
if $TEST "$uid" -eq "0" ; then
$ECHO Warning! ROOT owned SUID file $i is type: $type! >> $TEMPM
else
$ECHO Warning! User: $owner SUID file $i is type: $type! >> $TEMPM
fi
fi
done
if $TEST -s $TEMPNEW; then
$ECHO $WARN_NEW":" >>$TEMPM
$ECHO '' >>$TEMPM
$CAT $TEMPNEW >>$TEMPM
$ECHO '' >>$TEMPM
fi
if $TEST -s $TEMPGON; then
$ECHO $WARN_NO":" >>$TEMPM
$ECHO '' >>$TEMPM
$CAT $TEMPGON >>$TEMPM
fi
# mail or save to a file?
if $TEST -z "$OUTFILE" ; then
$MAIL $INFORM <$TEMPM
else
$MV $TEMPM $OUTFILE
fi
$RM -f $TEMPM
fi
$RM -f $TEMPOLD $TEMPCUR $TEMPNEW $TEMPGON $yp_passwd
# end it all....
exit 0