ab26031ac2
non-printable characters to sneak into /var/log/messages (e.g. someone aims a Solaris/Linux RCP exploit at your FreeBSD box and you end up with his shellcode as part of a log entry). You might get something like, host.mydom.org login failures: Binary file (standard input) matches In the daily security script as a result. Allowing attackers to mess with your security script's ability to accurately report is a Bad Thing. Tell grep(1) to treat /var/log/messages like a text file even if it has non-printable characters. Submitted by: Tim Zingelman <zingelman@fnal.gov> on freebsd-security Approved by: ru MFC after: 1 week
202 lines
5.5 KiB
Bash
202 lines
5.5 KiB
Bash
#!/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 as c
|
|
do
|
|
case "$c" in
|
|
a) ignore="$ignore|^amd:";;
|
|
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 -a 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 -ia "^$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
|