xref: /csrg-svn/etc/security (revision 53104)
142328Sbostic#!/bin/sh -
242328Sbostic#
3*53104Sbostic#	@(#)security	5.14 (Berkeley) 03/31/92
442328Sbostic#
552578SbosticPATH=/sbin:/usr/sbin:/bin:/usr/bin
642328Sbostic
752215Sbosticumask 22
852215Sbostic
953098SbosticERR=/tmp/_secure1.$$
1053098SbosticTMP1=/tmp/_secure2.$$
1153098SbosticTMP2=/tmp/_secure3.$$
1253098SbosticLIST=/tmp/_secure4.$$
1352578Sbostic
14*53104Sbostictrap 'rm -f $ERR $TMP1 $TMP2 $LIST' 0
1552578Sbostic
16*53104Sbostic# Check uids.
1752573Sbosticecho ""
1852573Sbosticecho "Checking for uids of 0:"
19*53104Sbosticawk -F: "\$3 == 0 \
20*53104Sbostic	{ print \"user \" \$1 \" has a uid of \" \$3 }" /etc/master.passwd
2142328Sbostic
22*53104Sbostic# Check passwords.
2352151Sbosticecho ""
2452573Sbosticecho "Checking for uids without passwords:"
25*53104Sbosticawk -F: "\$2 == \"\" \
26*53104Sbostic	{ print \"user \" \$1 \" has no password\" }" /etc/master.passwd
2752573Sbostic
28*53104Sbosticecho ""
29*53104Sbosticecho "Checking for turned-off accounts with valid shells:"
30*53104Sbosticawk -F: "length(\$2) != 13 && \$10 ~ /.*sh$/ \
31*53104Sbostic	{ print \"user \" \$1 \" account turned off with valid shell.\" }" \
32*53104Sbostic	/etc/master.passwd
33*53104Sbostic
34*53104Sbostic# Check special users with .rhosts files.
35*53104Sbosticecho ""
36*53104Sbosticecho "Checking for special users with .rhosts files."
37*53104Sbosticawk -F: "\$3 < 100 || \$1 == \"ftp\" || \$1 == \"uucp\" \
38*53104Sbostic	{ print \$1 \" \" \$6 }" /etc/passwd | \
39*53104Sbostic	while read uid homedir; do
40*53104Sbostic		if [ -f ${homedir}/.rhosts ] ; then
41*53104Sbostic			rhost=`ls -lT ${homedir}/.rhosts`
42*53104Sbostic			echo "$uid: $rhost"
43*53104Sbostic		fi
44*53104Sbostic	done
45*53104Sbostic
46*53104Sbostic# Check home directories.
47*53104Sbosticecho ""
48*53104Sbosticecho "Checking user's home directories."
49*53104Sbosticecho "Checking .netrc, .rhosts."
50*53104Sbostic# Files that should not be owned by someone else or readable.
51*53104Sbosticawk -F: "{ print \$1 \" \" \$6 }" /etc/passwd | \
52*53104Sbosticwhile read uid homedir; do
53*53104Sbostic	if [ -f ${homedir}/.netrc ] ; then
54*53104Sbostic		file=`ls -lT ${homedir}/.netrc`
55*53104Sbostic		echo "$uid .netrc $file"
56*53104Sbostic	fi
57*53104Sbostic	if [ -f ${homedir}/.rhosts ] ; then
58*53104Sbostic		file=`ls -lT ${homedir}/.rhosts`
59*53104Sbostic		echo "$uid .rhosts $file"
60*53104Sbostic	fi
61*53104Sbosticdone | awk \
62*53104Sbostic	    "\$1 != \$5 && \$5 != \"root\" \
63*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is owned by \" \$5 } \
64*53104Sbostic	     \$3 ~ /^-...r/ \
65*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is group readable\" } \
66*53104Sbostic	     \$3 ~ /^-......r/ \
67*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is other readable\" } \
68*53104Sbostic	     \$3 ~ /^-....w/ \
69*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is group writeable\" } \
70*53104Sbostic	     \$3 ~ /^-.......w/ \
71*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is other writeable\" }"
72*53104Sbostic
73*53104Sbostic# Files that should not be owned by someone else or writeable.
74*53104Sbosticecho ""
75*53104Sbosticecho "Checking .cshrc, .klogin, .login, .profile."
76*53104Sbosticawk -F: "{ print \$1 \" \" \$6 }" /etc/passwd | \
77*53104Sbosticwhile read uid homedir; do
78*53104Sbostic	if [ -f ${homedir}/.cshrc ] ; then
79*53104Sbostic		file=`ls -lT ${homedir}/.cshrc`
80*53104Sbostic		echo "$uid .cshrc $file"
81*53104Sbostic	fi
82*53104Sbostic	if [ -f ${homedir}/.klogin ] ; then
83*53104Sbostic		file=`ls -lT ${homedir}/.klogin`
84*53104Sbostic		echo "$uid .klogin $file"
85*53104Sbostic	fi
86*53104Sbostic	if [ -f ${homedir}/.login ] ; then
87*53104Sbostic		file=`ls -lT ${homedir}/.login`
88*53104Sbostic		echo "$uid .login $file"
89*53104Sbostic	fi
90*53104Sbostic	if [ -f ${homedir}/.profile ] ; then
91*53104Sbostic		file=`ls -lT ${homedir}/.profile`
92*53104Sbostic		echo "$uid .profile $file"
93*53104Sbostic	fi
94*53104Sbosticdone | awk \
95*53104Sbostic	    "\$1 != \$5 && \$5 != \"root\" \
96*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is owned by \" \$5 } \
97*53104Sbostic	     \$3 ~ /^-....w/ \
98*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is group writeable\" } \
99*53104Sbostic	     \$3 ~ /^-.......w/ \
100*53104Sbostic	{ print \"user \" \$1 \"'s \" \$2 \" file is other writeable\" }"
101*53104Sbostic
102*53104Sbostic# Check mailbox ownership and permissions.
103*53104Sbosticecho ""
104*53104Sbosticecho "Checking mailbox ownership."
105*53104Sbosticls -l /var/mail | \
106*53104Sbosticawk "\$3 != \$9 \
107*53104Sbostic	{ print \"user \" \$9 \"'s mailbox is owned by \" \$3 } \
108*53104Sbostic     \$2 ~ /^-...r/ \
109*53104Sbostic	{ print \"user \" \$1 \"'s mailbox is group readable\" } \
110*53104Sbostic     \$2 ~ /^-......r/ \
111*53104Sbostic	{ print \"user \" \$1 \"'s mailbox is other readable\" } \
112*53104Sbostic     \$2 ~ /^-....w/ \
113*53104Sbostic	{ print \"user \" \$1 \"'s mailbox is group writeable\" } \
114*53104Sbostic     \$2 ~ /^-.......w/ \
115*53104Sbostic	{ print \"user \" \$1 \"'s mailbox is other writeable\" }"
116*53104Sbostic
117*53104Sbostic# Check for special files.
118*53104Sbosticecho ""
119*53104Sbosticecho "Checking dangerous files and directories."
120*53104Sbosticmtree -e -p / -f /etc/mtree/flist.secure
121*53104Sbostic
122*53104Sbostic# Check for bad paths in root startup files.
123*53104Sbosticecho ""
124*53104Sbosticecho "Checking root paths (csh startup files)."
125*53104Sbosticrhome=/root
126*53104Sbosticfor i in /etc/csh.cshrc /etc/csh.login ${rhome}/.cshrc ${rhome}/.login ; do
127*53104Sbostic	echo "$i:"
128*53104Sbostic	if [ -f $i ] ; then
129*53104Sbostic		if egrep -h -i 'path.*[^a-z]\.[^a-z]' $i > /dev/null ; then
130*53104Sbostic			echo "Root's path appears to include ."
131*53104Sbostic		fi
132*53104Sbostic		egrep -h -i path $i | \
133*53104Sbostic		awk "{ for (i = 1; i <= NF; ++i) print \$i }" | \
134*53104Sbostic		while read dir; do
135*53104Sbostic			if [ -d $dir ] ; then
136*53104Sbostic				echo `ls -ldgT $dir`
137*53104Sbostic			fi
138*53104Sbostic		done | \
139*53104Sbostic		awk "\$1 ~ /^d....w/ \
140*53104Sbostic	{ print \"Root path directory \" \$10 \" is group writeable.\" } \
141*53104Sbostic		     \$1 ~ /^d.......w/ \
142*53104Sbostic	{ print \"Root path directory \" \$10 \" is other writeable.\" }"
143*53104Sbostic	fi
144*53104Sbosticdone
145*53104Sbostic
146*53104Sbosticecho ""
147*53104Sbosticecho "Checking root paths (sh startup files)."
148*53104Sbosticfor i in ${rhome}/.profile ${rhome}/.klogin ; do
149*53104Sbostic	echo "$i:"
150*53104Sbostic	if [ -f $i ] ; then
151*53104Sbostic		if egrep -h -i 'path.*:\.:' $i > /dev/null ; then
152*53104Sbostic			echo "Root's path appears to include ."
153*53104Sbostic		fi
154*53104Sbostic		egrep -h -i 'path.*:' $i | \
155*53104Sbostic		awk -F: "{ for (i = 1; i <= NF; ++i) print \$i }" | \
156*53104Sbostic		while read dir; do
157*53104Sbostic			if [ -d $dir ] ; then
158*53104Sbostic				echo `ls -ldgT $dir`
159*53104Sbostic			fi
160*53104Sbostic		done | \
161*53104Sbostic		awk "\$1 ~ /^d....w/ \
162*53104Sbostic	{ print \"Root path directory \" \$10 \" is group writeable.\" } \
163*53104Sbostic		     \$1 ~ /^d.......w/ \
164*53104Sbostic	{ print \"Root path directory \" \$10 \" is other writeable.\" }"
165*53104Sbostic	fi
166*53104Sbosticdone
167*53104Sbostic
16853098Sbostic# Display setuid and device changes.
16952573Sbosticecho ""
17052143Sbosticecho "Checking setuid files and devices:"
17153098Sbostic(find / ! -fstype local -a -prune -o \
17252573Sbostic    \( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l \) | \
17353098Sbostic    sort | sed -e 's/^/ls -lgT /' | sh >$TMP1) 2>$ERR
17442328Sbostic
17553098Sbostic# Display any errors that occurred during system file walk.
17653098Sbosticif [ -s $ERR ] ; then
17753098Sbostic	echo "Setuid/device find errors:"
17853098Sbostic	cat $ERR
17952573Sbostic	echo ""
18042328Sbosticfi
18142328Sbostic
18253098Sbostic# Display any changes in the setuid file list.
18353098Sbosticegrep -v '^[bc]' $TMP1 > $LIST
18452573Sbosticif [ -s $LIST ] ; then
18553098Sbostic	CUR=/var/log/setuid.current
18653098Sbostic	BACK=/var/log/setuid.backup
18752215Sbostic
18853098Sbostic	if [ -s $CUR ] ; then
18953098Sbostic		if cmp -s $CUR $LIST ; then
19052573Sbostic			:
19152573Sbostic		else
19253098Sbostic			:> $TMP1
19353098Sbostic			join -110 -210 -v2 $CUR $LIST >$TMP2
19453098Sbostic			if [ -s $TMP2 ] ; then
19553098Sbostic				echo "Setuid additions:"
19653098Sbostic				tee -a $TMP1 < $TMP2
19752573Sbostic				echo ""
19852573Sbostic			fi
19952573Sbostic
20053098Sbostic			join -110 -210 -v1 $CUR $LIST >$TMP2
20153098Sbostic			if [ -s $TMP2 ] ; then
20253098Sbostic				echo "Setuid deletions:"
20353098Sbostic				tee -a $TMP1 < $TMP2
20452573Sbostic				echo ""
20552573Sbostic			fi
20652573Sbostic
20753098Sbostic			sort +9 $TMP1 $CUR $LIST | \
20853098Sbostic			    sed -e 's/[	 ][	 ]*/ /g' | uniq -u >$TMP2
20953098Sbostic			if [ -s $TMP2 ] ; then
21053098Sbostic				echo "Setuid changes:"
21153098Sbostic				column $TMP2
21252573Sbostic				echo ""
21352573Sbostic			fi
21452573Sbostic
21553098Sbostic			mv $CUR $BACK
21653098Sbostic			mv $LIST $CUR
21752573Sbostic		fi
21852573Sbostic	else
21953098Sbostic		echo "Setuid additions:"
22052573Sbostic		cat $LIST
22152573Sbostic		echo ""
22253098Sbostic		mv $LIST $CUR
22352573Sbostic	fi
22452215Sbosticfi
22552215Sbostic
22653098Sbostic# Display any changes in the device file list.
22753098Sbosticegrep '^[bc]' $TMP1 > $LIST
22853098Sbosticif [ -s $LIST ] ; then
22953098Sbostic	CUR=/var/log/device.current
23053098Sbostic	BACK=/var/log/device.backup
23153098Sbostic
23253098Sbostic	if [ -s $CUR ] ; then
23353098Sbostic		if cmp -s $CUR $LIST ; then
23453098Sbostic			:
23553098Sbostic		else
23653098Sbostic			:> $TMP1
23753098Sbostic			join -111 -211 -v2 $CUR $LIST >$TMP2
23853098Sbostic			if [ -s $TMP2 ] ; then
23953098Sbostic				echo "Device additions:"
24053098Sbostic				tee -a $TMP1 < $TMP2
24153098Sbostic				echo ""
24253098Sbostic			fi
24353098Sbostic
24453098Sbostic			join -111 -211 -v1 $CUR $LIST >$TMP2
24553098Sbostic			if [ -s $TMP2 ] ; then
24653098Sbostic				echo "Device deletions:"
24753098Sbostic				tee -a $TMP1 < $TMP2
24853098Sbostic				echo ""
24953098Sbostic			fi
25053098Sbostic
25153098Sbostic			sort +10 $TMP1 $CUR $LIST | \
25253098Sbostic			    sed -e 's/[	 ][	 ]*/ /g' | uniq -u >$TMP2
25353098Sbostic			if [ -s $TMP2 ] ; then
25453098Sbostic				echo "Device changes:"
25553098Sbostic				column $TMP2
25653098Sbostic				echo ""
25753098Sbostic			fi
25853098Sbostic
25953098Sbostic			mv $CUR $BACK
26053098Sbostic			mv $LIST $CUR
26153098Sbostic		fi
26253098Sbostic	else
26353098Sbostic		echo "Device additions:"
26453098Sbostic		cat $LIST
26553098Sbostic		echo ""
26653098Sbostic		mv $LIST $CUR
26753098Sbostic	fi
26853098Sbosticfi
26953098Sbostic
27052578Sbostic# Check the system binaries.
27152578Sbostic# Create the mtree tree specifications using:
27252578Sbostic#
273*53104Sbostic#	mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid
274*53104Sbostic#	    DIR.secure
27552578Sbostic#	chown bin.bin DIR.SECURE
27652578Sbostic#	chmod 444 DIR.SECURE
27752578Sbostic#
27852578Sbostic# Note, this is not complete protection against Trojan horsed binaries, as
27952578Sbostic# the hacker can modify the tree specification to match the replaced binary.
28052578Sbostic# For details on really protecting yourself against modified binaries, see
28152578Sbostic# the mtree(8) manual page.
28252578Sbosticif cd /etc/mtree; then
28352578Sbostic	echo ""
28452578Sbostic	echo "Checking system binaries:"
28552578Sbostic	for file in *.secure; do
28652578Sbostic		tree=`sed -n -e '3s/.* //p' -e 3q $file`
28752578Sbostic		echo ""
28852578Sbostic		echo "Checking $tree:"
28952578Sbostic		mtree -f $file -p $tree
29052578Sbostic	done
29152578Sbosticfi
292