/home/wpollock1/public_html/restricted/ShellScripting/suspicious.sh

#!/bin/sh -
# suspicious.sh: Checks for suspicious files
# Written by Wayne Pollock, Tampa Florida USA

# TODO:
# If the file ~/.ignore exists (and is readable), then
# it is expected to contain a sorted list of pathnames
# of files that look suspicious but in fact are OK.
# (This file should be digitally signed whenever updated,
# and the signature should be verified before use.)
# Note the Gnu extensions to find are used.  While a
# more verbose POSIX compliant command could be used,
# Gnu find is common enough.
#
# $Id: suspicious.sh,v 2.8 2014/04/21 06:04:44 wpollock Exp $

PATH=$(getconf PATH)

# TMP is used to compare file dates with now:
TMP=$(mktemp) || exit 1
# (This can now be done without an external file, using Gnu's
# "-newerXY" predicate.)

# Clean up temp file:
trap 'rm $TMP; trap - 0; exit 0' EXIT HUP INT QUIT TERM

#IGNORE_FILE=~/.ignore  # non-suspicious files
#[ -r "$IGNORE_FILE" ] || IGNORE_FILE=/dev/null

# The following find command:
# Ignores optimizations that may cause some files to be skipped (-noleaf),
# Skips various (fake) filesystems (-prune),
# Finds:
# with ANY of SUID, SGID ("-perm /06000"),
# files writable by "other" ("-perm -02"), except symlinks,
#   sockets, and directories that also have the sticky (text) bit set,
# files with strange combinations of permissions (only a few are
#   checked, TODO: include a comprehensive set),
# files with no valid owner or group,
# very large files,
# files older than 20 years ("+7300"), (probably should use
#   system install date but there is no decent way to know that,
# and some files are installed with older timestamps),
# files with future timestamps (a-, c-, or m-time),
# files with strange names (2+ leading dots, ends with a space, contains
#   wildcard or non-printable characters),
# device files outside of /dev,
# updated configuration files that aren't used (*.rpm* files),
# and broken symlinks (using Gnu readlink(1)).
#
# TODO:
# Alter output to include a "type" of bad file + pathname;
# then the output of find can be piped into an awk
# script similar to this:
#
# awk '
# {type=$1; $1=""; list[type]=list[type] "\n" $0}
# END { for ( type in list)
#          print "\n=========== " type " ============\n" list[type]}
# ' foo
#
# (A list of type and section heading strings would be useful
# in BEGIN, to provide better section headings.  Also filenames
# should be indented by a tab.)
#
# TODO:
# Change reported pathname by processing it to clearly show hidden
# or strange characters (especially newlines) as octal escapes.
#
# TODO:
# Add detection of broken symlinks:
# find -type l ! -exec sh -c 'readlink -e "$@" >/dev/null' X '{}' \; -print

find . -noleaf -regextype posix-basic \
   -path '/proc' -prune \
-o -path '/sys' -prune \
-o -path '/windows-C-Drive' -prune \
-o -path '/selinux' -prune \
-o \( -perm /04000 -printf '%p (Set UID)\n' \) \
-o \( -perm /02000 ! -type d -printf '%p (Set GID)\n' \) \
-o \( -perm -02 \( -type f -o \( -type d ! -perm -01000 \) \) \
     -printf '%p (Bad Permissions - world writable)\n' \) \
-o \( \( ! -perm -400 -o \( -perm /111 ! -perm -100 \) -o \
     \( -perm /222 ! -perm -200 \) \) \
     -printf '%p (Strange permissions)\n' \) \
-o \( \( -nouser -o -nogroup \) -printf '%p (Invalid owner or group)\n' \) \
-o \( \( -size +100M -type f \) -printf '%p (Very large file)\n' \) \
-o \( \( -mtime +7300 -o -atime +7300 -o -ctime +7300 \) \
     -printf '%p (Very old file)\n' \) \
-o \( \( -newer $TMP -o -cnewer $TMP \) \
     -printf '%p (Modification time in the future)\n' \) \
-o \( -name '..?*' -printf '%p (Name starts with two periods)\n' \) \
-o \( -name '* ' -printf '%p (Name ends with a space)\n' \) \
-o \( -name '*[*?]*' -printf '%p (Name contains a wildcard)\n' \) \
-o \( ! -regex '^[[:print:]]*$' \
     -printf '%p (Name contains non-printable chars)\n' \) \
-o \( ! -wholename '/dev/*' \( -type b -o -type c \) \
     -printf '%p (File is a special device file)\n' \) \
-o \( -name '*.rpmnew' -printf '%p (Updated configuration file)\n' \) \
-o -name '*.rpmsaved' -printf '%p (Old configuration file)\n' \
-o \( -type l ! -exec sh -c 'readlink -e "$@" >/dev/null' badLinkChk '{}' \; \
      -printf '%p (Broken Symlink)\n)' \) \
2>/dev/null