Finding SUID files

How to find SUID files.

There are 2 ways to find SUID files:

  • You can directly search for them using the find command
  • You can take a complete listing of the file system, and searching through that listing afterwards

The advantage of using the find command is that you directly have the information you need. However, most of the time you will be looking for more than only SUID files (e.g. SGID, world-writable, unowned). Running a find command for each of these can be resource intensive. Therefore, if resources could be an issue, take a complete listing of the file system and afterwards you can search manually through that listing of all sorts of files you want.

Below you will find the description of how to search for SUID files using both these methods.

Finding SUID files using find

The find command is really simple. Just run the following command (with root privileges) on the UNIX system:
find / -type f -perm -4000 -ls > find_suid.txt 2>> error_find_suid.txt
All SUID files will be listed in the file find_suid.txt and errors encountered during the process will be listed in error_find_suid.txt

Finding SUID files in a filesystem listing

First of all you need to take a full listing of the complete filesystem. You can do this using the ls command:
ls -laR / > /tmp/full_fs_list.txt 2>> error_full_fs_list.txt

You can see a clear pattern in this listing. First you see the name of the folder and then follows the listing of the files in that folder. For example:

/usr/:
total 152
drwxr-xr-x  11 root root   4096 2007-10-07 18:06 .
drwxr-xr-x  22 root root   4096 2008-05-18 15:55 ..
drwxr-xr-x   2 root root  36864 2008-05-18 10:26 bin
drwxrwsr-x   2 root src    4096 2006-10-28 16:06 src
drwxr-xr-x   3 root root   4096 2007-10-07 18:06 X11R6

/usr/bin:
total 55424
drwxr-xr-x  2 root   root      36864 2008-05-18 10:26 .
drwxr-xr-x 11 root   root       4096 2007-10-07 18:06 ..
-rwsr-xr-x  1 root   root      28480 2007-02-27 08:53 passwd
-rwxr-xr-x  1 root   root      15644 2007-01-30 19:51 paste
-rwxr-xr-x  1 root   root      92036 2006-01-28 19:35 patch

Our goal is to filter out the folder name containing SUID files and the details of the SUID file itself. I always filter such filesystem listings in 2 phases:

  • First I filter out all directory names and all SUID files
  • Then I filter out all directory names that don't contain SUID files

Phase 1: filtering all directory names and all SUID files
If you just want to know about all SUID files on your system, filter the listing using this command:
sed -n -r -e "/^-[rwx-]{2}s/p" -e "/^\//p" ls_usr.txt
This code will print out all lines that have the SUID bit set and will print out all lines starting with a slash (the directory names).

If you want to know only about all SUID files owned by the root user filter the listing using this command:
sed -n -r -e "/^-[rw-]{2}s[-rwxsSt]{6}[[:space:]]{1,}[[:digit:]]{1,}[[:space:]]{1,}root/p" -e "/^\//p" ls_usr.txt

If we run these commands against the small listing from above, we will get the following result:

/usr/:
/usr/bin:
-rwsr-xr-x  1 root   root      28480 2007-02-27 08:53 passwd

You can imagine that on a complete filesystem, there will be a lot of directories not having SUID files, so you will have many instances similar to the /usr/: in the above listing. Therefore, we will filter these out in the following phase.

Phase 2: Filtering out empty directory names
The important thing to see, is that empty directories have a certain pattern. You will see that the first character of the next line will be a slash again. This will be how we will filter out empty directories.

I once quickly wrote this bash script to do this task:

read line1
while read line2
do
  if [[ "/" == "${line1:0:1}" ]]
  then
    if [[ "/" != "${line2:0:1}" ]]
    then
      echo "$line1"
      echo "$line2"
    fi
  else
      echo "$line1"
  fi
  line1=$line2
done | uniq

If you save this script to a file called filter.sh, then you can combine the two phases into 1 command line to get what you wanted to see:
lode@LNX-DEBIANWS:~$ sed -n -r -e "/^-[rw-]{2}s[-rwxsSt]{6}[[:space:]]{1,}[[:digit:]]{1,}[[:space:]]{1,}root/p" -e "/^\//p" ls_usr.txt | sh filter.sh
/usr/bin:
-rwsr-xr-x 1 root root 28480 2007-02-27 08:53 passwd
lode@LNX-DEBIANWS:~$

On a full directory listing of the /usr folder on my system, the script gives you the following result

lode@LNX-DEBIANWS:~$ ls -laR /usr > ls_usr.txt
lode@LNX-DEBIANWS:~$ sed -n -r -e "/^-[rw-]{2}s[-rwxsSt]{6}[[:space:]]{1,}[[:digit:]]{1,}[[:space:]]{1,}root/p" -e "/^\//p" ls_usr.txt | sh filter.sh
/usr/bin:
-rwsr-xr-x  1 root   root      10916 2007-01-31 00:10 arping
-rwsr-xr-x  1 root   root      32064 2007-02-27 08:53 chfn
-rwsr-xr-x  1 root   root      23616 2007-02-27 08:53 chsh
-rwsr-xr-x  1 root   root      11003 2006-10-01 19:33 fileshareset
-rwsr-xr-x  1 root   root      37248 2007-02-27 08:53 gpasswd
-rwsr-xr-x  1 root   root     837304 2007-03-07 23:16 gpg
-rwsr-xr-x  1 root   root       5824 2008-02-02 20:31 kgrantpty
-rwsr-xr-x  1 root   root       6372 2008-02-02 20:31 kpac_dhcp_helper
-rwsr-xr-x  1 root   root      44924 2006-05-14 18:50 mtr
-rwsr-xr-x  1 root   root      20056 2007-02-27 08:53 newgrp
-rwsr-xr-x  1 root   root      28480 2007-02-27 08:53 passwd
-rwsr-xr--  1 root   plugdev   29280 2006-09-11 13:48 pmount
-rwsr-sr-x  1 root   mail      72544 2006-04-30 21:34 procmail
-rwsr-xr--  1 root   plugdev   22316 2006-09-11 13:48 pumount
-rwsr-xr-x  1 root   root       5316 2008-02-02 20:31 start_kdeinit
-rwsr-xr-x  2 root   root      91700 2006-04-15 09:39 sudo
-rwsr-xr-x  2 root   root      91700 2006-04-15 09:39 sudoedit
-rwsr-xr-x  1 root   root      18060 2006-11-23 21:58 traceroute.lbl
-rwsr-sr-x  1 root   root       7672 2007-04-08 20:26 X
/usr/lib:
-rwsr-xr-x   1 root root     9580 2008-01-19 13:14 pt_chown
/usr/lib/openssh:
-rwsr-xr-x   1 root root 144160 2008-05-14 21:07 ssh-keysign
/usr/sbin:
-rwsr-xr-x  1 root root 688128 2007-01-20 10:46 exim4
lode@LNX-DEBIANWS:~$

Tags: 

You might also be interested in...