[comp.unix.wizards] Unix security automating script

hendrik@zeusa.UUCP (Hendrik Vermooten) (03/19/90)

This script is used to try and improve a system's security. Go through the
commands and you'll see what is done.

The challenge is this: who has more and/or better ideas to improve this
thing? Please mail me your [tested] suggestions, and I'll send in some
follow-up articles.

 *** ***     Hendrik Vermooten, ZEUS software
 * o o *     Bang: ..!uunet!ddsw1!olsa99!zeusa!hendrik
O|  I  |O    or hendrik@zeusa.UUCP
 | *** |
 \*****/

# Security checking script.
#
# Hendrik Vermooten, ZEUS software  (No copyright)
#    hendrik@zeusa.UUCP
#    ..!uunet!ddsw1!olsa99!zeusa!hendrik
#
DIR=/u/security
CRONDIR=/usr/spool/cron/crontabs
UUCPDIR=/usr/lib/uucp
echo "*** Hendrik's UNIX security check script ***"
date
echo ""
echo "* Logins with super user privileges:"
awk 'BEGIN { FS=":" } { if ($3 == "0" || $3 == "") print $1 }' < /etc/passwd
echo ""
#
echo "* Logins without passwords:"
awk 'BEGIN { FS=":" } { if ($2 == "") print $1 }' < /etc/passwd
echo ""

# Check changes to passwd file
echo "* Changes to /etc/passwd since `cat $DIR/prevrun`"
diff /etc/passwd $DIR/passwd
cp /etc/passwd $DIR/passwd
echo "* Changes to /etc/group since `cat $DIR/prevrun`"
diff /etc/group $DIR/group
cp /etc/group $DIR/group
echo ""

# Check writeability of /etc/passwd
ls -l /etc/passwd | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
ls -l /etc/group | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
ls -l /etc/rc | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
ls -l $CRONDIR/root | grep -v "^-rw-------" && echo "WARNING: Check this file's access mode!"
if [ -f $CRONDIR/bin ]
	then
		ls -l $CRONDIR/bin | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
	fi

# If someone has changed root or bin crontabs, they can get in.
# This section is not working yet, because I haven't figured out how to pass
#  shell variables as variables to 'awk' below.
# echo ""
# ls $CRONDIR | sort > $DIR/newcron
# ls $DIR/crons | sort > $DIR/oldcron
# echo "* New crontab files:"
# diff $DIR/oldcron $DIR/newcron | grep "^>"
# echo "* Changes to crontab files:"
# ls $CRONDIR/* | awk '{ printf "echo %s:\ndiff %s/crons/%s %s/%s\n", $1, $DIR, $1, $CRONDIR, $1 }' | /bin/sh

