version 1.1, 1995/10/18 08:37:57 |
version 1.2, 1995/12/18 16:56:37 |
|
|
} |
} |
if (NF != 10) |
if (NF != 10) |
printf("Line %d has the wrong number of fields.\n", NR); |
printf("Line %d has the wrong number of fields.\n", NR); |
if ($1 !~ /^[A-Za-z0-9]*$/) |
if ($1 ~ /^[+-].*$/) |
|
next; |
|
if ($1 == "") |
|
printf("Line %d has an empty login field.\n",NR); |
|
else if ($1 !~ /^[A-Za-z0-9][A-Za-z0-9_-]*$/) |
printf("Login %s has non-alphanumeric characters.\n", $1); |
printf("Login %s has non-alphanumeric characters.\n", $1); |
if (length($1) > 8) |
if (length($1) > 8) |
printf("Login %s has more than 8 characters.\n", $1); |
printf("Login %s has more than 8 characters.\n", $1); |
|
|
column $OUTPUT |
column $OUTPUT |
fi |
fi |
|
|
awk -F: '{ print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | |
awk -F: '$1 != "toor" { print $1 " " $3 }' $MP | sort -n +1 | tee $TMP1 | |
uniq -d -f 1 | awk '{ print $2 }' > $TMP2 |
uniq -d -f 1 | awk '{ print $2 }' > $TMP2 |
if [ -s $TMP2 ] ; then |
if [ -s $TMP2 ] ; then |
printf "\n$MP has duplicate user id's.\n" |
printf "\n$MP has duplicate user id's.\n" |
|
|
# Backup the master password file; a special case, the normal backup |
# Backup the master password file; a special case, the normal backup |
# mechanisms also print out file differences and we don't want to do |
# mechanisms also print out file differences and we don't want to do |
# that because this file has encrypted passwords in it. |
# that because this file has encrypted passwords in it. |
|
if [ ! -d /var/backups ] ; then |
|
mkdir /var/backups |
|
chmod 755 /var/backups |
|
fi |
CUR=/var/backups/`basename $MP`.current |
CUR=/var/backups/`basename $MP`.current |
BACK=/var/backups/`basename $MP`.backup |
BACK=/var/backups/`basename $MP`.backup |
if [ -s $CUR ] ; then |
if [ -s $CUR ] ; then |
|
|
printf("Line %d is a blank line.\n", NR); |
printf("Line %d is a blank line.\n", NR); |
next; |
next; |
} |
} |
|
if ($1 ~ /^[+-].*$/) |
|
next; |
if (NF != 4) |
if (NF != 4) |
printf("Line %d has the wrong number of fields.\n", NR); |
printf("Line %d has the wrong number of fields.\n", NR); |
if ($1 !~ /^[A-za-z0-9]*$/) |
if ($1 !~ /^[A-za-z0-9]*$/) |
|
|
fi |
fi |
|
|
# Files that should not have + signs. |
# Files that should not have + signs. |
list="/etc/hosts.equiv /etc/hosts.lpd" |
list="/etc/hosts.equiv /etc/shosts.equiv /etc/hosts.lpd" |
for f in $list ; do |
for f in $list ; do |
if egrep '\+' $f > /dev/null ; then |
if [ -f $f ] ; then |
printf "\nPlus sign in $f file.\n" |
awk '{ |
|
if ($0 ~ /^+@.*$/ ) |
|
next; |
|
if ($0 ~ /^+.*$/ ) |
|
printf("\nPlus sign in %s file.\n", FILENAME); |
|
}' $f |
fi |
fi |
done |
done |
|
|
# Check for special users with .rhosts files. Only root and toor should |
# Check for special users with .rhosts/.shosts files. Only root and |
# have a .rhosts files. Also, .rhosts files should not plus signs. |
# toor should have .rhosts/.shosts files. Also, .rhosts/.shosts files |
awk -F: '$1 != "root" && $1 != "toor" && \ |
# should not have plus signs. |
|
awk -F: '$1 != "root" && $1 != "toor" && $1 !~ /^[+-].*$/ && \ |
($3 < 100 || $1 == "ftp" || $1 == "uucp") \ |
($3 < 100 || $1 == "ftp" || $1 == "uucp") \ |
{ print $1 " " $6 }' /etc/passwd | |
{ print $1 " " $6 }' /etc/passwd | |
while read uid homedir; do |
while read uid homedir; do |
if [ -f ${homedir}/.rhosts ] ; then |
for j in .rhosts .shosts; do |
rhost=`ls -ldgT ${homedir}/.rhosts` |
if [ -f ${homedir}/$j ] ; then |
printf "$uid: $rhost\n" |
rhost=`ls -ldgT ${homedir}/$j` |
fi |
printf "$uid: $rhost\n" |
|
fi |
|
done |
done > $OUTPUT |
done > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "\nChecking for special users with .rhosts files.\n" |
printf "\nChecking for special users with .rhosts/.shosts files.\n" |
cat $OUTPUT |
cat $OUTPUT |
fi |
fi |
|
|
awk -F: '{ print $1 " " $6 }' /etc/passwd | \ |
awk -F: '{ print $1 " " $6 }' /etc/passwd | \ |
while read uid homedir; do |
while read uid homedir; do |
if [ -f ${homedir}/.rhosts ] && \ |
for j in .rhosts .shosts; do |
egrep '\+' ${homedir}/.rhosts > /dev/null ; then |
if [ -f ${homedir}/$j ] ; then |
printf "$uid: + in .rhosts file.\n" |
awk '{ |
fi |
if ($0 ~ /^+@.*$/ ) |
|
next; |
|
if ($0 ~ /^+.*$/ ) |
|
printf("%s has + sign in it.\n", |
|
FILENAME); |
|
}' ${homedir}/$j |
|
fi |
|
done |
done > $OUTPUT |
done > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "\nChecking .rhosts files syntax.\n" |
printf "\nChecking .rhosts/.shosts files syntax.\n" |
cat $OUTPUT |
cat $OUTPUT |
fi |
fi |
|
|
# Check home directories. Directories should not be owned by someone else |
# Check home directories. Directories should not be owned by someone else |
# or writeable. |
# or writeable. |
awk -F: '{ print $1 " " $6 }' /etc/passwd | \ |
awk -F: '{ if ( $1 !~ /^[+-].*$/ ) print $1 " " $6 }' /etc/passwd | \ |
while read uid homedir; do |
while read uid homedir; do |
if [ -d ${homedir}/ ] ; then |
if [ -d ${homedir}/ ] ; then |
file=`ls -ldgT ${homedir}` |
file=`ls -ldgT ${homedir}` |
|
|
fi |
fi |
|
|
# Files that should not be owned by someone else or readable. |
# Files that should not be owned by someone else or readable. |
list=".netrc .rhosts" |
list=".netrc .rhosts .shosts" |
awk -F: '{ print $1 " " $6 }' /etc/passwd | \ |
awk -F: '{ print $1 " " $6 }' /etc/passwd | \ |
while read uid homedir; do |
while read uid homedir; do |
for f in $list ; do |
for f in $list ; do |
|
|
done | |
done | |
awk '$1 != $5 && $5 != "root" \ |
awk '$1 != $5 && $5 != "root" \ |
{ print "user " $1 " " $2 " file is owned by " $5 } |
{ print "user " $1 " " $2 " file is owned by " $5 } |
$3 ~ /^-...r/ \ |
|
{ print "user " $1 " " $2 " file is group readable" } |
|
$3 ~ /^-......r/ \ |
$3 ~ /^-......r/ \ |
{ print "user " $1 " " $2 " file is other readable" } |
{ print "user " $1 " " $2 " file is other readable" } |
$3 ~ /^-....w/ \ |
$3 ~ /^-....w/ \ |
|
|
cat $OUTPUT |
cat $OUTPUT |
fi |
fi |
|
|
# File systems should not be globally exported. |
if [ -f /etc/exports ]; then |
awk '{ |
# File systems should not be globally exported. |
|
awk '{ |
readonly = 0; |
readonly = 0; |
for (i = 2; i <= NF; ++i) { |
for (i = 2; i <= NF; ++i) { |
if ($i ~ /-ro/) |
if ($i ~ /-ro/) |
|
|
print "File system " $1 " globally exported, read-only." |
print "File system " $1 " globally exported, read-only." |
else |
else |
print "File system " $1 " globally exported, read-write." |
print "File system " $1 " globally exported, read-write." |
}' < /etc/exports > $OUTPUT |
}' < /etc/exports > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "\nChecking for globally exported file systems.\n" |
printf "\nChecking for globally exported file systems.\n" |
cat $OUTPUT |
cat $OUTPUT |
|
fi |
fi |
fi |
|
|
# Display any changes in setuid files and devices. |
# Display any changes in setuid files and devices. |
printf "\nChecking setuid files and devices:\n" |
pending="\nChecking setuid files and devices:\n" |
(find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \ |
(find / \( ! -fstype local -o -fstype fdesc -o -fstype kernfs \ |
-o -fstype procfs \) -a -prune -o \ |
-o -fstype procfs \) -a -prune -o \ |
\( -perm -u+s -o -perm -g+s -o ! -type d -a ! -type f -a ! -type l -a \ |
-type f -a \( -perm -u+s -o -perm -g+s \) -print -o \ |
! -type s \) | \ |
! -type d -a ! -type f -a ! -type l -a ! -type s -print | \ |
sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT |
sort | sed -e 's/^/ls -ldgT /' | sh > $LIST) 2> $OUTPUT |
|
|
# Display any errors that occurred during system file walk. |
# Display any errors that occurred during system file walk. |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "Setuid/device find errors:\n" |
printf "${pending}Setuid/device find errors:\n" |
|
pending= |
cat $OUTPUT |
cat $OUTPUT |
printf "\n" |
printf "\n" |
fi |
fi |
|
|
if [ -s $TMP1 ] ; then |
if [ -s $TMP1 ] ; then |
# Check to make sure uudecode isn't setuid. |
# Check to make sure uudecode isn't setuid. |
if grep -w uudecode $TMP1 > /dev/null ; then |
if grep -w uudecode $TMP1 > /dev/null ; then |
printf "\nUudecode is setuid.\n" |
printf "${pending}\nUudecode is setuid.\n" |
|
pending= |
fi |
fi |
|
|
CUR=/var/backups/setuid.current |
CUR=/var/backups/setuid.current |
|
|
> $TMP2 |
> $TMP2 |
join -110 -210 -v2 $CUR $TMP1 > $OUTPUT |
join -110 -210 -v2 $CUR $TMP1 > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "Setuid additions:\n" |
printf "${pending}Setuid additions:\n" |
|
pending= |
tee -a $TMP2 < $OUTPUT |
tee -a $TMP2 < $OUTPUT |
printf "\n" |
printf "\n" |
fi |
fi |
|
|
join -110 -210 -v1 $CUR $TMP1 > $OUTPUT |
join -110 -210 -v1 $CUR $TMP1 > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "Setuid deletions:\n" |
printf "${pending}Setuid deletions:\n" |
|
pending= |
tee -a $TMP2 < $OUTPUT |
tee -a $TMP2 < $OUTPUT |
printf "\n" |
printf "\n" |
fi |
fi |
|
|
sort +9 $TMP2 $CUR $TMP1 | \ |
sort +9 $TMP2 $CUR $TMP1 | \ |
sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT |
sed -e 's/[ ][ ]*/ /g' | uniq -u > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "Setuid changes:\n" |
printf "${pending}Setuid changes:\n" |
|
pending= |
column -t $OUTPUT |
column -t $OUTPUT |
printf "\n" |
printf "\n" |
fi |
fi |
|
|
cp $TMP1 $CUR |
cp $TMP1 $CUR |
fi |
fi |
else |
else |
printf "Setuid additions:\n" |
printf "${pending}Setuid additions:\n" |
|
pending= |
column -t $TMP1 |
column -t $TMP1 |
printf "\n" |
printf "\n" |
cp $TMP1 $CUR |
cp $TMP1 $CUR |
|
|
# Check for block and character disk devices that are readable or writeable |
# Check for block and character disk devices that are readable or writeable |
# or not owned by root.operator. |
# or not owned by root.operator. |
>$TMP1 |
>$TMP1 |
DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx rz sd up wd" |
DISKLIST="dk fd hd hk hp jb kra ra rb rd rl rx xd rz sd up wd vnd ccd" |
for i in $DISKLIST; do |
for i in $DISKLIST; do |
egrep "^b.*/${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 |
egrep "^b.*/${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 |
egrep "^c.*/r${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 |
egrep "^c.*/r${i}[0-9][0-9]*[a-h]$" $LIST >> $TMP1 |
|
|
# Create the mtree tree specifications using: |
# Create the mtree tree specifications using: |
# |
# |
# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure |
# mtree -cx -pDIR -kcksum,gid,mode,nlink,size,link,time,uid > DIR.secure |
# chown root.wheel DIR.SECURE |
# chown root.wheel DIR.secure |
# chmod 600 DIR.SECURE |
# chmod 600 DIR.secure |
# |
# |
# Note, this is not complete protection against Trojan horsed binaries, as |
# Note, this is not complete protection against Trojan horsed binaries, as |
# the hacker can modify the tree specification to match the replaced binary. |
# the hacker can modify the tree specification to match the replaced binary. |
# For details on really protecting yourself against modified binaries, see |
# For details on really protecting yourself against modified binaries, see |
# the mtree(8) manual page. |
# the mtree(8) manual page. |
if cd /etc/mtree; then |
if [ -d /etc/mtree ]; then |
|
cd /etc/mtree |
mtree -e -p / -f /etc/mtree/special > $OUTPUT |
mtree -e -p / -f /etc/mtree/special > $OUTPUT |
if [ -s $OUTPUT ] ; then |
if [ -s $OUTPUT ] ; then |
printf "\nChecking special files and directories.\n" |
printf "\nChecking special files and directories.\n" |
|
|
|
|
> $OUTPUT |
> $OUTPUT |
for file in *.secure; do |
for file in *.secure; do |
|
[ $file = '*.secure' ] && continue |
tree=`sed -n -e '3s/.* //p' -e 3q $file` |
tree=`sed -n -e '3s/.* //p' -e 3q $file` |
mtree -f $file -p $tree > $TMP1 |
mtree -f $file -p $tree > $TMP1 |
if [ -s $TMP1 ]; then |
if [ -s $TMP1 ]; then |
|
|
printf "\nChecking system binaries:\n" |
printf "\nChecking system binaries:\n" |
cat $OUTPUT |
cat $OUTPUT |
fi |
fi |
|
else |
|
echo /etc/mtree is missing |
fi |
fi |
|
|
# List of files that get backed up and checked for any modifications. Each |
# List of files that get backed up and checked for any modifications. Each |