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 /  /'