rm $DIR/newcron
rm $DIR/oldcron
mkdir $DIR/crons 2> /dev/null
cp $CRONDIR/* $DIR/crons

echo ""
echo "* UUCP security:"
echo "'Systems' file changes:"
diff $UUCPDIR/Systems $DIR/Systems
cp $UUCPDIR/Systems $DIR/Systems
echo "'Permissions' file changes:"
diff $UUCPDIR/Permissions $DIR/Permissions
cp $UUCPDIR/Permissions $DIR/Permissions

#
# It would be nice to have full path names in the next two reports. But how?
#
echo ""
echo "* Directories that can be written to by everyone:"
ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
echo ""
echo "* Directories with search permissions for everyone:"
ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'

# Check Set UIDs & GIDs: I left the most important check till last
mv $DIR/setuids $DIR/setuids.prev
find / \( -perm -4000 -o -perm -2000 \) -exec ls -ld {} \; | sort > $DIR/setuids
echo "* Set UID status that have been enabled since `cat $DIR/prevrun`"
diff $DIR/setuids.prev $DIR/setuids | grep "^>"

date > $DIR/prevrun
chown root $DIR/*
chmod 600 $DIR/*
chmod 700 $DIR
chmod +x $DIR/$0

# Other checks:
#   Changes to files under /etc/rc.d/*

konczal@mail-gw.ncsl.nist.gov (Joseph C. Konczal) (03/21/90)

| #
| # It would be nice to have full path names in the next two reports. But how?
| #
| echo ""
| echo "* Directories that can be written to by everyone:"
| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
| echo ""
| echo "* Directories with search permissions for everyone:"
| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'

Replace the ls ... lines with:

find / -type d -perm -0002 -print

find / -type d -perm -0001 -print

This works under SunOS 4.0, 4.3 BSD, and 4.4 BSD; I don't know about
Sys. V.  You can replace "-print" with "-ls" to get more information
about each directory.

Joe Konczal

gentry@kcdev.UUCP (Art Gentry) (03/22/90)

In article <22817@adm.BRL.MIL> konczal@mail-gw.ncsl.nist.gov (Joseph C. Konczal) writes:
>| #
>| # It would be nice to have full path names in the next two reports. But how?
>| #
>| echo ""
>| echo "* Directories that can be written to by everyone:"
>| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
>| echo ""
>| echo "* Directories with search permissions for everyone:"
>| ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
>
>Replace the ls ... lines with:
>
>find / -type d -perm -0002 -print
>
>find / -type d -perm -0001 -print
>
>This works under SunOS 4.0, 4.3 BSD, and 4.4 BSD; I don't know about
>Sys. V.  You can replace "-print" with "-ls" to get more information
>about each directory.
>


To do this under SysV use:


find / -type d -perm -002 -print
                      ^^^
and

find / -type d -perm -001 -print
                      ^^^






  [dead space to satisfy postnews <grrrrrrrrrr>]







-- 
| R. Arthur Gentry     AT&T Communications     Kansas City, MO     64106 |
| Email: gentry@kcdev.uucp          ATTMail: attmail!kc4rtm!gentry       |
| The UNIX BBS: 816-221-0475        The Bedroom BBS: 816-637-4183        |
| $include {std_disclaimer.h}       "I will make a quess" - Spock - STIV |

news@haddock.ima.isc.com (overhead) (03/23/90)

In article <1083@kcdev.UUCP> gentry@kcdev. (Art Gentry) writes:
>  [dead space to satisfy postnews <grrrrrrrrrr>]
If you _must_ quote so much material, edit the angle bracket to some
other character.  Then you will not need the dead space also.

Jim

guy@auspex.auspex.com (Guy Harris) (03/23/90)

>>find / -type d -perm -0002 -print

	...

>To do this under SysV use:
>
>
>find / -type d -perm -002 -print
>                      ^^^

Are you trying to say that you need to use a different number of leading
zeroes in System V?  I just checked the 4.3BSD "find" and the System V
Release 3 "find", and the code that handles the "-perm" option when
parsing the command line, and that executes the "perm" test when doing
the tree walk, is *identical* in the two versions of "find" (as in "the
only difference in the source code, if any, is in white space between C
tokens" - the comparison code I was using ignores white space, including
new lines). 

What the *documentation* says is:

     -perm onum     True if the  file  permission  flags  exactly
                    match  the octal number onum (see chmod(1V)).
                    If onum is prefixed by  a  minus  sign,  more
                    flag bits (017777, see chmod(1V)) become sig-
                    nificant  and   the   flags   are   compared:
                    (flags&onum)==onum.

which doesn't say bugger all about leading zeroes - all it talks about
is a leading "-".  The code (in both versions of "find", natch) *always*
treats the argument as an octal number (just as the documentation
says!), and doesn't treat leading zeroes specially.

hendrik@zeusa.UUCP (Hendrik Vermooten) (03/23/90)

I refer back to a UNIX security checking script that I posted a while ago.
There were plenty replies to that one! Thanks for everybody that gave more
ideas. I incorporated most of the ideas into this one.

The idea behind this script is to point out potential security holes in your
system. If anybody has *even more* ideas, please mail to me, or if it isn't
a lot, post it. If enough stuff arrives, I'll post it again.

-------------- Cut here ---------------
# Security checking script.
#
# Hendrik Vermooten, ZEUS software  (No copyright)
#    hendrik@zeusa.UUCP
#    ..!uunet!ddsw1!olsa99!zeusa!hendrik
#
# Thanks for all the tips on passing shell variables to awk scripts.
#
# Originally posted by hendrik@zeusa.UUCP, with help & suggestions from:
#   (There were 4 more: I threw away my mail by mistake! Sorry guys!)
# riacs!rutgers!coat.com!andyb (Andy Behrens)
# uwm!swbatl.SWBT.COM!dwn (David Neill-OKCy Mktg 405-278-4007)
# riacs!rutgers!ux1.cso.uiuc.edu!hugh%slee01 (Hugh Fader)
# Joseph C. Konczal <uunet!mail-gw.ncsl.nist.gov!konczal>
# riacs!rutgers!gouldfr.encore.fr!kstock (Kevin Stock)
# "Michael J. Chinni, SMCAR-CCS-E" <!uunet!PICA.ARMY.MIL!mchinni>
# uunet!ddsw1!olsa99!oct1!cside1!mike (Mike Morris)
# Paul Smee <uunet!bris.ac.uk!P.Smee>
#
# BSD suggestions from:
#   "Michael J. Chinni, SMCAR-CCS-E" <!uunet!PICA.ARMY.MIL!mchinni>
# Change the next line to BSD=1 for BSD systems
BSD=0
# This is the directory where this utility lives:
DIR=/u/security
CRONDIR=/usr/spool/cron/crontabs
UUCPDIR=/usr/lib/uucp
# This line, for skipping NFS directories, didn't work on my (XENIX) system:
# FSTYPE="\( -fstype nfs -prune \) -o "
FSTYPE=""
echo "*** Hendrik's UNIX security check script ***"
date
echo ""
echo "* Logins with super user privileges:"
awk 'BEGIN { FS=":" } { if ($3 == "0" || $3 == "") print $1 }' < /etc/passwd
echo ""
#
echo "* Logins without passwords:"
awk 'BEGIN { FS=":" } { if ($2 == "") print $1 }' < /etc/passwd
# Next line from: Paul Smee <uunet!bris.ac.uk!P.Smee>
awk 'BEGIN { FS=":" } (NF<2) {print "Blank or incomplete entry, line ", NR}' < /etc/passwd
echo ""

# Check changes to passwd file
echo "* Changes to /etc/passwd since `cat $DIR/prevrun`:"
diff /etc/passwd $DIR/passwd
cp /etc/passwd $DIR/passwd
echo "* Changes to /etc/group since `cat $DIR/prevrun`:"
diff /etc/group $DIR/group
cp /etc/group $DIR/group
echo ""

# Check writeability of /etc/passwd
ls -l /etc/passwd | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
ls -l /etc/group | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
ls -l /etc/rc | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
if [ $BSD -eq 1 ]
then
	ls -l /usr/lib/crontab | grep -v "^-rw-------" && echo "WARNING: Check this file's access mode!"
	ls -l /etc/rc.boot | grep -v "^-rw-------" && echo "WARNING: Check this file's access mode!"
	ls -l /etc/rc.local | grep -v "^-rw-------" && echo "WARNING: Check this file's access mode!"
else
	ls -l $CRONDIR/root | grep -v "^-rw-------" && echo "WARNING: Check this file's access mode!"
	if [ -f $CRONDIR/bin ]
		then
			ls -l $CRONDIR/bin | grep -v "^-rw-r--r--" && echo "WARNING: Check this file's access mode!"
		fi
fi

# If someone has changed root or bin crontabs, they can get in.
# Thanks to ddsw1!riacs!rutgers!ux1.cso.uiuc.edu!hugh%slee01 (Hugh Fader)
echo ""
if [ $BSD -eq 1 ]
then
	echo "* Changes to /usr/lib/crontab since `cat $DIR/prevrun`"
	diff /usr/lib/crontab $DIR/crontab
	cp /usr/lib/crontab $DIR/crontab
	echo ""
	echo "* Changes to /etc/rc.boot since `cat $DIR/prevrun`"
	diff /etc/rc.boot $DIR/rc.boot
	cp /etc/rc.boot $DIR/rc.boot
	echo ""
	echo "* Changes to /etc/rc.local since `cat $DIR/prevrun`"
	diff /etc/rc.local $DIR/rc.local
	cp /etc/rc.local $DIR/rc.local
	echo ""
else
# System V
	ls $CRONDIR | sort > $DIR/newcron
	ls $DIR/crons | sort > $DIR/oldcron
	echo "* New crontab files:"
	diff $DIR/oldcron $DIR/newcron | grep "^>"
	echo "* Changes to crontab files:"
	for i in $DIR/crons/*; do
		user=`basename $i`
		diff $i $CRONDIR/$user > $DIR/crondiffs
		if [ $? -ne 0 ]; then
	 		echo "* $user: "
	 		cat $DIR/crondiffs
		fi
	done
	rm $DIR/crondiffs
	rm $DIR/newcron
	rm $DIR/oldcron
	mkdir $DIR/crons 2> /dev/null
	cp $CRONDIR/* $DIR/crons
fi

# Naughty hackers might try to change their uucp access rights:
#
echo ""
echo "* UUCP security:"
if [ -f $UUCPDIR/L.sys ]
	then
		echo "'L.sys' file changes:"
		diff $UUCPDIR/L.sys $DIR/L.sys
		cp $UUCPDIR/L.sys $DIR/L.sys
	fi
if [ -f $UUCPDIR/Systems ]
	then
		echo "'Systems' file changes:"
		diff $UUCPDIR/Systems $DIR/Systems
		cp $UUCPDIR/Systems $DIR/Systems
	fi
if [ -f $UUCPDIR/Permissions ]
	then
		echo "'Permissions' file changes:"
		diff $UUCPDIR/Permissions $DIR/Permissions
		cp $UUCPDIR/Permissions $DIR/Permissions
	fi

#
# It would be nice to have full path names in the next two reports. But how?
# Thanks to ddsw1!riacs!rutgers!ux1.cso.uiuc.edu!hugh%slee01 (Hugh Fader):
# > With the find command that's how. Notice the -fstype clause causes skips
# > over nfs directories. The two finds could probably be combined.
#
echo ""
echo "* Directories that can be written to by everyone:"
ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
# My find doesn't have the -ls option. If you have, try using:
# find / -ls | awk '/d[rwx]......w[x-]/ { print }'
echo ""
echo "* Directories with search permissions for everyone:"
ls -lR / | awk '/^d[rwx]......w[x-]/ { print }'
# My find doesn't have the -ls option. If you have, try using:
#find / $FSTYPE -ls | awk '/d[rwx]......w[x-]/ { print }'

# Check Set UIDs & GIDs: I left the most important check till last
# Thanks to ddsw1!riacs!rutgers!ux1.cso.uiuc.edu!hugh%slee01 (Hugh Fader):
#   Skips over NFS directories
mv $DIR/setuids $DIR/setuids.prev
find / $FSTYPE \( -perm -4000 -o -perm -2000 \) -exec ls -l {} \; | sort > $DIR/setuids
echo "* Set UID status that have been enabled since `cat $DIR/prevrun`"
diff $DIR/setuids.prev $DIR/setuids | grep "^>"

grep "^-[rwx]......w" $DIR/setuids && echo "* Set UID executeables that are writeable by Other"
grep "^-[rwx]...w" $DIR/setuids && echo "* Set UID executeables that are writeable by the group"

date > $DIR/prevrun
chown root $DIR/*
chmod 600 $DIR/*
chmod 700 $DIR
chmod +x $DIR/$0

# Other checks:
#   Changes to files under /etc/rc.d/*

#   Check only for set UID/GID to bin & root?
-------------- Cut here ---------------

 *** ***     Hendrik Vermooten, ZEUS software
 * o o *     Bang: ..!uunet!ddsw1!olsa99!zeusa!hendrik
O|  I  |O    or hendrik@zeusa.UUCP
 | *** |
 \*****/