Mercurial > pkg
diff 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 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/previous-work/more_control_helpers/bin/list_suspicious_files Tue Jan 08 11:45:01 2013 +0000 1.3 @@ -0,0 +1,218 @@ 1.4 +#!/bin/bash 1.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de> 1.6 +# You may do everything with this code except misrepresent its origin. 1.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND! 1.8 + 1.9 +#The following list should contain the mount points of all filesystems 1.10 +#that are to be scanned as a space-separated list within parentheses. 1.11 +#/ will usually be in this list and if you have /usr 1.12 +#on a separate partition, it will also be in this list. Other non-special 1.13 +#filesystems where suspicious files could be located should also be put in 1.14 +#this list. 1.15 +#Mount points whose filesystems are special, such as procfs or sysfs should 1.16 +#not be in this list. 1.17 +fs_to_scan=(/) 1.18 + 1.19 +#Files with a path prefix found in the following list are ignored. 1.20 +#DO !!!!NOT!!! PUT /usr/src OR WHATEVER THE HOME DIRECTORY prefix is for your 1.21 +#package users into this list!!! You DO want to scan those directories in 1.22 +#order to spot e.g. world-writable tarballs and other abominations that 1.23 +#may have crept in. 1.24 +#Ideally, this list should be empty. 1.25 +prune_prefixes=() #NO TRAILING SLASHES!!! 1.26 + 1.27 +#If the following variable is set to "yes", then files that contain 1.28 +#control characters or other non-printable characters (except for space) 1.29 +#will be reported as suspicious. 1.30 +#This test slows down the search considerably! 1.31 +enable_illchars=yes 1.32 + 1.33 + 1.34 +#suppress ugly debug output from shell 1.35 +trap ':' SIGPIPE 1.36 + 1.37 +#"-false" as 1st argument is used when called by list_suspicious_files_from 1.38 +if [ $# -ge 1 -a "$1" != "-false" ]; then 1.39 + echo 1>&2 1.40 + echo 1>&2 "USAGE: ${0##*/}" 1.41 + echo 1>&2 1.42 + echo 1>&2 ' Outputs a categorized list of files and directories with properties' 1.43 + echo 1>&2 ' that could mean trouble and should be investigated.' 1.44 + echo 1>&2 1.45 + exit 1 1.46 +fi 1.47 + 1.48 + 1.49 +usergroupmatch=(-true) 1.50 +if [ "$1" = "-false" ]; then 1.51 + usergroupmatch=(\( "$@" \)) 1.52 +fi 1.53 + 1.54 +#construct find commands that match the prune_prefixes. Each prefix will be 1.55 +#matched as -path <prefix> -or -path <prefix>/* 1.56 +#so that the directory itself and all subdirectories are matched. 1.57 +y=(\( -false) 1.58 +for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) 1.59 +do 1.60 + y[${#y[@]}]='-or' 1.61 + y[${#y[@]}]=-path 1.62 + y[${#y[@]}]="${prune_prefixes[$i]}" 1.63 + y[${#y[@]}]='-or' 1.64 + y[${#y[@]}]=-path 1.65 + y[${#y[@]}]="${prune_prefixes[$i]}/*" 1.66 +done 1.67 +y[${#y[@]}]=')' 1.68 + 1.69 +illchars=( $'\x1' $'\x2' $'\x3' $'\x4' $'\x5' $'\x6' $'\x7' $'\x8' 1.70 + $'\x9' $'\xA' $'\xB' $'\xC' $'\xD' $'\xE' $'\xF' $'\x10' $'\x11' 1.71 + $'\x12' $'\x13' $'\x14' $'\x15' $'\x16' $'\x17' $'\x18' $'\x19' 1.72 + $'\x1A' $'\x1B' $'\x1C' $'\x1D' $'\x1E' $'\x1F' $'\x7f' $'\x80' 1.73 + $'\x81' $'\x82' $'\x83' $'\x84' $'\x85' $'\x86' $'\x87' $'\x88' 1.74 + $'\x89' $'\x8A' $'\x8B' $'\x8C' $'\x8D' $'\x8E' $'\x8F' $'\x90' 1.75 + $'\x91' $'\x92' $'\x93' $'\x94' $'\x95' $'\x96' $'\x97' $'\x98' 1.76 + $'\x99' $'\x9A' $'\x9B' $'\x9C' $'\x9D' $'\x9E' $'\x9F' ) 1.77 + 1.78 + 1.79 +if [ "$enable_illchars" = yes ]; then 1.80 + 1.81 + illname=(\( -false) 1.82 + for ((i=0; $i<${#illchars[@]}; i=$i+1)) 1.83 + do 1.84 + #handle bash \x7f error 1.85 + if [ "*${illchars[$i]}*" = "**" ]; then 1.86 + illchars[$i]=$'\x80' #' 1.87 + fi 1.88 + illname[${#illname[@]}]='-or' 1.89 + illname[${#illname[@]}]=-name 1.90 + illname[${#illname[@]}]="*${illchars[$i]}*" 1.91 + done 1.92 + illname[${#illname[@]}]=')' 1.93 + 1.94 + illlink=(\( -false) 1.95 + for ((i=0; $i<${#illchars[@]}; i=$i+1)) 1.96 + do 1.97 + illlink[${#illlink[@]}]='-or' 1.98 + illlink[${#illlink[@]}]=-lname 1.99 + illlink[${#illlink[@]}]="*${illchars[$i]}*" 1.100 + done 1.101 + illlink[${#illlink[@]}]=')' 1.102 +else #if [ "$enable_illchars" = no ] 1.103 + illlink=(-false) 1.104 + illname=(-false) 1.105 +fi 1.106 + 1.107 +# $1=section heading 1.108 +# $2=inode message 1.109 +report() 1.110 +{ 1.111 + echo -printf "increment_code_here" 1.112 + echo -printf 1.113 + echo "1 ${1}\\n" | sed 's/ /\\040/g' 1.114 + echo -printf "insert_code_here" 1.115 + 1.116 + if [ -n "$2" ]; then 1.117 + echo -printf 1.118 + echo "2 %i 1 ${2}\\n" | sed 's/ /\\040/g' 1.119 + echo -printf "insert_code_here" 1.120 + echo -printf 1.121 + echo "2 %i 2 " | sed 's/ /\\040/g' 1.122 + else 1.123 + echo -printf "2\\040" 1.124 + fi 1.125 + 1.126 + echo -exec ls -T 0 -ladQ {} \; 1.127 +} 1.128 + 1.129 + 1.130 +filegoodperm=(\( -perm 644 -or -perm 755 -or -perm 555 -or -perm 444 -or -perm 600 -or -perm 700 -or -perm 640 \)) 1.131 +dirgoodperm=(\( -perm 755 -or -perm 555 -or -perm 700 -or -perm 750 \)) 1.132 + 1.133 +good=( \( 1.134 + -not \( -not -type d -links +1 \) 1.135 + -not -nouser -not -nogroup 1.136 + -not \( "${illname[@]}" \) 1.137 + -not \( "${illlink[@]}" \) 1.138 + \) 1.139 + -and 1.140 +\( 1.141 + \( -type f -not -group install "${filegoodperm[@]}" \) 1.142 + -or \( -type d -not -group install "${dirgoodperm[@]}" \) 1.143 + -or \( -type d -group install \( -perm 1775 \) \) 1.144 + -or \( -type d -group root -user root -path "/tmp" \( -perm 1777 \) \) 1.145 + -or \( -type d -group root -user root -path "/var/tmp" \( -perm 1777 \) \) 1.146 + -or \( -not -type d -not -type f -not -type l -path "/dev/*" \) 1.147 + -or \( -type l \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) \) 1.148 +\) 1.149 +) 1.150 + 1.151 +bad=( 1.152 + \( "${illname[@]}" $(report "NON-PRINTABLE CHAR IN NAME") \) 1.153 + OP \( "${illlink[@]}" $(report "NON-PRINTABLE-CHAR IN LINK-TARGET") \) 1.154 + OP \( -type f -perm -4000 $(report "SETUID FILES") \) 1.155 + OP \( -type f -perm -2000 $(report "SETGID FILES") \) 1.156 + OP \( -type f -perm -1000 $(report "STICKY FILES") \) 1.157 + OP \( -type d -perm -2000 $(report "GROUP-KEEPING DIRECTORIES") \) 1.158 + OP \( -type d -not -group install -perm -1000 $(report "STICKY DIRECTORIES") \) 1.159 + OP \( -type f -perm -g+w $(report "GROUP-WRITABLE FILES") \) 1.160 + OP \( -type f -perm -o+w $(report "WORLD-WRITABLE FILES") \) 1.161 + OP \( -type d -perm -g+w $(report "GROUP-WRITABLE DIRECTORIES") \) 1.162 + OP \( -type d -perm -o+w $(report "WORLD-WRITABLE DIRECTORIES") \) 1.163 + OP \( -not \( -type f -or -type l -or -type d \) -not -path "/dev/*" $(report "SPECIAL FILES OUTSIDE /dev") \) 1.164 + OP \( -type d -group install -not -perm 1755 $(report "INSTALL DIRECTORIES WITH UNUSUAL PERMISSIONS") \) 1.165 + OP \( -type f -group install $(report "FILES ASSIGNED TO GROUP INSTALL") \) 1.166 + OP \( -type l -not \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) $(report "SYMLINKS POSSIBLY BROKEN OR LOOP") \) 1.167 + OP \( -not -type d -links +1 $(report "HARDLINKED FILES" "Inode %i is shared by %n files, including") \) 1.168 + OP \( -nouser $(report "THINGS HAVING UID WITH NO ASSIGNED USER NAME") \) 1.169 + OP \( -nogroup $(report "THINGS HAVING GID WITH NO ASSIGNED GROUP NAME") \) 1.170 + OP \( -type f -not -group install -not "${filegoodperm[@]}" $(report "FILES WITH UNUSUAL PERMISSIONS") \) 1.171 + OP \( -type d -not -group install -not "${dirgoodperm[@]}" $(report "DIRECTORIES WITH UNUSUAL PERMISSIONS") \) 1.172 +) 1.173 + 1.174 +#insert unique codes for the messages 1.175 +code=100 1.176 +for ((i=0; $i<${#bad[@]}; i=$i+1)) 1.177 +do 1.178 + if [ "${bad[$i]}" = "increment_code_here" ]; then 1.179 + code=$(($code + 1)) 1.180 + bad[$i]=$code 1.181 + elif [ "${bad[$i]}" = "insert_code_here" ]; then 1.182 + bad[$i]=$code 1.183 + fi 1.184 +done 1.185 + 1.186 +allbad=() #all bad matches are reported 1.187 +onebad=() #only the first bad match is reported 1.188 +for ((i=0; $i<${#bad[@]}; i=$i+1)) 1.189 +do 1.190 + if [ "${bad[$i]}" = "OP" ]; then 1.191 + allbad[$i]="," 1.192 + onebad[$i]="-or" 1.193 + else 1.194 + allbad[$i]="${bad[$i]}" 1.195 + onebad[$i]="${bad[$i]}" 1.196 + fi 1.197 +done 1.198 + 1.199 +#Add a default case to onebad. 1.200 +#This should never be hit, because the explicit cases should catch all 1.201 +#files, but just in case I've missed something, this will catch it. 1.202 +onebad=("${onebad[@]}" -or $(report "WEIRD SHIT") ) 1.203 + 1.204 +#make allbad always return false 1.205 +allbad=("${allbad[@]}" , -false) 1.206 + 1.207 +cmd=( "${usergroupmatch[@]}" -and 1.208 + \( \( "${good[@]}" \) -or \( "${allbad[@]}" \) -or \( "${onebad[@]}" \) \) 1.209 + ) 1.210 + 1.211 +#In the following find command, the part 1.212 +# -not ( ( "${y[@]}" -prune ) -or "${y[@]}" ) 1.213 +#is responsible for preventing the files that match prune_prefixes from 1.214 +#being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because 1.215 +#-prune has no effect and is always false when -depth is used. 1.216 +find "${fs_to_scan[@]}" -xdev -noleaf \ 1.217 + -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \ 1.218 + -and \( "${cmd[@]}" \) | 1.219 +sed 's/^\(...2\) \([0-9]\+ 2 \)\?\([^ ]\+\) \+[^ ]\+ \+\([^ ]\+\) \+\([^ ]\+\) \+[^"]\+\(".\+\)/\1 \2\3 \6 \4:\5/' | 1.220 +sort -u | 1.221 +sed 's/^...1 /\'$'\n''/;s/^...2 [0-9]\+ 1 /\'$'\n'' /;s/^...2 [0-9]\+ 2 / /;s/^...2 / /'