Mercurial > pkg
comparison previous-work/more_control_helpers/bin/list_suspicious_files @ 1:d6bef198ae71
add work by Matthias S. Benkmann which is the inspiration for this project.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Tue, 08 Jan 2013 11:45:01 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:0b7a589f6e9a | 1:d6bef198ae71 |
---|---|
1 #!/bin/bash | |
2 # Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de> | |
3 # You may do everything with this code except misrepresent its origin. | |
4 # PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! | |
5 | |
6 #The following list should contain the mount points of all filesystems | |
7 #that are to be scanned as a space-separated list within parentheses. | |
8 #/ will usually be in this list and if you have /usr | |
9 #on a separate partition, it will also be in this list. Other non-special | |
10 #filesystems where suspicious files could be located should also be put in | |
11 #this list. | |
12 #Mount points whose filesystems are special, such as procfs or sysfs should | |
13 #not be in this list. | |
14 fs_to_scan=(/) | |
15 | |
16 #Files with a path prefix found in the following list are ignored. | |
17 #DO !!!!NOT!!! PUT /usr/src OR WHATEVER THE HOME DIRECTORY prefix is for your | |
18 #package users into this list!!! You DO want to scan those directories in | |
19 #order to spot e.g. world-writable tarballs and other abominations that | |
20 #may have crept in. | |
21 #Ideally, this list should be empty. | |
22 prune_prefixes=() #NO TRAILING SLASHES!!! | |
23 | |
24 #If the following variable is set to "yes", then files that contain | |
25 #control characters or other non-printable characters (except for space) | |
26 #will be reported as suspicious. | |
27 #This test slows down the search considerably! | |
28 enable_illchars=yes | |
29 | |
30 | |
31 #suppress ugly debug output from shell | |
32 trap ':' SIGPIPE | |
33 | |
34 #"-false" as 1st argument is used when called by list_suspicious_files_from | |
35 if [ $# -ge 1 -a "$1" != "-false" ]; then | |
36 echo 1>&2 | |
37 echo 1>&2 "USAGE: ${0##*/}" | |
38 echo 1>&2 | |
39 echo 1>&2 ' Outputs a categorized list of files and directories with properties' | |
40 echo 1>&2 ' that could mean trouble and should be investigated.' | |
41 echo 1>&2 | |
42 exit 1 | |
43 fi | |
44 | |
45 | |
46 usergroupmatch=(-true) | |
47 if [ "$1" = "-false" ]; then | |
48 usergroupmatch=(\( "$@" \)) | |
49 fi | |
50 | |
51 #construct find commands that match the prune_prefixes. Each prefix will be | |
52 #matched as -path <prefix> -or -path <prefix>/* | |
53 #so that the directory itself and all subdirectories are matched. | |
54 y=(\( -false) | |
55 for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) | |
56 do | |
57 y[${#y[@]}]='-or' | |
58 y[${#y[@]}]=-path | |
59 y[${#y[@]}]="${prune_prefixes[$i]}" | |
60 y[${#y[@]}]='-or' | |
61 y[${#y[@]}]=-path | |
62 y[${#y[@]}]="${prune_prefixes[$i]}/*" | |
63 done | |
64 y[${#y[@]}]=')' | |
65 | |
66 illchars=( $'\x1' $'\x2' $'\x3' $'\x4' $'\x5' $'\x6' $'\x7' $'\x8' | |
67 $'\x9' $'\xA' $'\xB' $'\xC' $'\xD' $'\xE' $'\xF' $'\x10' $'\x11' | |
68 $'\x12' $'\x13' $'\x14' $'\x15' $'\x16' $'\x17' $'\x18' $'\x19' | |
69 $'\x1A' $'\x1B' $'\x1C' $'\x1D' $'\x1E' $'\x1F' $'\x7f' $'\x80' | |
70 $'\x81' $'\x82' $'\x83' $'\x84' $'\x85' $'\x86' $'\x87' $'\x88' | |
71 $'\x89' $'\x8A' $'\x8B' $'\x8C' $'\x8D' $'\x8E' $'\x8F' $'\x90' | |
72 $'\x91' $'\x92' $'\x93' $'\x94' $'\x95' $'\x96' $'\x97' $'\x98' | |
73 $'\x99' $'\x9A' $'\x9B' $'\x9C' $'\x9D' $'\x9E' $'\x9F' ) | |
74 | |
75 | |
76 if [ "$enable_illchars" = yes ]; then | |
77 | |
78 illname=(\( -false) | |
79 for ((i=0; $i<${#illchars[@]}; i=$i+1)) | |
80 do | |
81 #handle bash \x7f error | |
82 if [ "*${illchars[$i]}*" = "**" ]; then | |
83 illchars[$i]=$'\x80' #' | |
84 fi | |
85 illname[${#illname[@]}]='-or' | |
86 illname[${#illname[@]}]=-name | |
87 illname[${#illname[@]}]="*${illchars[$i]}*" | |
88 done | |
89 illname[${#illname[@]}]=')' | |
90 | |
91 illlink=(\( -false) | |
92 for ((i=0; $i<${#illchars[@]}; i=$i+1)) | |
93 do | |
94 illlink[${#illlink[@]}]='-or' | |
95 illlink[${#illlink[@]}]=-lname | |
96 illlink[${#illlink[@]}]="*${illchars[$i]}*" | |
97 done | |
98 illlink[${#illlink[@]}]=')' | |
99 else #if [ "$enable_illchars" = no ] | |
100 illlink=(-false) | |
101 illname=(-false) | |
102 fi | |
103 | |
104 # $1=section heading | |
105 # $2=inode message | |
106 report() | |
107 { | |
108 echo -printf "increment_code_here" | |
109 echo -printf | |
110 echo "1 ${1}\\n" | sed 's/ /\\040/g' | |
111 echo -printf "insert_code_here" | |
112 | |
113 if [ -n "$2" ]; then | |
114 echo -printf | |
115 echo "2 %i 1 ${2}\\n" | sed 's/ /\\040/g' | |
116 echo -printf "insert_code_here" | |
117 echo -printf | |
118 echo "2 %i 2 " | sed 's/ /\\040/g' | |
119 else | |
120 echo -printf "2\\040" | |
121 fi | |
122 | |
123 echo -exec ls -T 0 -ladQ {} \; | |
124 } | |
125 | |
126 | |
127 filegoodperm=(\( -perm 644 -or -perm 755 -or -perm 555 -or -perm 444 -or -perm 600 -or -perm 700 -or -perm 640 \)) | |
128 dirgoodperm=(\( -perm 755 -or -perm 555 -or -perm 700 -or -perm 750 \)) | |
129 | |
130 good=( \( | |
131 -not \( -not -type d -links +1 \) | |
132 -not -nouser -not -nogroup | |
133 -not \( "${illname[@]}" \) | |
134 -not \( "${illlink[@]}" \) | |
135 \) | |
136 -and | |
137 \( | |
138 \( -type f -not -group install "${filegoodperm[@]}" \) | |
139 -or \( -type d -not -group install "${dirgoodperm[@]}" \) | |
140 -or \( -type d -group install \( -perm 1775 \) \) | |
141 -or \( -type d -group root -user root -path "/tmp" \( -perm 1777 \) \) | |
142 -or \( -type d -group root -user root -path "/var/tmp" \( -perm 1777 \) \) | |
143 -or \( -not -type d -not -type f -not -type l -path "/dev/*" \) | |
144 -or \( -type l \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) \) | |
145 \) | |
146 ) | |
147 | |
148 bad=( | |
149 \( "${illname[@]}" $(report "NON-PRINTABLE CHAR IN NAME") \) | |
150 OP \( "${illlink[@]}" $(report "NON-PRINTABLE-CHAR IN LINK-TARGET") \) | |
151 OP \( -type f -perm -4000 $(report "SETUID FILES") \) | |
152 OP \( -type f -perm -2000 $(report "SETGID FILES") \) | |
153 OP \( -type f -perm -1000 $(report "STICKY FILES") \) | |
154 OP \( -type d -perm -2000 $(report "GROUP-KEEPING DIRECTORIES") \) | |
155 OP \( -type d -not -group install -perm -1000 $(report "STICKY DIRECTORIES") \) | |
156 OP \( -type f -perm -g+w $(report "GROUP-WRITABLE FILES") \) | |
157 OP \( -type f -perm -o+w $(report "WORLD-WRITABLE FILES") \) | |
158 OP \( -type d -perm -g+w $(report "GROUP-WRITABLE DIRECTORIES") \) | |
159 OP \( -type d -perm -o+w $(report "WORLD-WRITABLE DIRECTORIES") \) | |
160 OP \( -not \( -type f -or -type l -or -type d \) -not -path "/dev/*" $(report "SPECIAL FILES OUTSIDE /dev") \) | |
161 OP \( -type d -group install -not -perm 1755 $(report "INSTALL DIRECTORIES WITH UNUSUAL PERMISSIONS") \) | |
162 OP \( -type f -group install $(report "FILES ASSIGNED TO GROUP INSTALL") \) | |
163 OP \( -type l -not \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) $(report "SYMLINKS POSSIBLY BROKEN OR LOOP") \) | |
164 OP \( -not -type d -links +1 $(report "HARDLINKED FILES" "Inode %i is shared by %n files, including") \) | |
165 OP \( -nouser $(report "THINGS HAVING UID WITH NO ASSIGNED USER NAME") \) | |
166 OP \( -nogroup $(report "THINGS HAVING GID WITH NO ASSIGNED GROUP NAME") \) | |
167 OP \( -type f -not -group install -not "${filegoodperm[@]}" $(report "FILES WITH UNUSUAL PERMISSIONS") \) | |
168 OP \( -type d -not -group install -not "${dirgoodperm[@]}" $(report "DIRECTORIES WITH UNUSUAL PERMISSIONS") \) | |
169 ) | |
170 | |
171 #insert unique codes for the messages | |
172 code=100 | |
173 for ((i=0; $i<${#bad[@]}; i=$i+1)) | |
174 do | |
175 if [ "${bad[$i]}" = "increment_code_here" ]; then | |
176 code=$(($code + 1)) | |
177 bad[$i]=$code | |
178 elif [ "${bad[$i]}" = "insert_code_here" ]; then | |
179 bad[$i]=$code | |
180 fi | |
181 done | |
182 | |
183 allbad=() #all bad matches are reported | |
184 onebad=() #only the first bad match is reported | |
185 for ((i=0; $i<${#bad[@]}; i=$i+1)) | |
186 do | |
187 if [ "${bad[$i]}" = "OP" ]; then | |
188 allbad[$i]="," | |
189 onebad[$i]="-or" | |
190 else | |
191 allbad[$i]="${bad[$i]}" | |
192 onebad[$i]="${bad[$i]}" | |
193 fi | |
194 done | |
195 | |
196 #Add a default case to onebad. | |
197 #This should never be hit, because the explicit cases should catch all | |
198 #files, but just in case I've missed something, this will catch it. | |
199 onebad=("${onebad[@]}" -or $(report "WEIRD SHIT") ) | |
200 | |
201 #make allbad always return false | |
202 allbad=("${allbad[@]}" , -false) | |
203 | |
204 cmd=( "${usergroupmatch[@]}" -and | |
205 \( \( "${good[@]}" \) -or \( "${allbad[@]}" \) -or \( "${onebad[@]}" \) \) | |
206 ) | |
207 | |
208 #In the following find command, the part | |
209 # -not ( ( "${y[@]}" -prune ) -or "${y[@]}" ) | |
210 #is responsible for preventing the files that match prune_prefixes from | |
211 #being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because | |
212 #-prune has no effect and is always false when -depth is used. | |
213 find "${fs_to_scan[@]}" -xdev -noleaf \ | |
214 -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \ | |
215 -and \( "${cmd[@]}" \) | | |
216 sed 's/^\(...2\) \([0-9]\+ 2 \)\?\([^ ]\+\) \+[^ ]\+ \+\([^ ]\+\) \+\([^ ]\+\) \+[^"]\+\(".\+\)/\1 \2\3 \6 \4:\5/' | | |
217 sort -u | | |
218 sed 's/^...1 /\'$'\n''/;s/^...2 [0-9]\+ 1 /\'$'\n'' /;s/^...2 [0-9]\+ 2 / /;s/^...2 / /' |