#!/bin/sh - # # Copyright (c) 2000 The FreeBSD Project # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # @(#)security 5.3 (Berkeley) 5/28/91 # $FreeBSD$ # PATH=/sbin:/bin:/usr/bin LC_ALL=C; export LC_ALL rc=0 LOG=/var/log TMP=/var/run/_secure.$$ separator () { echo '' echo '' } catmsgs() { find $LOG -name 'messages.*' -mtime -2 | sort -t. -r -n +1 -2 | xargs zcat -f [ -f $LOG/messages ] && cat $LOG/messages } sflag=FALSE ignore= while getopts ams c do case "$c" in a) ignore="$ignore|^amd:";; m) ignore="$ignore|^mfs:";; s) sflag=TRUE;; esac done yesterday=`date -v-1d "+%b %e "` host=`hostname` [ $sflag = FALSE ] && echo "Subject: ${host} security check output" umask 027 echo 'Checking setuid files and devices:' # Don't have ncheck, but this does the equivalent of the commented out block. # Note that one of the original problems, the possibility of overrunning # the args to ls, is still here... # MP=`mount -t ufs | grep -v " nosuid" | awk '{ print $3 }' | sort` set ${MP} while [ $# -ge 1 ]; do mount=$1 shift find $mount -xdev -type f \ \( -perm -u+x -or -perm -g+x -or -perm -o+x \) \ \( -perm -u+s -or -perm -g+s \) -print0 done | xargs -0 -n 20 ls -liTd | sort +10 > ${TMP} if [ ! -f ${LOG}/setuid.today ]; then [ $rc -lt 1 ] && rc=1 separator echo "No ${LOG}/setuid.today" cp ${TMP} ${LOG}/setuid.today || rc=3 fi if ! cmp ${LOG}/setuid.today ${TMP} >/dev/null; then [ $rc -lt 1 ] && rc=1 separator echo "${host} setuid diffs:" diff -w ${LOG}/setuid.today ${TMP} mv ${LOG}/setuid.today ${LOG}/setuid.yesterday || rc=3 mv ${TMP} ${LOG}/setuid.today || rc=3 fi # Show changes in the way filesystems are mounted # [ -n "$ignore" ] && cmd="egrep -v ${ignore#|}" || cmd=cat if mount -p | $cmd > $TMP; then if [ ! -f $LOG/mount.today ]; then [ $rc -lt 1 ] && rc=1 separator echo "No $LOG/mount.today" cp $TMP $LOG/mount.today || rc=3 fi if ! cmp $LOG/mount.today $TMP >/dev/null 2>&1; then [ $rc -lt 1 ] && rc=1 separator echo "$host changes in mounted filesystems:" diff -b $LOG/mount.today $TMP mv $LOG/mount.today $LOG/mount.yesterday || rc=3 mv $TMP $LOG/mount.today || rc=3 fi fi separator echo 'Checking for uids of 0:' n=$(awk -F: '/^#/ {next} $3==0 {print $1,$3}' /etc/master.passwd | tee /dev/stderr | sed -e '/^root 0$/d' -e '/^toor 0$/d' | wc -l) [ $n -gt 0 -a $rc -lt 1 ] && rc=1 separator echo 'Checking for passwordless accounts:' n=$(awk -F: 'NF > 1 && $1 !~ /^[#+-]/ && $2=="" {print $0}' /etc/master.passwd | tee /dev/stderr | wc -l) [ $n -gt 0 -a $rc -lt 1 ] && rc=1 # Show denied packets # if ipfw -a l 2>/dev/null | egrep "deny|reset|unreach" > ${TMP}; then if [ ! -f ${LOG}/ipfw.today ]; then [ $rc -lt 1 ] && rc=1 separator echo "No ${LOG}/ipfw.today" cp ${TMP} ${LOG}/ipfw.today || rc=3 fi if ! cmp ${LOG}/ipfw.today ${TMP} >/dev/null; then [ $rc -lt 1 ] && rc=1 separator echo "${host} denied packets:" diff -b ${LOG}/ipfw.today ${TMP} | egrep "^>" mv ${LOG}/ipfw.today ${LOG}/ipfw.yesterday || rc=3 mv ${TMP} ${LOG}/ipfw.today || rc=3 fi fi # Show ipfw rules which have reached the log limit # IPFW_LOG_LIMIT=`sysctl -n net.inet.ip.fw.verbose_limit 2> /dev/null` if [ $? -eq 0 -a "${IPFW_LOG_LIMIT}" -ne 0 ]; then ipfw -a l | grep " log " | perl -n -e \ '/^\d+\s+(\d+)/; print if ($1 >= '$IPFW_LOG_LIMIT')' > ${TMP} if [ -s "${TMP}" ]; then [ $rc -lt 1 ] && rc=1 separator echo 'ipfw log limit reached:' cat ${TMP} fi fi # Show kernel log messages # if dmesg 2>/dev/null > ${TMP}; then if [ ! -f ${LOG}/dmesg.today ]; then [ $rc -lt 1 ] && rc=1 separator echo "No ${LOG}/dmesg.today" cp ${TMP} ${LOG}/dmesg.today || rc=3 fi if ! cmp ${LOG}/dmesg.today ${TMP} >/dev/null 2>&1; then [ $rc -lt 1 ] && rc=1 separator echo "${host} kernel log messages:" diff -b ${LOG}/dmesg.today ${TMP} | egrep "^>" mv ${LOG}/dmesg.today ${LOG}/dmesg.yesterday || rc=3 mv ${TMP} ${LOG}/dmesg.today || rc=3 fi fi # Show login failures # separator echo "${host} login failures:" n=$(catmsgs | grep -i "^$yesterday.*login failure" | tee /dev/stderr | wc -l) [ $n -gt 0 -a $rc -lt 1 ] && rc=1 # Show tcp_wrapper warning messages # separator echo "${host} refused connections:" n=$(catmsgs | grep -i "^$yesterday.*refused connect" | tee /dev/stderr | wc -l) [ $n -gt 0 -a $rc -lt 1 ] && rc=1 rm -f ${TMP} exit $rc