3 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
4 # You may do everything with this code except misrepresent its origin.
5 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
7 # Copyright (C) 2014 Steve Youngs <steve@steveyoungs.com>
8 # many updates/tweaks --SY.
10 # The following list should contain the mount points of all filesystems
11 # that are to be scanned as a space-separated list within parentheses.
12 # / will usually be in this list and if you have /usr
13 # on a separate partition, it will also be in this list. Other non-special
14 # filesystems where suspicious files could be located should also be put in
16 # Mount points whose filesystems are special, such as procfs or sysfs should
17 # not be in this list.
29 # Files with a path prefix found in the following list are ignored.
30 # DO !!!!NOT!!! PUT /usr/src OR WHATEVER THE HOME DIRECTORY prefix is for your
31 # package users into this list!!! You DO want to scan those directories in
32 # order to spot e.g. world-writable tarballs and other abominations that
34 # Ideally, this list should be empty.
36 prune_prefixes=(/root /{,*/{,*/}}lost+found) #NO TRAILING SLASHES!!!
40 # /{,*/{,*/}}lost+found \
43 # /opt/sql-ledger/{spool,templates,users,css} \
44 # /etc/apache/ssl.key \
45 # /etc/audisp/plugins.d \
48 # /etc/mail/spamassassin \
50 # /etc/polkit-1/rules.d \
54 # /var/lib/colord/.cache \
55 # /var/lib/{sasl,sudo,net-snmp,udisks{,2},NetworkManager} \
58 # /usr/share/polkit-1/rules.d \
60 # /var/{cache,chroot,db,run,snmp,spool} \
61 # /var/lib/{sshd,nfs,spamassassin,pulse,machines}) #NO TRAILING SLASHES!!!!
63 # Set the following to `-noleaf' if you are scanning non-UNIX filesystems
64 # like MS-DOS, CD-ROM etc. But only do so if you really need it as it
65 # will slow the search significantly.
69 # If the following variable is set to "yes", then files that contain
70 # control characters or other non-printable characters (except for space)
71 # will be reported as suspicious.
72 # This test slows down the search considerably!
77 # suppress ugly debug output from shell
80 # "-false" as 1st argument is used when called by list_suspicious_files_from
81 if [ $# -ge 1 -a "$1" != "-false" ]; then
83 echo 1>&2 "USAGE: ${0##*/}"
85 echo 1>&2 ' Outputs a categorized list of files and directories with properties'
86 echo 1>&2 ' that could mean trouble and should be investigated.'
92 usergroupmatch=(-true)
93 if [ "$1" = "-false" ]; then
94 usergroupmatch=(\( "$@" \))
97 # construct find commands that match the prune_prefixes. Each prefix will be
98 # matched as -path <prefix> -or -path <prefix>/*
99 # so that the directory itself and all subdirectories are matched.
101 for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1))
105 y[${#y[@]}]="${prune_prefixes[$i]}"
108 y[${#y[@]}]="${prune_prefixes[$i]}/*"
112 illchars=( $'\x1' $'\x2' $'\x3' $'\x4' $'\x5' $'\x6' $'\x7' $'\x8'
113 $'\x9' $'\xA' $'\xB' $'\xC' $'\xD' $'\xE' $'\xF' $'\x10' $'\x11'
114 $'\x12' $'\x13' $'\x14' $'\x15' $'\x16' $'\x17' $'\x18' $'\x19'
115 $'\x1A' $'\x1B' $'\x1C' $'\x1D' $'\x1E' $'\x1F' $'\x7f' $'\x80'
116 $'\x81' $'\x82' $'\x83' $'\x84' $'\x85' $'\x86' $'\x87' $'\x88'
117 $'\x89' $'\x8A' $'\x8B' $'\x8C' $'\x8D' $'\x8E' $'\x8F' $'\x90'
118 $'\x91' $'\x92' $'\x93' $'\x94' $'\x95' $'\x96' $'\x97' $'\x98'
119 $'\x99' $'\x9A' $'\x9B' $'\x9C' $'\x9D' $'\x9E' $'\x9F' )
122 if [ "$enable_illchars" = yes ]; then
125 for ((i=0; $i<${#illchars[@]}; i=$i+1))
127 #handle bash \x7f error
128 if [ "*${illchars[$i]}*" = "**" ]; then
129 illchars[$i]=$'\x80' #'
131 illname[${#illname[@]}]='-or'
132 illname[${#illname[@]}]=-name
133 illname[${#illname[@]}]="*${illchars[$i]}*"
135 illname[${#illname[@]}]=')'
138 for ((i=0; $i<${#illchars[@]}; i=$i+1))
140 illlink[${#illlink[@]}]='-or'
141 illlink[${#illlink[@]}]=-lname
142 illlink[${#illlink[@]}]="*${illchars[$i]}*"
144 illlink[${#illlink[@]}]=')'
145 else #if [ "$enable_illchars" = no ]
154 echo -printf "increment_code_here"
156 echo "1 ${1}\\n" | sed 's/ /\\040/g'
157 echo -printf "insert_code_here"
161 echo "2 %i 1 ${2}\\n" | sed 's/ /\\040/g'
162 echo -printf "insert_code_here"
164 echo "2 %i 2 " | sed 's/ /\\040/g'
166 echo -printf "2\\040"
169 echo -exec ls -T 0 -ladQ {} \;
173 filegoodperm=(\( -perm 644 -or -perm 755 -or -perm 555 -or -perm 444 -or -perm 600 -or -perm 700 -or -perm 640 \))
174 dirgoodperm=(\( -perm 755 -or -perm 555 -or -perm 700 -or -perm 750 \))
177 -not \( -not -type d -links +1 \)
178 -not -nouser -not -nogroup
179 -not \( "${illname[@]}" \)
180 -not \( "${illlink[@]}" \)
184 \( -type f -not -group install "${filegoodperm[@]}" \)
185 -or \( -type d -not -group install "${dirgoodperm[@]}" \)
186 -or \( -type d -group install \( -perm 1775 \) \)
187 -or \( -type d -group root -user root -path "/tmp" \( -perm 1777 \) \)
188 -or \( -type d -group root -user root -path "/var/tmp" \( -perm 1777 \) \)
189 -or \( -not -type d -not -type f -not -type l -path "/dev/*" \)
190 -or \( -type l \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) \)
195 \( "${illname[@]}" $(report "NON-PRINTABLE CHAR IN NAME") \)
196 OP \( "${illlink[@]}" $(report "NON-PRINTABLE-CHAR IN LINK-TARGET") \)
197 OP \( -type f -perm -4000 $(report "SETUID FILES") \)
198 OP \( -type f -perm -2000 $(report "SETGID FILES") \)
199 OP \( -type f -perm -1000 $(report "STICKY FILES") \)
200 OP \( -type d -perm -2000 $(report "GROUP-KEEPING DIRECTORIES") \)
201 OP \( -type d -not -group install -perm -1000 $(report "STICKY DIRECTORIES") \)
202 OP \( -type f -perm -g+w $(report "GROUP-WRITABLE FILES") \)
203 OP \( -type f -perm -o+w $(report "WORLD-WRITABLE FILES") \)
204 OP \( -type d -perm -g+w $(report "GROUP-WRITABLE DIRECTORIES") \)
205 OP \( -type d -perm -o+w $(report "WORLD-WRITABLE DIRECTORIES") \)
206 OP \( -not \( -type f -or -type l -or -type d \) -not -path "/dev/*" $(report "SPECIAL FILES OUTSIDE /dev") \)
207 OP \( -type d -group install -not -perm 1755 $(report "INSTALL DIRECTORIES WITH UNUSUAL PERMISSIONS") \)
208 OP \( -type f -group install $(report "FILES ASSIGNED TO GROUP INSTALL") \)
209 OP \( -type l -not \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) $(report "SYMLINKS POSSIBLY BROKEN OR LOOP") \)
210 OP \( -not -type d -links +1 $(report "HARDLINKED FILES" "Inode %i is shared by %n files, including") \)
211 OP \( -nouser $(report "THINGS HAVING UID WITH NO ASSIGNED USER NAME") \)
212 OP \( -nogroup $(report "THINGS HAVING GID WITH NO ASSIGNED GROUP NAME") \)
213 OP \( -type f -not -group install -not "${filegoodperm[@]}" $(report "FILES WITH UNUSUAL PERMISSIONS") \)
214 OP \( -type d -not -group install -not "${dirgoodperm[@]}" $(report "DIRECTORIES WITH UNUSUAL PERMISSIONS") \)
217 # insert unique codes for the messages
219 for ((i=0; $i<${#bad[@]}; i=$i+1))
221 if [ "${bad[$i]}" = "increment_code_here" ]; then
224 elif [ "${bad[$i]}" = "insert_code_here" ]; then
229 allbad=() #all bad matches are reported
230 onebad=() #only the first bad match is reported
231 for ((i=0; $i<${#bad[@]}; i=$i+1))
233 if [ "${bad[$i]}" = "OP" ]; then
237 allbad[$i]="${bad[$i]}"
238 onebad[$i]="${bad[$i]}"
242 # Add a default case to onebad.
243 # This should never be hit, because the explicit cases should catch all
244 # files, but just in case I've missed something, this will catch it.
245 onebad=("${onebad[@]}" -or $(report "WEIRD SHIT") )
247 # make allbad always return false
248 allbad=("${allbad[@]}" , -false)
250 cmd=( "${usergroupmatch[@]}" -and
251 \( \( "${good[@]}" \) -or \( "${allbad[@]}" \) -or \( "${onebad[@]}" \) \)
254 # In the following find command, the part
255 # -not ( ( "${y[@]}" -prune ) -or "${y[@]}" )
256 # is responsible for preventing the files that match prune_prefixes from
257 # being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because
258 # -prune has no effect and is always false when -depth is used.
259 find "${fs_to_scan[@]}" -xdev $NOLEAF \
260 -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \
261 -and \( "${cmd[@]}" \) 2>/dev/null |
262 sed 's/^\(...2\) \([0-9]\+ 2 \)\?\([^ ]\+\) \+[^ ]\+ \+\([^ ]\+\) \+\([^ ]\+\) \+[^"]\+\(".\+\)/\1 \2\3 \6 \4:\5/' |
264 sed 's/^...1 /\'$'\n''/;s/^...2 [0-9]\+ 1 /\'$'\n'' /;s/^...2 [0-9]\+ 2 / /;s/^...2 / /'