# @(#)69 1.20.1.1 src/bos/usr/lib/security/CC_EVALify.sh, cmdsadm, bos720 7/14/11 17:25:19 # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # bos720 src/bos/usr/lib/security/CC_EVALify.sh 1.20.1.1 # # Licensed Materials - Property of IBM # # Restricted Materials of IBM # # COPYRIGHT International Business Machines Corp. 2002,2011 # All Rights Reserved # # US Government Users Restricted Rights - Use, duplication or # disclosure restricted by GSA ADP Schedule Contract with IBM Corp. # # IBM_PROLOG_END_TAG # # NAME: CC_EVALify.sh # # DESCRIPTION: # Perform the steps needed to modify a base-installed system # to conform to the Target of Evaluation for the Common # Criteria evaluation. # # Finish Common Criteria technology configuration: # # 1). Remove /dev/echo from /etc/pse.conf # 2). Instantiate streams devices # 3). Set permissions on BSD-style ptys to 000 # 4). Remove non-CC entries from inetd.conf # 5). Update CC status in sysck.cfg # 6). Change device permissions # 7). Remove suid/sgid permission bits from non-trusted commands. # 8). Remove ALLOW_ALL from non-trusted commands in privcmds. # 9). Run aixpert -l low for security hardening. # 10). Remove TCB bit from volatile data files # 11). NFS port (2049) is a privileged port # 12). Change websm to 9090 in /etc/security/priv # 13). Add the default dacinet ACL # 14). Make sure that the loopback interface is up # 15). Create synonyms for /dev/console. # 16). Enforce default X server connection permissions # 17). Add ODM stanzas to set the console permissions # 18). Disable sendmail, IMNsearch, tunrestore, xwlm, writesrv, snmp, rsct. # 19). Remove perfvmmstat and ipcs_perf # 20). Add netrules for Trusted AIX # umask 077 unset PATH export PATH=/usr/bin:/etc:/usr/sbin:/sbin:/usr/ucb #Get the TCB state and save it tcb_enabled=`/usr/bin/odmget -q deflt=tcb_enabled PdAt` #Get the Trusted OS state and save it trust_mode=`/usr/bin/odmget PdAt | grep -p trusted_os | \ grep deflt | sed 's/.*= //' | sed 's/"//g'` typeset TMP=/tmp/${0##*/}.$$ mkdir $TMP || { print -u2 "${0##*/}: could not create temporary directory" exit 1 } function cleanup_exit { [[ -s $TMP/stderr || -s $TMP/stdout ]] || rm -rf $TMP return 0 } trap 'cleanup_exit ; exit 0' EXIT QUIT TERM HUP INT if [[ $trust_mode == "disable" ]]; then echo "Finishing BAS/EAL4+ Technology configuration..." else echo "Finishing LAS/EAL4+ Technology configuration..." fi echo exec 3>&1 exec 1>&- exec 2>&- typeset -i i=0; typeset file mode fileset srv found=0 typeset oLANG ipldev pty cdrom patch set -A CC_CHG \ "/usr/sbin/krshd" "bos.net.tcp.client" "C2_exclude" \ "/usr/sbin/krlogind" "bos.net.tcp.client" "C2_exclude" \ "/sbin/comp.kext" "bos.rte.jfscomp" "C2_exclude" \ "/sbin/comp.uext" "bos.rte.jfscomp" "C2_exclude" \ "/usr/sbin/portmir" "bos.sysmgt.serv_aid" "C2_exclude" \ "/usr/lpp/internet/server_root/cgi-bin/dpid2" "internet_server.base.httpd" "C2_exclude" \ "/usr/sbin/auditconv" "bos.rte.security" "C2_exclude" \ "/usr/bin/nslookup" "bos.net.tcp.client" "C2_exclude" \ "/usr/sbin/mkpasswd" "bos.rte.security" "C2_exclude" \ "/usr/lib/lpd/rembak" "bos.rte.printers" "" set -A CC_INETD_SERVICE \ "ftp" \ "telnet" \ "login" \ "shell" \ "exec" set -A CHG_DEV \ "/dev/xti" "0700" \ "/dev/xti/tcp" "0600" \ "/dev/xti/tcp6" "0600" \ "/dev/xti/udp" "0600" \ "/dev/xti/udp6" "0600" \ "/dev/xti/unixst" "0600" \ "/dev/xti/unixdg" "0600" \ "/dev/clone" "0600" \ "/dev/echo" "0000" \ "/dev/slog" "0600" \ "/dev/spx" "0600" \ "/dev/sad" "0600" set -A CHG_SGID \ "/usr/bin/chfn" "0500" \ "/usr/bin/chgrpmem" "0555" \ "/usr/bin/lssrc" "0555" \ "/usr/bin/ps" "0555" \ "/usr/bin/smitacl" "0555" \ "/usr/bin/splp" "0555" \ "/usr/bin/timex" "0555" \ "/usr/bin/uptime" "0555" \ "/usr/bin/w" "0555" \ "/usr/bin/w64" "0555" \ "/usr/lib/lpd/pio/etc/piomkapqd" "0555" \ "/usr/lib/lpd/piobe" "0555" \ "/usr/sbin/killall" "0555" \ "/usr/sbin/lsgroup" "0555" set -A TRUSTED_PROGS \ "/usr/bin/at"\ "/usr/bin/atq"\ "/usr/bin/atrm"\ "/usr/sbin/audit"\ "/usr/sbin/auditbin"\ "/usr/sbin/auditcat"\ "/usr/sbin/auditmerge"\ "/usr/sbin/auditpr"\ "/usr/sbin/auditselect"\ "/usr/sbin/auditstream"\ "/usr/bin/batch"\ "/usr/bin/chsh"\ "/usr/sbin/chtcb"\ "/usr/sbin/cron"\ "/usr/bin/crontab"\ "/usr/sbin/diag"\ "/usr/sbin/efsmgr"\ "/usr/sbin/efskeymgr"\ "/usr/sbin/ftpd"\ "/usr/sbin/getty"\ "/usr/bin/logout"\ "/usr/bin/passwd"\ "/usr/sbin/ping"\ "/usr/bin/pvi"\ "/usr/sbin/rexecd"\ "/usr/sbin/rlogind"\ "/usr/bin/rolelist"\ "/usr/sbin/rpc.mountd"\ "/usr/sbin/rshd"\ "/usr/bin/setsenv"\ "/usr/bin/su"\ "/usr/bin/swrole"\ "/usr/sbin/telnetd"\ "/usr/sbin/tsm"\ "/usr/lpp/X11/bin/xlock"\ "/usr/bin/telnet"\ "/usr/bin/tn3270"\ "/usr/bin/tn"\ "/usr/sbin/lstxattr" set -A CHG_ACCAUTH \ "/usr/sbin/lsuser" "aix.security.user.list" \ "/usr/bin/vmstat" "aix.system.stat" \ "/usr/sbin/lquerylv" "aix.lvm.manage" \ "/usr/sbin/lquerypv" "aix.lvm.manage" \ "/usr/sbin/lqueryvg" "aix.lvm.manage" \ "/usr/sbin/lqueryvgs" "aix.lvm.manage" \ "/usr/sbin/lquerylv" "aix.lvm.manage" \ "/usr/sbin/lsattr" "aix.system.stat" \ "/usr/sbin/lscons" "aix.system.config.console" \ "/usr/sbin/lslv" "aix.lvm.manage" \ "/usr/sbin/lspv" "aix.lvm.manage" \ "/usr/sbin/lsvg" "aix.lvm.manage" \ "/usr/sbin/netstat" "aix.system.stat" \ "/usr/ccs/bin/probevctrl" "aix.ras.probevue.manage" \ "/usr/sbin/lsmcode" "aix.system.stat" \ "/usr/bin/enq" "aix.device.config.printer" \ "/usr/sbin/lsvirprt" "aix.device.config.printer" \ "/usr/sbin/pdmode" "aix.mls.pdir.mode" \ "/usr/sbin/pdmkdir" "aix.mls.pdir.create" \ "/usr/sbin/pdrmdir" "aix.mls.pdir.remove" \ "/usr/sbin/restore" "aix.fs.manage.restore" #We need to edit group owner and mode attributes in the TSD #without losing hash and signature data. #$1 = filename, $2,...,$6 = "attr=val" function tsd_update { #Find the stanza in tsd.dat and save to file trustchk -q $1 > $TMP/CC_trust if [[ $? != 0 ]]; then #stanza doesn't exist. we can't update so just add it trustchk -a $1 size=VOLATILE rm $TMP/CC_trust return; fi for pair in $2 $3 $4 $5 $6 ; do if [[ -n $pair ]]; then #Split the attr and val attr=`echo $pair| cut -d'=' -f 1` val=`echo $pair| cut -d'=' -f 2` #Edit the attributes sed "/$attr = /s/$attr = .*/$attr = $val/" $TMP/CC_trust >$TMP/CC_trust1 #copy back to file mv $TMP/CC_trust1 $TMP/CC_trust fi done #Add the modified stanza back to tsd.dat and clean up trustchk -wa -f $TMP/CC_trust rm $TMP/CC_trust } function chgmode { typeset file=${1?} typeset owner=${2?} typeset group=${3?} typeset mode=${4?} if [[ -e $file ]]; then chown $owner.$group $file chmod $mode $file tsd_update $file mode=$mode owner=$owner group=$group if [[ -n $tcb_enabled ]]; then tcbck -a $file mode=$mode owner=$owner group=$group type tcbck -y $file fi fi } # # 1). Remove /dev/echo from /etc/pse.conf # echo "1). Remove /dev/echo from /etc/pse.conf" 1>&3 ex - /etc/pse.conf <&3 strload -f /etc/pse.conf # # 3). Set permissions on BSD-style ptys to 000 # echo "3). Set permissions on BSD-style ptys to 000" 1>&3 for pty in /dev/ptyp* /dev/ttyp* ; do chgmode $pty root system 000 done # # 4). Remove non-CC entries from inetd.conf # echo "4). Remove non-CC technology entries from inetd.conf" 1>&3 # create backup / keep top-of-file comments [[ ! -f /etc/inetd.conf.non-CC ]] && cp -p /etc/inetd.conf /etc/inetd.conf.non-CC ex - /etc/inetd.conf <<-EOF 1,/^[^#][^#]/-1 ya c %d 0pu c x EOF # add CC services to end of inetd.conf i=0 while [[ $i -lt ${#CC_INETD_SERVICE[*]} ]] ; do srv=${CC_INETD_SERVICE[$i]} ; i=$i+1 sed -e "/^[# ]*$srv[ ]*/!d" /etc/inetd.conf.non-CC >> /etc/inetd.conf done # # 5). Update CC status in sysck.cfg # echo "5). Update CC technology status in sysck.cfg" 1>&3 if [[ -n $tcb_enabled ]]; then i=0; while [[ $i -lt ${#CC_CHG[*]} ]] ; do file=${CC_CHG[$i]} ; i=$i+1 fileset=${CC_CHG[$i]} ; i=$i+1 exclude=${CC_CHG[$i]} ; i=$i+1 tcbck -a $file mode class=apply,inventory,$fileset${exclude:+,$exclude} tcbck -y $file done fi # # 6). Change permissions on devices to be accessible by root only # echo "6). Change permissions on devices to be accessible by root only" 1>&3 #Restrict access to some /dev objects i=0; while [[ $i -lt ${#CHG_DEV[*]} ]] ; do file=${CHG_DEV[$i]} ; i=$i+1 mode=${CHG_DEV[$i]} ; i=$i+1 chgmode $file root system $mode done # # 7). Remove suid/sgid permission bits from commands that are non-trusted. # echo "7). Remove suid/sgid permission bits from commands that are non-trusted." 1>&3 #Remove suid bit if file is owned by root and executable by an entity that is not in #an admin group. Trusted programs are to be exempt from this modification. for FILE in \ `find / ! \( -type d -a -name "proc" -a -prune \) -a \ \( -type f -a \( -perm -4000 \) -a -user root -a \ \( -perm -0001 -o \( -perm -4010 -a \ ! \( -group system -o -group sys -o -group adm -o\ -group uucp -o -group mail -o -group security -o\ -group cron -o -group printq -o -group audit -o\ -group shutdown \) \) \) \)` do LINE=`echo ${TRUSTED_PROGS[*]} | grep "$FILE"` if [[ -z $LINE ]]; then #if not a trusted program #Look up the file in TSD trustchk -q $FILE 2>&1 >/dev/null ret=$? if [[ $ret != 0 ]]; then #no entry but could be a link, check "links" attrs trustchk -q ALL | egrep "$FILE,|$FILE\$" |\ egrep links 2>&1 >/dev/null ret=$? if [[ $ret != 0 ]]; then #not a link, need to chmod chg_flag=1 else #is a link, skip this file chg_flag=0 fi else #there is an entry, need to chmod chg_flag=1 fi #if needed, chmod and update/add to the TSD/TCB if [[ $chg_flag -eq 1 ]]; then chmod "-s" $FILE #get the mode attribute from tsd and remove SUID/SGID mode=`trustchk -q $FILE | grep mode | sed "s/.*mode = //" | \ sed "s/SUID,//" | sed "s/SGID,//" ` tsd_update $FILE mode=$mode if [[ -n $tcb_enabled ]]; then tcbck -a $FILE mode owner group type tcbck -y $FILE fi fi fi done #Restrict access to some sgid objects i=0; while [[ $i -lt ${#CHG_SGID[*]} ]] ; do file=${CHG_SGID[$i]} ; i=$i+1 mode=${CHG_SGID[$i]} ; i=$i+1 chgmode $file root system $mode done # # 8). Remove ALLOW_ALL from non-trusted commands in privcmds. # echo "8). Remove ALLOW_ALL from non-trusted commands in privcmds." 1>&3 #ALLOW_ALL in privcmds is equivalent to suid bits. Normal users #have access to privileged operations, therefore we restrict #the number of these to limit possibilities for vulnerability. #Only Trusted Programs are allowed to be ALLOW_ALL. #create back-up privcmds cp -p /etc/security/privcmds /etc/security/privcmds.non-CC #First, some commands will not work at all on root-disabled systems #if we remove them completely from privcmds. To fix this we will #set their accessauths. This way users will still be able to #execute the command if they have been authorized by sys admin. i=0; while [[ $i -lt ${#CHG_ACCAUTH[*]} ]] ; do file=${CHG_ACCAUTH[$i]} ; i=$i+1 auth=${CHG_ACCAUTH[$i]} ; i=$i+1 #if the file exists (some are MLS-only) if [[ -e $file ]]; then /usr/bin/setsecattr -c accessauths=$auth $file tsd_update $file accessauths=$auth fi done #Anything remaining that still has ALLOW_ALL at this point needs #to be removed from privcmds. for FILE in \ `grep -p ALLOW_ALL /etc/security/privcmds | egrep "^/" | sed 's/://g'` do #trusted programs are once again exempt. LINE=`echo ${TRUSTED_PROGS[*]} | grep "$FILE"` if [[ -z $LINE ]]; then #if not a trusted program /usr/sbin/rmsecattr -c $FILE #remove from privcmds tsd_update $FILE accessauths= innateprivs= inheritprivs= \ authprivs= secflags= fi done #upload new privcmd table to kernel /usr/sbin/setkst -t cmd # # 9). Run aixpert -l low for security hardening # echo "9). Run aixpert -l low for security hardening." 1>&3 #aixpert runs pwdck with option to auto-fix. We are requiring #passwords, so one will automatically be set for users with #blank password. Since this script runs during install, we #may lock users out of the system without an opportunity to set #a root password. We will set NOCHECK flags to combat this. #$1 = user name function add_nocheck { #get the existing flags. currflags=`/usr/bin/pwdadm -q $1 | grep flags | sed 's/.*= //'` #if NOCHECK is not already there, add it to current flags echo $currflags | grep NOCHECK if [[ $? -ne 0 ]]; then #if there are existing flags add NOCHECK, #else just set NOCHECK if [[ -n $currflags ]]; then /usr/bin/pwdadm -f $currflags,NOCHECK $1 else /usr/bin/pwdadm -f NOCHECK $1 fi fi } #$1 = user name function rmv_nocheck { #get the existing flags and delete NOCHECK # (delete any extra commas that might result too) newflags=`pwdadm -q $1 | grep flags | sed 's/.*= //' | sed 's/NOCHECK//'\ | sed 's/,,/,/g' | sed 's/^,//' | sed 's/,$//'` #if NOCHECK was not the only flag, set the new flags #else remove NOCHECK by clearing flags. if [[ -n $newflags ]]; then /usr/bin/pwdadm -f $newflags $1 else /usr/bin/pwdadm -c $1 fi } #Trusted AIX is root-disabled, protect isso. if [[ $trust_mode == "enable" ]]; then add_nocheck isso fi add_nocheck root #Run aixpert /usr/sbin/aixpert -l low #remove the NOCHECK flags rmv_nocheck root if [[ $trust_mode == "enable" ]]; then rmv_nocheck isso fi #Add some password restrictions #(aixpert has very limited restrictions on low setting) /usr/bin/chsec -f /etc/security/user -s default \ -a umask=077 -a minalpha=2 -a minother=2 \ -a mindiff=4 -a maxrepeats=2 -a loginretries=3 #For non-trusted system, harden the root account if [[ $trust_mode == "disable" ]]; then #create a new group SUADMIN /usr/bin/mkgroup SUADMIN #Disable remote logins and limit su attempts to #members of the SUADMIN group /usr/bin/chuser rlogin=false sugroups=SUADMIN root fi # # 10). Remove TCB bit from volatile data files # echo "10). Remove TCB bit from volatile data files" 1>&3 #this file doesn't seem to be in TSD so do nothing for TSD. if [[ -n $tcb_enabled ]]; then chtcb off /etc/qconfig tcbck -a /etc/qconfig owner group mode type fi # # 11). Only root can bind() to the NFS port # echo "11). Restrict non-root access to NFS port" 1>&3 egrep -q '^2049[ ]' /etc/security/priv || echo "2049" >> /etc/security/priv # # 12). Change websm port to 9090 # echo "12). Change websm port to 9090" 1>&3 /usr/bin/ex - /etc/security/priv <<-EOF g/^[ ]*websm.*\$/s//9090/ w! q EOF # # 13). Add the default dacinet ACL # echo "13). Add the default dacinet ACL" 1>&3 egrep -q '^0[ ]' /etc/security/acl || echo "0 ::/0" >> /etc/security/acl # # 14). Make sure that the loopback interface is up # echo "14). Enable the loopback interface" 1>&3 chdev -l lo0 -a "state=up" # # 15). Create synonyms for /dev/console # echo "15). Create synonyms for /dev/console" 1>&3 chsec -f /etc/security/login.cfg -s /dev/console \ -a "synonym=/dev/lft0,/dev/mouse0,/dev/kbd0,/dev/rcm0" # # 16). Enforce default X server connection permissions # echo "16). Enforce default X server connection permissions" 1>&3 ed - /usr/lpp/X11/defaults/xserverrc << \EOF g!\(/usr/lpp/X11/bin/X\)[ ][ ]*\($EXTENSIONS\)!s!!\1 -secIP -secSMT -secLocal 700 \2! w q EOF # # 17). Add ODM stanzas to set the console permissions # echo "17). Add ODM stanzas to set the console permissions" 1>&3 cat >$TMP/console.odm <&3 #aixpert only disables sendmail on high level security. if [[ -f /etc/rc.tcpip ]] then sed 's/^start[ ]*\/usr\/lib\/sendmail/#start \/usr\/lib\/sendmail/' \ /etc/rc.tcpip > /etc/rc.tcpip.$$ cp /etc/rc.tcpip.$$ /etc/rc.tcpip rm /etc/rc.tcpip.$$ fi stopsrc -s sendmail #for MLS mode we also need to shut off access to mail and bellmail since #the mail system is not instrumented for labelled communication. if [[ $trust_mode == "enable" ]]; then chgmode /usr/bin/mail bin mail 000 chgmode /usr/bin/bellmail root mail 000 /usr/sbin/rmsecattr -c /usr/bin/mail /usr/sbin/rmsecattr -c /usr/bin/bellmail /usr/sbin/setkst -t cmd fi # remove httpdlite from inittab lsitab httpdlite >/dev/null && rmitab httpdlite # remove IMNsearch from inittab lsitab itess > /dev/null && rmitab itess # remove tunrestore from inittab lsitab tunables >/dev/null && rmitab tunables # remove xmwlm from inittab lsitab xmdaily >/dev/null && rmitab xmdaily # disable writesrv lsitab writesrv >/dev/null && rmitab writesrv stopsrc -s writesrv #aixpert already does some deconfiguration of snmp but does #not perform a stop on some of the daemons. #disable snmpd, snmpmibd, aixmibd, hostmibd stopsrc -s snmpd stopsrc -s snmpmibd stopsrc -s aixmibd stopsrc -s hostmibd #disable RSCT daemons if RMC is installed lsitab ctrmc >/dev/null && rmitab ctrmc if [[ -e /usr/sbin/rsct/bin/rmcctrl ]]; then /usr/sbin/rsct/bin/rmcctrl -z fi # # 19). Remove perfvmmstat # echo "19). Remove perfvmmstat and ipcs_perf" 1>&3 for FILE in /usr/lib/drivers/perfvmmstat.* ; do if [ -f ${FILE} ] ; then rm ${FILE} tcbck -d ${FILE} for DIR in /etc/objrepos /usr/lib/objrepos ; do ODMDIR=$DIR odmdelete -o inventory \ -q "loc0 = '${FILE}'" done fi done chgmode /usr/bin/ipcs_perf root bin 000 # # 20). Add netrules for LAS # echo "20). Add netrules for LAS" 1>&3 #We need to remove the label range for network interfaces to be #LAS compliant. if [[ $trust_mode == "enable" ]]; then #first correct the default rule so future interface #configs take this new rule /usr/sbin/netrule i+u default +impl_lo +impl_lo +impl_lo #Change the range also on the loopback interface /usr/sbin/netrule i+u lo0 +impl_lo +impl_lo +impl_lo #There may be existing interfaces. Discover them and #correct their netrules. for IFNAME in `netstat -ni | awk '$1!="lo0" && $1!="Name" {print $0}'|\ awk 'substr($3,1,4)=="link" {print $1}'` do /usr/sbin/netrule i+u $IFNAME +impl_lo +impl_lo +impl_lo done fi # Finished echo "Finished." 1>&3 exit 0