How to find SGID files.
There are 2 ways to find SGID 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 SGID files (e.g. SUID, 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 SGID files using both these methods.
Finding SGID 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 -2000 -ls > find_sgid.txt 2>> error_find_sgid.txt
All SGID files will be listed in the file find_sgid.txt and errors encountered during the process will be listed in error_find_sgid.txt
Finding SGID 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 drwxr-xr-x 2 root root 4096 2007-10-07 17:01 games drwxr-xr-x 6 root root 4096 2007-10-07 16:50 include 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 .. -rwxr-xr-x 1 root root 3840 2008-04-25 22:44 cpan lrwxrwxrwx 1 root root 7 2007-10-07 18:06 cpp -> cpp-4.1 -rwxr-xr-x 1 root root 183444 2006-12-10 15:45 cpp-4.1 -rwxr-xr-x 1 root root 3899 2008-05-08 02:39 c_rehash -rwxr-sr-x 1 root crontab 26380 2006-12-20 01:02 crontab -rwxr-xr-x 1 root root 86140 2007-01-30 19:51 csplit
Our goal is to filter out the folder name containing SGID files and the details of the SGID file itself. I always filter such filesystem listings in 2 phases:
- First I filter out all directory names and all SGID files
- Then I filter out all directory names that don't contain SGID files
Phase 1: filtering all directory names and all SGID files
If you just want to know about all SGID files on your system, filter the listing using this command:sed -n -r -e "/^-[rwxstS-]{5}s/p" -e "/^\//p" ls_usr.txt
This code will print out all lines that have the SGID bit set and will print out all lines starting with a slash (the directory names).
If you want to know only about all SGID files owned by the root group filter the listing using this command:sed -n -r -e "/^-[rwxstS-]{5}s[-rwxstS]{3}[[:space:]]{1,}[[:digit:]]{1,}[[:space:]]{1,}[[:alnum:]]{1,}[[:space:]]{1,}root/p" -e "/^\//p" ls_usr.txt
If we run the first commands against the small listing from above, we will get the following result:
/usr: /usr/bin: -rwxr-sr-x 1 root crontab 26380 2006-12-20 01:02 crontab
You can imagine that on a complete filesystem, there will be a lot of directories not having SGID 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 "/^-[rwxstS-]{5}s/p" -e "/^\//p" ls_usr.txt | sh filter.sh
/usr/bin:
-rwxr-sr-x 1 root crontab 26380 2006-12-20 01:02 crontab
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 "/^-[rwxstS-]{5}s[-rwxstS]{3}[[:space:]]{1,}[[:digit:]]{1,}[[:space:]]{1,}[[:alnum:]]{1,}[[:space:]]{1,}root/p" -e "/^\//p" ls_usr.txt | sh filter.sh /usr/bin: -rwsr-sr-x 1 root root 7672 2007-04-08 20:26 X lode@LNX-DEBIANWS:~$