#! /bin/sh # # secure_sun - check/fix fourteen common Sun security holes # # Written by David Safford (saff@cssun.tamu.edu) # This program has been tested to handle most # common setups; if you find a configuration # that it does not handle, please let me know. # This version is specific to SunOS 4.0.3. 4.1 # # Introduction clear echo This program checks for 14 common SunOS configuration security loopholes. echo It has been tested only on SunOS4.0.3 on Sun4, Sun3, and Sun386i machines. echo Each test reports its findings, and will offer to fix any problem found. echo The program must be run as root if you want it to fix any of the problems, echo but it can be run from any account if you reply \'n\' to any fix requests. echo The 14 checks made are: echo " " 1. Fix ttytab to disable b -s problem echo " " 2. Check /etc/hosts.equiv either null or at least no + echo " " 3. Disable tftp \(nonserver\), or add secure switch \(server\) echo " " 4. Fix rcp hole echo " " 5. Check root\'s path for . echo " " 6. Check dirs in root\'s path not writeable by others echo " " 7. Check that /etc/passwd on ypserver does not have client line echo " " 8. Check that uucp decode alias is removed from /etc/aliases echo " " 9. Check /etc/utmp not world writeable echo " " 10. Check that rexd is disabled in /etc/inetd.conf echo " " 11. Disable login shell for uucp echo " " 12. Check for null /.rhosts echo " " 13. Check for accounts with no password echo " " 14. Check for backdoor root accounts echo echo -n press enter to continue read YN clear # # 1. check_boot - check for single user boot forced login # echo TEST 1: Checking for secure single user boot... if grep -s "secure" /etc/ttytab then echo -n " " ttytab is not secure: fix it \(y/n\)? read YN if test $YN = "y" then ed - \/etc/ttytab <<- ! g/secure/s/secure// w q ! ed - \/.profile <<- ! g/login root/d w q ! fi else echo " " "/etc/ttytab" is correct fi echo -n press enter to continue read YN clear # # 2. check_hosts.equiv - check for non-null or + /etc/hosts.equiv # echo TEST 2: Checking for non-null hosts.equiv ... if test -s "/etc/hosts.equiv" then cat /etc/hosts.equiv echo -n " " "/etc/hosts.equiv" is not null. Fix \(y/n\)? read YN if test $YN = "y" then mv "/etc/hosts.equiv" "/etc/hosts.equiv.bak" else if grep -s "^+$" /etc/hosts.equiv then echo -n " " hosts.equiv has a + line!!! Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/hosts.equiv <<- ! g/^+$/d w q ! fi fi fi else echo " " "/etc/hosts.equiv" is correct. fi echo -n press enter to continue read YN clear # # 3. check_tftpd - check that tftpd is either disabled or secure # echo TEST 3: Checking /etc/inetd.conf for secure tftpd entry if test -d /tftpboot then if grep -s "in.tftpd -s" /etc/inetd.conf then echo " " secure for server else echo -n " " Tftp not secure for server. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/inetd.conf <<- ! g/^tftp/s/in\.tftpd$/in.tftpd -s tftpboot/ w q ! fi fi else if grep -s "^#tftp" /etc/inetd.conf then echo " " secure nonserver else echo -n " " Tftp not secure for nonserver. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/inetd.conf <<- ! g/^tftp/s/tftp/#tftp/ w q ! fi fi fi echo -n press enter to continue read YN clear # # 4. check rcp - ensure rcp hole disabled # echo Test 4: checking that rcp hole disabled echo " " Testing /etc/passwd if grep "^nobody:\*:-2" /etc/passwd |grep -s ':$' then echo -n " " rcp hole not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/passwd <<- ! /^nobody/s/-2:-2::\/:/32767:32767:disable:\/disable:\/disable/ w q ! fi else echo " " rcp hole disabled in passwd fi if test -s /etc/yppasswd then echo " " Testing /etc/yppasswd if grep "^nobody:\*:-2" /etc/yppasswd |grep -s ':$' then echo -n " " rcp hole not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/yppasswd <<- ! /^nobody/s/-2:-2::\/:/32767:32767:disable:\/disable:\/disable/ w q ! fi else echo " " rcp hole disabled in yppasswd fi fi echo -n press enter to continue read YN clear # # 5. check_path - check root's path for . # echo TEST 5: Checking root\'s path for "." ... if grep -i -s "path[^\.]*\." /.login then echo -n " " "/.login" path contains "." Fix \(y/n\)? read YN if test $YN = "y" then if grep -s " path" /.login then ed - "/.login" <<- ! / path/ s/\.// w q ! elif grep -s "PATH" /.login then ed - "/.login" <<- ! /PATH/ s/\.// w q ! fi fi else echo " " "/.login" path is correct fi if grep -i -s "path[^\.]*\." /.cshrc then echo -n " " "/.cshrc" path contains "." Fix \(y/n\)? read YN if test $YN = "y" then if grep -s " path" /.cshrc then ed - "/.cshrc" <<- ! / path/ s/\.// w q ! elif grep -s "PATH" /.cshrc then ed - "/.cshrc" <<- ! /PATH/ s/\.// w q ! fi fi else echo " " "/.cshrc" path is correct fi if grep -i -s "path[^\.]*\." /.profile then echo -n " " "/.profile" path contains "." Fix \(y/n\)? read YN if test $YN = "y" then if grep -s " path" /.profile then ed - "/.profile" <<- ! / path/ s/\.// w q ! elif grep -s "PATH" /.profile then ed - "/.profile" <<- ! /PATH/ s/\.// w q ! fi fi else echo " " "/.profile" path is correct fi echo -n press enter to continue read YN clear # # 6. check_write - check directories in roots path for writeability # echo TEST 6: Checking your path for user writeable directories... IFS=: for DIR in $PATH do if test -d $DIR then cd $DIR if ls -dl . | grep -s "^........w" then echo -n " " $DIR is writeable by world. FIX \(y/n\)? read YN if test $YN = "y" then chmod o-w . fi else echo " " $DIR is not writable by world. fi if ls -dl . | grep -s "^.....w" then echo -n " " $DIR is writeable by group. FIX \(y/n\)? read YN if test $YN = "y" then chmod g-w . fi else echo " " $DIR is not writeable by group. fi else echo " " $DIR is not a directory! fi done echo -n press enter to continue read YN clear # # 7. check_ypserv - check passwd file for ypclient line on ypserver # echo The following test may be incompatible on the Sun 386i series. echo It is probably safest to reply \'n\' if it reports a problem on a 386i. echo TEST 7: Checking YP entries in /etc/passwd... if ps -ax|grep ypserv|grep -s -v grep then if grep -s "+::0:0:" /etc/passwd then echo " " This machine is a ypserver, and has the ypclient echo -n " " line in /etc/passwd. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/passwd <<- ! g/^+::0:0:/d w q ! fi else echo " " YP password entries correct. fi else echo " " YP password entries correct. fi echo -n press enter to continue read YN clear # # 8. check_/etc/aliases for decode alias, and remove # echo Test 8: checking that decode alias is removed if grep -s "^decode" /etc/aliases then echo -n " " decode not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/aliases <<- ! g/^decode/d w q ! fi else echo " " decode disabled fi echo -n press enter to continue read YN clear # # 9. check_/etc/utmp - if world writeable, fix # echo NOTE: the following fix will interefere with normal use of sunview. echo Apply this fix only on a server, or give all valid users echo group write access to /etc/utmp. echo echo Test 9: testing that /etc/utmp not writeable by world if ls -l /etc/utmp |grep -s "^........w" then echo -n " " utmp writeable. Fix \(y/n\)? read YN if test $YN = "y" then chmod o-w /etc/utmp fi else echo " " utmp correct. fi echo -n press enter to continue read YN clear # # 10. check_rexd - ensure rexd disabled in /etc/inetd.conf # echo Test 10: checking that rexd is disabled if grep -s "^#rexd" /etc/inetd.conf then echo " " rexd disabled else echo -n " " rexd not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/inetd.conf <<- ! g/^rexd/s/rexd/#rexd/ w q ! fi fi echo -n press enter to continue read YN clear # # 11. check_uucp - ensure uucp login shell disabled # echo Test 11: checking that uucp login shell is disabled echo " " Testing /etc/passwd if grep "^uucp" /etc/passwd |grep -s ':$' then echo -n " " uucp login shell not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/passwd <<- ! /^uucp a /disabled . /^uucp j w q ! fi else echo " " uucp login shell disabled fi if test -s /etc/yppasswd then echo " " Testing /etc/yppasswd if grep "^uucp" /etc/yppasswd |grep -s ':$' then echo -n " " uucp login shell not disabled. Fix \(y/n\)? read YN if test $YN = "y" then ed - /etc/yppasswd <<- ! /^uucp a /disabled . /^uucp j w q ! fi else echo " " uucp login shell disabled fi fi echo -n press enter to continue read YN clear # # 12. check_rhosts - check for non-null /.rhosts # echo TEST 12: Checking for non-null root .rhosts... if test -s "/.rhosts" then cat /.rhosts echo -n " " "/.rhosts" is not null. Fix \(y/n\)? read YN if test $YN = "y" then mv "/.rhosts" "/.rhosts.bak" else if grep -s "^+$" /.rhosts then echo -n " " /.rhosts has a + line!!! Fix \(y/n\)? read YN if test $YN = "y" then ed - /.rhosts <<- ! g/^+$/d w q ! fi fi fi else echo " " "/.rhosts" is correct. fi echo -n press enter to continue read YN clear # # 13. check_nopasswd - check that all accounts have passwords # (except sync, which should have no password) # echo TEST 13: Checking accounts for passwords... echo " " Checking /etc/passwd if grep "^[^:]*::" /etc/passwd |egrep -v '(sync:|ftp:|\+:)' then echo -n " " The above are accounts with no password. Lock \(y/n\)? read YN if test $YN = "y" then ed - /etc/passwd <<- ! g/^[^:]*::/s/::/:*:/ g/^sync:*:/s/:\*:/::/ w g/^+:/s/:\*/:/ w g/^ftp:/s/:\*/:/ w q ! fi else echo " " All accounts have passwords fi if test -s /etc/yppasswd then echo " " Checking /etc/yppasswd if grep "^[^:]*::" /etc/yppasswd |egrep -v '(sync:|ftp:|\+:)' then echo -n " " The above are accounts with no password. Lock \(y/n\)? read YN if test $YN = "y" then ed - /etc/yppasswd <<- ! g/^[^:]*::/s/::/:*:/ g/^sync:*:/s/:\*:/::/ w g/^+:/s/:\*/:/ w g/^ftp:/s/:\*/:/ w q ! fi else echo " " All accounts have passwords fi fi echo -n press enter to continue read YN clear # # 14. check_backdoor - check passwd file for users with 0 pid # (except root and sysdiag which must be 0) # echo TEST 14: Checking for backdoor accounts... echo " " Checking /etc/passwd if grep "^[^:]*:[^:]*:0:" /etc/passwd |egrep -v '(root:|sysdiag:|\+:)' then echo -n " " The above are accounts with root id. Lock \(y/n\)? read YN if test $YN = "y" then ed - /etc/passwd <<- ! g/^[^:]*:[^:]*:0:/s/:/:*/ g/^root:/s/:\*/:/ g/^sysdiag:/s/:\*/:/ w g/^+:/s/:\*/:/ w q ! fi else echo " " There are no back door accounts. fi if test -s /etc/yppasswd then echo " " Checking /etc/yppasswd if grep "^[^:]*:[^:]*:0:" /etc/yppasswd |egrep -v '(root:|sysdiag:|\+:)' then echo -n " " The above are accounts with root id. Lock \(y/n\)? read YN if test $YN = "y" then ed - /etc/yppasswd <<- ! g/^[^:]*:[^:]*:0:/s/:/:*/ g/^root:/s/:\*/:/ g/^sysdiag:/s/:\*/:/ w g/^+:/s/:\*/:/ w q ! fi else echo " " There are no back door accounts. fi fi echo If any fixes were made, and this machine is a ypserver, be sure echo to run ypmake \(cd /var/yp\;make\)